NautilusTrader 完整快速入门指南
NautilusTrader 完整快速入门指南
NautilusTrader 是一个高性能的开源交易平台,本文将提供一个包含数据获取的完整入门指南。
前置要求
- Python 3.11 或更高版本
- 稳定的网络连接(用于下载数据)
安装步骤
1. 安装 NautilusTrader
bash
# 创建虚拟环境(推荐)
python -m venv nautilus_env
source nautilus_env/bin/activate # Linux/Mac
# nautilus_env\Scripts\activate # Windows
# 安装 NautilusTrader
pip install -U nautilus_trader
# 安装 JupyterLab(可选,用于交互式开发)
pip install -U jupyterlab
2. 获取示例数据(重要!)
官方提供了一个便捷的脚本来下载示例数据:
python
# 在 Jupyter notebook 或 Python 脚本中运行
import subprocess
import sys
# 如果在 Colab 或需要安装 curl
# !apt-get update && apt-get install curl -y
# 下载并执行数据准备脚本
subprocess.run([
sys.executable,
"-c",
"import urllib.request; exec(urllib.request.urlopen('https://raw.githubusercontent.com/nautechsystems/nautilus_data/main/nautilus_data/hist_data_to_catalog.py').read())"
])
或者使用命令行:
bash
curl https://raw.githubusercontent.com/nautechsystems/nautilus_data/main/nautilus_data/hist_data_to_catalog.py | python -
这个脚本会:
- 下载 EUR/USD 的历史数据
- 将数据转换为 Parquet 格式
- 创建数据目录结构
完整的回测示例
1. 导入必要的模块
python
from decimal import Decimal
from pathlib import Path
import pandas as pd
from nautilus_trader.backtest.node import BacktestNode
from nautilus_trader.config import BacktestRunConfig, BacktestVenueConfig, BacktestDataConfig, BacktestEngineConfig
from nautilus_trader.config import ImportableStrategyConfig
from nautilus_trader.config import LoggingConfig
from nautilus_trader.core.datetime import dt_to_unix_nanos
from nautilus_trader.model.data import QuoteTick
from nautilus_trader.model.identifiers import InstrumentId, Symbol, Venue
from nautilus_trader.model.objects import Price, Quantity
from nautilus_trader.persistence.catalog.parquet import ParquetDataCatalog
from nautilus_trader.trading.strategy import Strategy
2. 设置数据目录
python
# 设置数据目录路径
from nautilus_trader.persistence.catalog import ParquetDataCatalog
# 从环境变量或默认路径创建数据目录
catalog = ParquetDataCatalog.from_env()
# 查看可用的交易工具
instruments = catalog.instruments()
print(f"可用交易工具: {[str(i.id) for i in instruments]}")
# 查看数据时间范围
start = catalog.min_timestamp("quote_tick", instrument_id="EUR/USD.SIM")
end = catalog.max_timestamp("quote_tick", instrument_id="EUR/USD.SIM")
print(f"数据时间范围: {start} 到 {end}")
3. 创建简单的 MACD 策略
python
from nautilus_trader.indicators.macd import MovingAverageConvergenceDivergence
from nautilus_trader.trading.strategy import Strategy
class MACDStrategy(Strategy):
def __init__(self, config: dict):
super().__init__(config)
self.instrument_id = InstrumentId.from_str(config["instrument_id"])
# MACD 参数
self.fast_period = config.get("fast_period", 12)
self.slow_period = config.get("slow_period", 26)
self.signal_period = config.get("signal_period", 9)
# 交易参数
self.trade_size = Decimal(config.get("trade_size", "1.0"))
self.entry_threshold = config.get("entry_threshold", 0.0)
# 指标
self.macd = None
def on_start(self):
"""策略启动时调用"""
self.macd = MovingAverageConvergenceDivergence(
fast_period=self.fast_period,
slow_period=self.slow_period,
signal_period=self.signal_period,
)
# 订阅报价数据
self.subscribe_quote_ticks(self.instrument_id)
def on_quote_tick(self, tick: QuoteTick):
"""接收到报价时调用"""
# 更新 MACD
price = float(tick.bid_price)
self.macd.update_raw(price)
if not self.macd.initialized:
return
# 获取 MACD 值
macd_line = self.macd.line
signal_line = self.macd.signal
# 检查持仓
position = self.cache.position(self.instrument_id)
# 交易逻辑
if position is None:
# 无持仓时的入场逻辑
if macd_line > self.entry_threshold and macd_line > signal_line:
# MACD 在阈值之上且高于信号线,做多
self.buy(size=self.trade_size)
elif macd_line < -self.entry_threshold and macd_line < signal_line:
# MACD 在阈值之下且低于信号线,做空
self.sell(size=self.trade_size)
else:
# 有持仓时的出场逻辑
if position.is_long and macd_line <= 0:
# 多仓且 MACD 跌破零线,平仓
self.close_position(position)
elif position.is_short and macd_line >= 0:
# 空仓且 MACD 升破零线,平仓
self.close_position(position)
def buy(self, size: Decimal):
"""发送买入订单"""
order = self.order_factory.market(
instrument_id=self.instrument_id,
order_side="BUY",
quantity=Quantity.from_str(str(size)),
)
self.submit_order(order)
def sell(self, size: Decimal):
"""发送卖出订单"""
order = self.order_factory.market(
instrument_id=self.instrument_id,
order_side="SELL",
quantity=Quantity.from_str(str(size)),
)
self.submit_order(order)
def close_position(self, position):
"""平仓"""
order = self.order_factory.market(
instrument_id=self.instrument_id,
order_side="SELL" if position.is_long else "BUY",
quantity=position.quantity,
)
self.submit_order(order)
4. 配置并运行回测
python
# 配置回测
config = BacktestRunConfig(
engine=BacktestEngineConfig(
strategies=[
ImportableStrategyConfig(
strategy_path="__main__:MACDStrategy",
config={
"instrument_id": "EUR/USD.SIM",
"fast_period": 12,
"slow_period": 26,
"signal_period": 9,
"trade_size": "100000", # 1标准手
"entry_threshold": 0.0001,
},
),
],
logging=LoggingConfig(log_level="INFO"),
),
venues=[
BacktestVenueConfig(
name="SIM",
oms_type="NETTING",
account_type="MARGIN",
base_currency="USD",
starting_balances=["100000 USD"],
),
],
data=[
BacktestDataConfig(
catalog_path=str(catalog.path),
data_cls="nautilus_trader.model.data:QuoteTick",
instrument_id="EUR/USD.SIM",
start_time="2020-01-01T00:00:00Z",
end_time="2020-01-31T23:59:59Z",
),
],
)
# 创建并运行回测节点
node = BacktestNode(configs=[config])
results = node.run()
5. 分析回测结果
python
# 获取引擎实例
engine = node.engine
# 生成报告
print("=== 订单成交报告 ===")
engine.trader.generate_order_fills_report()
print("\n=== 持仓报告 ===")
engine.trader.generate_positions_report()
print("\n=== 账户报告 ===")
engine.trader.generate_account_report(Venue("SIM"))
# 获取账户统计
account = engine.trader.accounts()[0]
print(f"\n初始余额: {account.starting_balances()}")
print(f"最终余额: {account.balances()}")
# 计算收益
starting_balance = 100000
final_balance = float(str(account.balance(USD).split()[0]))
pnl = final_balance - starting_balance
return_pct = (pnl / starting_balance) * 100
print(f"盈亏: ${pnl:.2f}")
print(f"收益率: {return_pct:.2f}%")
数据获取的其他方式
1. 使用自己的数据
如果你有自己的数据,可以将其转换为 NautilusTrader 格式:
python
# 从 CSV 导入数据
from nautilus_trader.persistence.loaders import CSVTickDataLoader
loader = CSVTickDataLoader(
instrument_id="EUR/USD.SIM",
price_precision=5,
size_precision=0,
)
# 加载数据
ticks = loader.load("path/to/your/data.csv")
# 保存到 catalog
catalog.write_data(ticks)
2. 从交易所获取实时数据
python
# 以 Binance 为例
from nautilus_trader.adapters.binance.config import BinanceDataClientConfig
from nautilus_trader.adapters.binance.factories import BinanceLiveDataClientFactory
# 配置数据客户端
config = BinanceDataClientConfig(
api_key="your_api_key", # 可选
api_secret="your_api_secret", # 可选
testnet=False,
)
# 创建数据客户端
data_client = BinanceLiveDataClientFactory.create(
loop=asyncio.get_event_loop(),
name="BINANCE",
config=config,
)
注意事项
- 数据质量:回测结果的准确性依赖于数据质量
- 滑点和手续费:记得在回测配置中设置现实的滑点和手续费
- 过度拟合:避免过度优化策略参数
- 样本外测试:使用未参与优化的数据进行验证
下一步
- 尝试修改 MACD 策略参数
- 实现其他技术指标策略
- 添加风险管理(止损、止盈)
- 尝试多品种交易
- 连接实盘交易
资源链接
现在你已经掌握了 NautilusTrader 的完整入门流程,包括最重要的数据获取步骤!
Comments