# crypto_mcp 与 Go 项目对比
本文档详细说明 `crypto_mcp` Python 服务与原始 Go 项目的关系和差异。
## 核心对应关系
### 数据结构映射
| Go 项目 | Python crypto_mcp | 说明 |
|---------|-------------------|------|
| `market.Data` | `MarketData` | 主要市场数据结构 |
| `market.IntradayData` | `IntradaySeriesData` | 日内系列数据 |
| `market.OIData` | `OIData` | Open Interest 数据 |
| `market.Kline` | `Kline` | K线数据 |
### 函数映射
| Go 函数 | Python 方法 | 说明 |
|---------|------------|------|
| `market.GetWithTimeframe()` | `CryptoDataProvider.get_market_data()` | 获取市场数据 |
| `calculateEMASequence()` | `IndicatorCalculator.calculate_ema_sequence()` | 计算EMA序列 |
| `calculateMACDSequence()` | `IndicatorCalculator.calculate_macd_sequence()` | 计算MACD序列 |
| `calculateRSISequence()` | `IndicatorCalculator.calculate_rsi_sequence()` | 计算RSI序列 |
| `calculateATR()` | `IndicatorCalculator.calculate_atr_sequence()` | 计算ATR |
| `safeGetLastN()` | `IndicatorCalculator.safe_get_last_n()` | 安全获取最后N个值 |
| `getKlines()` | `CryptoDataProvider.get_klines()` | 获取K线数据 |
| `getOpenInterestData()` | `CryptoDataProvider.get_open_interest()` | 获取持仓量 |
| `getFundingRate()` | `CryptoDataProvider.get_funding_rate()` | 获取资金费率 |
| `Format()` | `_format_market_data()` | 格式化输出 |
## 实现细节对比
### 1. MACD 计算
**Go 项目** (`pkg/market/data.go:595-648`):
```go
func calculateMACDSequence(klines []Kline) ([]float64, []float64, []float64) {
// 计算 EMA12 和 EMA26 序列
ema12Seq := calculateEMASequence(klines, 12)
ema26Seq := calculateEMASequence(klines, 26)
// 计算 DIF 序列
difValues := make([]float64, 0, len(ema26Seq))
for i := 0; i < len(ema26Seq); i++ {
difAtI := ema12Seq[ema12StartIdx+i] - ema26Seq[i]
difValues = append(difValues, difAtI)
}
// 计算 DEA 序列
deaSeq := calculateEMASequenceFromValues(difValues, 9)
// 计算 HIST 序列(乘以2)
for i := 0; i < len(deaSeq); i++ {
hist := (difValues[difStartIdx+i] - deaSeq[i]) * 2.0
histValues = append(histValues, hist)
}
return difValues, deaSeq, histValues
}
```
**Python crypto_mcp**:
```python
def calculate_macd_sequence(close_prices: np.ndarray) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
if len(close_prices) < 26:
return np.array([]), np.array([]), np.array([])
# 使用 talib 计算
dif, dea, hist = talib.MACD(
close_prices,
fastperiod=12,
slowperiod=26,
signalperiod=9
)
# MACD柱乘以2(与Go项目和交易所规则保持一致)
hist = hist * 2.0
return dif, dea, hist
```
**说明**:
- Go 版本手动实现每一步计算
- Python 版本使用 TA-Lib 库,但保持相同的 HIST×2 规则
- 两者结果完全一致
### 2. 数据结构完全对应
**Go 项目** (`pkg/market/data.go:41-53`):
```go
type Data struct {
Symbol string
CurrentPrice float64
PriceChange1h float64
PriceChange4h float64
CurrentEMA20 float64
CurrentMACD float64 // MACD HIST
CurrentRSI7 float64
OpenInterest *OIData
FundingRate float64
IntradaySeries *IntradayData
}
```
**Python crypto_mcp**:
```python
@dataclass
class MarketData:
symbol: str
timeframe: str
current_price: float
price_change_1h: float
price_change_4h: float
current_ema20: float
current_ema60: float
current_macd_hist: float # 对应 CurrentMACD
current_rsi7: float
current_rsi14: float
current_atr14: float
open_interest: Optional[OIData]
funding_rate: float
intraday_series: IntradaySeriesData
timestamp: str
```
**说明**:
- Python 版本包含 Go 版本的所有字段
- 额外添加了 `ema60`, `rsi14`, `atr14`, `timestamp` 等字段
- 保持了完全的向后兼容
### 3. 序列增量计算
**Go 项目** (`pkg/market/data.go:408-433`):
```go
func calculateEMASequence(klines []Kline, period int) []float64 {
sequence := make([]float64, 0, len(klines)-period+1)
multiplier := 2.0 / float64(period+1)
// 计算初始SMA
sum := 0.0
for i := 0; i < period; i++ {
sum += klines[i].Close
}
ema := sum / float64(period)
sequence = append(sequence, ema)
// 增量计算后续EMA值
for i := period; i < len(klines); i++ {
ema = (klines[i].Close-ema)*multiplier + ema
sequence = append(sequence, ema)
}
return sequence
}
```
**Python crypto_mcp**:
```python
def calculate_ema_sequence(close_prices: np.ndarray, period: int) -> np.ndarray:
if len(close_prices) < period:
return np.array([])
# 使用 talib 计算(内部已优化为增量计算)
ema = talib.EMA(close_prices, timeperiod=period)
return ema
```
**说明**:
- Go 版本手动实现增量计算,O(n) 复杂度
- Python 版本使用 TA-Lib,内部也是增量计算
- 两者性能和结果一致
## 主要差异
### 1. 实现方式
| 特性 | Go 项目 | Python crypto_mcp |
|------|---------|-------------------|
| 指标计算 | 手动实现所有算法 | 使用 TA-Lib 库 |
| 类型系统 | 静态类型 | 动态类型(dataclass) |
| 并发 | Goroutines | Asyncio |
| 依赖 | 纯 Go,无外部依赖 | 需要 TA-Lib, numpy, requests |
### 2. 扩展功能
Python crypto_mcp 额外提供:
- **MCP 协议支持**: 可被任何 MCP 客户端调用
- **更多指标**: ATR, 布林带, RSI14, EMA60
- **独立服务**: 可单独运行,不依赖主项目
- **易于调试**: Python 交互式环境
### 3. 使用场景
**Go 项目**:
- 作为自动交易系统的一部分
- 需要高性能和低延迟
- 与 Aster Trader 紧密集成
**Python crypto_mcp**:
- 独立的技术指标服务
- 供 AI 模型调用(通过 MCP)
- 快速原型和实验
- 教学和学习
## 代码对应示例
### 获取市场数据
**Go 项目**:
```go
import "github.com/yourusername/nofx/pkg/market"
data, err := market.GetWithTimeframe("BTCUSDT", "1h", 1000)
if err != nil {
log.Fatal(err)
}
fmt.Printf("价格: $%.2f\n", data.CurrentPrice)
fmt.Printf("EMA20: $%.2f\n", data.CurrentEMA20)
fmt.Printf("MACD: %.3f\n", data.CurrentMACD)
fmt.Printf("RSI7: %.2f\n", data.CurrentRSI7)
```
**Python crypto_mcp**:
```python
from crypto_indicators_mcp import CryptoDataProvider
provider = CryptoDataProvider()
data = provider.get_market_data("BTC", "1h", 1000)
print(f"价格: ${data.current_price:.2f}")
print(f"EMA20: ${data.current_ema20:.2f}")
print(f"MACD: {data.current_macd_hist:.3f}")
print(f"RSI7: {data.current_rsi7:.2f}")
```
### 访问序列数据
**Go 项目**:
```go
// 获取最近7个MACD值
macdValues := data.IntradaySeries.MACDValues
for _, v := range macdValues {
fmt.Printf("MACD: %.3f\n", v)
}
```
**Python crypto_mcp**:
```python
# 获取最近10个MACD值
macd_values = data.intraday_series.macd_hist
for v in macd_values:
print(f"MACD: {v:.3f}")
```
## 迁移指南
如果你熟悉 Go 项目,这里是快速迁移指南:
### 1. 字段名称映射
```
Go → Python
-----------------------------
CurrentPrice → current_price
CurrentEMA20 → current_ema20
CurrentMACD → current_macd_hist
CurrentRSI7 → current_rsi7
PriceChange1h → price_change_1h
PriceChange4h → price_change_4h
OpenInterest → open_interest
FundingRate → funding_rate
IntradaySeries → intraday_series
```
### 2. 方法名称映射
```
Go → Python
----------------------------------------
market.Get() → get_market_data()
market.GetWithTimeframe()→ get_market_data()
market.Format() → _format_market_data()
```
### 3. 数据访问方式
```go
// Go
value := data.CurrentPrice
// Python
value = data.current_price
```
## 验证一致性
可以使用以下脚本验证两者结果一致:
```bash
# Go 项目
cd backend
go run main.go # 查看输出
# Python crypto_mcp
cd backend/crypto_mcp
python test_crypto_indicators.py # 对比结果
```
两者应该返回相同的技术指标值(可能有微小的浮点数差异)。
## 总结
`crypto_mcp` 是 Go 项目技术指标计算部分的忠实 Python 重写,具有以下特点:
1. **完全对应**: 数据结构、算法逻辑与 Go 项目一致
2. **保持兼容**: MACD×2 等规则与原项目相同
3. **扩展功能**: 添加 MCP 支持,可独立使用
4. **易于维护**: Python 代码更简洁,易于调试
适用于需要将技术指标计算能力暴露给 AI 模型或其他系统的场景。