花了几周时间调好的自适应策略,终于要上战场了。我们先把模拟环境跑起来,再把实时行情和模拟盘接入,离实盘只差一个开关。
我们此前实现了均值回归、趋势跟踪、动量轮动和事件驱动四种策略,最终融合成一个自适应系统,回测表现:年化8.30%,最大回撤6.40%。今天,我们把这套系统接入富途OpenAPI,实现实时行情 + 模拟盘交易,并配备完整的风控模块和模拟撮合,搭建一个生产级量化机器人。
完整代码约650行,关注公众号回复「富途机器人」即可下载。下文只展示核心逻辑片段。
一、系统架构
| 模块 | 职责 | 本地模拟实现 | 富途实盘/模拟实现 |
|---|
| 策略引擎 | 市场状态识别 + 子策略选择 | AdaptiveStrategy | 相同 |
| 数据行情 | 提供价格/成交量 | LocalCSVDataFeed | FutuRealtimeDataFeed |
| 账户订单 | 资金管理、下单 | SimulatedAccount | FutuAccount |
| 撮合成交 | 滑点、延迟模拟 | MatchingEngine | 券商原生撮合 |
| 风控模块 | 仓位限制、止损 | RiskManager | 相同 |
| 主控台 | 调度、监控、停止 | TradingConsole | 相同 |
两种模式自由切换:改一行配置即可从本地CSV切到富途实时行情+模拟盘,再改一行切换到实盘。
二、核心模块关键代码
2.1 自适应策略引擎(仅展示核心选择逻辑)
class AdaptiveStrategy: def __init__(self, threshold_vol=15.0, threshold_adx=20.0): self.strategies = { 'mean_reversion': MeanReversionStrategy(), 'trend_following': TrendFollowingStrategy(), 'momentum': MomentumStrategy(), 'event_driven': EventDrivenStrategy() } def select_strategy(self, all_codes, current_prices): # 计算市场波动率 prices = [current_prices[c] for c in all_codes if c in current_prices] vol = np.std(prices) / np.mean(prices) * 100 adx = 25.0 if vol > 2.0 else 15.0 # ADX简化计算 if vol < self.threshold_vol: return 'mean_reversion' if adx < self.threshold_adx else 'trend_following' else: return 'event_driven' if adx < self.threshold_adx else 'momentum' def get_signal(self, code, price, is_held, all_codes, current_prices): selected = self.select_strategy(all_codes, current_prices) return self.strategies[selected].get_signal(code, price, is_held)
2.2 模拟账户与撮合(关键函数)
class SimulatedAccount: def place_order(self, code, side, shares): order = Order(id=self._next_id(), code=code, side=side, shares=shares) self.orders.append(order) return orderclass MatchingEngine: def simulate_fill(self, order, current_price): # 市价单:买入上滑,卖出下滑 if order.side == BUY: fill_price = current_price * (1 + self.slippage) else: fill_price = current_price * (1 - self.slippage) return True, fill_price
2.3 风控模块(三层拦截)
class RiskManager: def __init__(self, max_position_pct=0.25, max_daily_loss_pct=0.05): self.max_position_pct = max_position_pct self.max_daily_loss_pct = max_daily_loss_pct self.daily_start_asset = None def check_order(self, account, code, shares, price): total_asset = account.get_total_asset() if self.daily_start_asset is None: self.daily_start_asset = total_asset daily_loss = self.daily_start_asset - total_asset if daily_loss > self.daily_start_asset * self.max_daily_loss_pct: return False, "每日亏损限额触发" order_value = shares * price if order_value > total_asset * self.max_position_pct: return False, f"单笔仓位超限" return True, "ok"
三、接入富途OpenAPI(实时行情+模拟盘)
3.1 环境准备
下载 FutuOpenD 并启动,默认监听端口11111(行情)和(交易)。
3.2 数据源替换:FutuRealtimeDataFeed
from futu import OpenQuoteContext, SubType, RET_OKclass FutuRealtimeDataFeed: def __init__(self, host='127.0.0.1', port=11111): self.quote_ctx = OpenQuoteContext(host, port) self.last_prices = {} def subscribe(self, code_list): ret, _ = self.quote_ctx.subscribe(code_list, [SubType.QUOTE]) return ret == RET_OK def get_all_prices(self, codes): ret, data = self.quote_ctx.get_market_snapshot(codes) if ret == RET_OK: return {row['code']: row['last_price'] for _, row in data.iterrows()} return {}
3.3 账户替换:FutuAccount(模拟盘)
from futu import OpenSecTradeContext, TrdEnv, TrdSide, OrderTypeclass FutuAccount: def __init__(self, host='127.0.0.1', port=11111): self.trade_ctx = OpenSecTradeContext(host, port) self.trd_env = TrdEnv.SIMULATE # 模拟盘,改成 REAL 即实盘 def place_order(self, code, side, shares): trd_side = TrdSide.BUY if side == 'BUY' else TrdSide.SELL ret, data = self.trade_ctx.place_order( code=code, price=0.0, qty=shares, trd_side=trd_side, order_type=OrderType.MARKET, trd_env=self.trd_env ) return ret == RET_OK, data
⚠️ 实盘开关:仅需将 TrdEnv.SIMULATE 改为 TrdEnv.REAL,代码其他部分完全不变。
3.4 主控机器人循环
class FutuAdaptiveBot: def run_once(self): prices = self.data_feed.get_all_prices(self.etf_pool) for code, price in prices.items(): is_held = self.account.is_held(code) signal = self.strategy.get_signal(code, price, is_held, self.etf_pool, prices) if signal == 'BUY' and not is_held: ok, msg = self.risk_mgr.check_order(...) if ok: self.account.place_order(code, 'BUY', 100)
四、风控模块详解(实盘必备)
| 风控规则 | 执行时机 | 默认值 | 说明 |
|---|
| 单笔仓位上限 | 开仓前 | 20% | 单次买入金额 ≤ 总资产×20% |
| 每日亏损限额 | 开仓前 + 实时监控 | 5% | 当日累计亏损(含浮动)超过5%则禁止所有新开仓 |
| 移动止损(可扩展) | 持仓中 | 10% | 从最高点回撤10%自动平仓 |
| 单品种止损 | 持仓中 | 5% | 价格低于成本价5%强制平仓 |
完整版中还包含了订单成交滑点、延迟模拟及每日亏损重置逻辑。
五、运行指南
富途模拟盘版
启动FutuOpenD并登录
运行 python futu_bot.py
切换到实盘
六、完整代码获取
本文仅展示核心逻辑片段,完整代码(约700行) 包含:
四种完整子策略实现
自适应策略引擎完整版
本地模拟版全功能实现
富途OpenAPI全功能实现
风控模块完整版(含移动止损)
配置说明与常见问题
关注公众号「Alpha信号站」,回复关键词「富途机器人」即可下载。
声明:所有内容均为量化策略教学,不构成投资建议。市场有风险,投资需谨慎。
如果你在部署中遇到任何问题,欢迎留言,我会一一解答。