用OctoBot构建量化交易策略:回测与参数优化教程
Building and Validating a Quantitative Trading Strategy with OctoBot, Walk-Forward Backtesting, Parameter Optimization, and Interactive Analysis
In this tutorial, we build a complete quantitative backtesting workflow with OctoBot and OctoBot-Script while keeping the environment isolated from Colab’s preinstalled dependencies. We configure a rule-based trading strategy that combines RSI-based oversold signals, EMA trend confirmation, and ATR-driven adaptive stop-loss and take-profit levels, and we execute it through OctoBot’s native market-order and backtesting APIs. We also retrieve historical OHLCV data through OctoBot’s data layer with automatic exchange fallback, perform a multi-parameter grid search over an in-sample period, and select the strongest configuration based on its excess return relative to buy-and-hold. We then validate the selected parameters on a completely separate out-of-sample period to assess generalization and identify potential overfitting. Finally, we extract OctoBot’s backtest report data and use Pandas and Plotly to analyze parameter sensitivity, portfolio performance, price action, indicators, and execution results in an interactive Colab environment.
在本教程中,我们使用OctoBot和OctoBot-Script构建一个完整的量化回测工作流程,同时保持环境与Colab预装依赖隔离。我们配置一个基于规则的交易策略,该策略结合了基于RSI的超卖信号、EMA趋势确认以及ATR驱动的自适应止损和止盈水平,并通过OctoBot的原生市价单和回测API执行该策略。我们还通过OctoBot的数据层检索历史OHLCV数据,并自动进行交易所回退,在样本内期间执行多参数网格搜索,并根据相对于买入并持有的超额收益选择最强的配置。然后,我们在完全独立的样本外期间验证所选参数,以评估泛化能力并识别潜在的过拟合。最后,我们提取OctoBot的回测报告数据,并使用Pandas和Plotly在交互式Colab环境中分析参数敏感性、投资组合表现、价格行为、指标和执行结果。
SYMBOL = "BTC/USDT"
TIME_FRAME = "1d"
EXCHANGES = ["binance", "kucoin", "okx", "bybit", "mexc", "kraken"]
IN_SAMPLE = ("2019-01-01", "2023-01-01")
OUT_OF_SAMPLE = ("2023-01-01", "2025-06-01")
GRID = {
"rsi_period": [7, 14, 21],
"rsi_threshold": [25, 30, 35],
"tp_atr_mult": [3.0, 5.0],
}
FIXED = {
"ema_fast": 50,
"ema_slow": 200,
"atr_period": 14,
"sl_atr_mult": 2.0,
"position_size": "20%",
"min_offset_pct": 1.0,
"max_offset_pct": 40.0,
}
VENV_DIR = "/content/octobot_env"
WORK_DIR = "/content/octobot_lab"
OCTOBOT_V = "2.1.1"
PY_VERSION = "3.12"
import json, os, subprocess, sys, textwrap, time, itertools, shutil
os.makedirs(WORK_DIR, exist_ok=True)
PY = os.path.join(VENV_DIR, "bin", "python")
MARKER = os.path.join(VENV_DIR, ".octobot_ready")
def sh(cmd, **kw):
"""Run a command, streaming its output live into the Colab cell."""
print(f"$ {' '.join(cmd)}")
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
text=True, bufsize=1, **kw)
for line in p.stdout:
print(" " + line.rstrip())
p.wait()
if p.returncode != 0:
raise RuntimeError(f"command failed ({p.returncode}): {' '.join(cmd)}")
if not os.path.exists(MARKER):
print("=" * 90, "\n BUILDING OCTOBOT ENVIRONMENT (one-off, ~2 min)\n", "=" * 90)
subprocess.run([sys.executable, "-m", "pip", "install", "-q", "uv"], check=True)
UV = [sys.executable, "-m", "uv"]
sh(UV + ["venv", "--python", PY_VERSION, VENV_DIR])
sh(UV + ["pip", "install", "--python", PY, "-q",
f"OctoBot=={OCTOBOT_V}", "wheel", "setuptools", "appdirs==1.4.4"])
sh(UV + ["pip", "install", "--python", PY, "-q", "--no-build-isolation", "octobot-script"])
sh([PY, "-m", "octobot_script.cli", "install_tentacles", "--quite"])
sh([PY, "-c", textwrap.dedent("""
import os, shutil, octobot_script.resources as r
base = r.get_report_resource_path("")
src, dst_dir = os.path.join(base, "index.html"), os.path.join(base, "dist")
os.makedirs(dst_dir, exist_ok=True)
dst = os.path.join(dst_dir, "index.html")
if os.path.exists(src) and not os.path.exists(dst):
shutil.copy2(src, dst); print("patched report template ->", dst)
else:
print("report template already fine")
""")])
open(MARKER, "w").write("ok")
print("\n environment ready\n")
else:
print(" environment already built (delete", VENV_DIR, "to rebuild)\n")SYMBOL = "BTC/USDT"
TIME_FRAME = "1d"
EXCHANGES = ["binance", "kucoin", "okx", "bybit", "mexc", "kraken"]
IN_SAMPLE = ("2019-01-01", "2023-01-01")
OUT_OF_SAMPLE = ("2023-01-01", "2025-06-01")
GRID = {
"rsi_period": [7, 14, 21],
"rsi_threshold": [25, 30, 35],
"tp_atr_mult": [3.0, 5.0],
}
FIXED = {
"ema_fast": 50,
"ema_slow": 200,
"atr_period": 14,
"sl_atr_mult": 2.0,
"position_size": "20%",
"min_offset_pct": 1.0,
"max_offset_pct": 40.0,
}
VENV_DIR = "/content/octobot_env"
WORK_DIR = "/content/octobot_lab"
OCTOBOT_V = "2.1.1"
PY_VERSION = "3.12"
import json, os, subprocess, sys, textwrap, time, itertools, shutil
os.makedirs(WORK_DIR, exist_ok=True)
PY = os.path.join(VENV_DIR, "bin", "python")
MARKER = os.path.join(VENV_DIR, ".octobot_ready")
def sh(cmd, **kw):
"""Run a command, streaming its output live into the Colab cell."""
print(f"$ {' '.join(cmd)}")
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
text=True, bufsize=1, **kw)
for line in p.stdout:
print(" " + line.rstrip())
p.wait()
if p.returncode != 0:
raise RuntimeError(f"command failed ({p.returncode}): {' '.join(cmd)}")
if not os.path.exists(MARKER):
print("=" * 90, "\n BUILDING OCTOBOT ENVIRONMENT (one-off, ~2 min)\n", "=" * 90)
subprocess.run([sys.executable, "-m", "pip", "install", "-q", "uv"], check=True)
UV = [sys.executable, "-m", "uv"]
sh(UV + ["venv", "--python", PY_VERSION, VENV_DIR])
sh(UV + ["pip", "install", "--python", PY, "-q",
f"OctoBot=={OCTOBOT_V}", "wheel", "setuptools", "appdirs==1.4.4"])
sh(UV + ["pip", "install", "--python", PY, "-q", "--no-build-isolation", "octobot-script"])
sh([PY, "-m", "octobot_script.cli", "install_tentacles", "--quite"])
sh([PY, "-c", textwrap.dedent("""
import os, shutil, octobot_script.resources as r
base = r.get_report_resource_path("")
src, dst_dir = os.path.join(base, "index.html"), os.path.join(base, "dist")
os.makedirs(dst_dir, exist_ok=True)
dst = os.path.join(dst_dir, "index.html")
if os.path.exists(src) and not os.path.exists(dst):
shutil.copy2(src, dst); print("patched report template ->", dst)
else:
print("report template already fine")
""")])
open(MARKER, "w").write("ok")
print("\n environment ready\n")
else:
print(" environment already built (delete", VENV_DIR, "to rebuild)\n")We define the core trading configuration, including the symbol, timeframe, exchange fallback list, backtesting windows, parameter grid, and fixed strategy settings. We then create an isolated Python environment with uv and install the pinned OctoBot and OctoBot-Script dependencies required for the workflow. We also install the OctoBot tentacles package and patch the report-template path so later backtest reporting works correctly inside the Colab environment.
我们定义核心交易配置,包括交易对、时间框架、交易所回退列表、回测窗口、参数网格和固定策略设置。然后,我们使用uv创建一个隔离的Python环境,并安装工作流程所需的固定版本的OctoBot和OctoBot-Script依赖。我们还安装OctoBot的tentacles包,并修补报告模板路径,以便后续回测报告在Colab环境中能正确工作。
更进一步:量化金融体系
看懂新闻只是起点——沿量化金融路径,把它变成能交付的工程能力