从‘茅台’到‘一篮子股票’:手把手教你用Supermind和Python扩展你的第一个量化策略
从单标到组合用Supermind和Python构建多股票量化策略实战指南在量化交易的世界里从单只股票策略扩展到多股票组合是每个交易者必须跨越的关键门槛。本文将带你深入探索如何将一个基础的双均线策略从单一股票如贵州茅台扩展到能够同时监控和交易多只股票的投资组合。通过Supermind平台和Python代码的实战演示你将掌握处理多标的数据、资金分配、信号同步等核心技能避开实际交易中的常见陷阱。1. 多股票策略的核心挑战与解决方案当我们将策略从单只股票扩展到多只股票时会面临几个关键的技术和逻辑挑战数据获取与处理需要同时获取和处理多只股票的历史价格数据信号生成与同步不同股票可能在同一时间产生相反的交易信号资金分配如何在多只股票之间合理分配有限资金风险管理组合层面的风险控制与单只股票有何不同在Supermind平台上我们可以利用其内置的多标的数据处理功能和Python的向量化计算能力来高效解决这些问题。以下是一个多股票策略的基本框架def init(context): # 设置要操作的股票列表示例为沪深300前5只成分股 context.security_list [ 600519.SH, # 贵州茅台 601318.SH, # 中国平安 600036.SH, # 招商银行 601888.SH, # 中国中免 000858.SZ # 五粮液 ] # 设置每只股票的最大资金占比 context.max_weight 0.2 # 每只股票最多分配20%资金2. 多标的数据处理与均线计算优化处理多只股票的历史数据时我们需要考虑性能和代码简洁性。Supermind的history函数原生支持多标的数据获取def handle_bar(context, bar_dict): # 一次性获取所有股票过去20天的收盘价数据 all_closeprice history(context.security_list, [close], 20, 1d, False, pre, is_panel1) # 计算每只股票的均线 for security in context.security_list: closeprice all_closeprice.minor_xs(security)[close] MA20 closeprice.mean() MA5 closeprice.iloc[-5:].mean() # 获取当前持仓比例 current_position context.portfolio.positions[security].value_percent # 交易逻辑 if MA5 MA20 and current_position context.max_weight: order_target_percent(security, context.max_weight) log.info(买入 %s % security) elif MA5 MA20 and current_position 0: order_target(security, 0) log.info(卖出 %s % security)注意使用minor_xs方法可以高效地从多标的面板数据中提取单个股票的数据这比循环获取每只股票的数据性能更高。3. 资金分配与组合管理策略在多股票策略中资金分配方式直接影响策略的风险收益特征。常见的资金分配方法包括分配方法优点缺点适用场景等权重分配简单易实现分散风险不考虑个股差异初期测试阶段波动率倒数分配平衡组合波动计算复杂成熟策略市值加权接近市场结构可能过度集中指数跟踪策略信号强度加权强化优质信号增加换手率趋势明显的市场环境在Supermind中实现动态资金分配的示例def calculate_dynamic_weights(context, signal_strength): 根据信号强度动态计算权重分配 signal_strength: 各股票信号强度的字典 {stock: strength} total_strength sum(signal_strength.values()) if total_strength 0: return {stock: 0 for stock in context.security_list} weights {} for stock in context.security_list: weights[stock] (signal_strength.get(stock, 0) / total_strength) * 0.9 # 保留10%现金 return weights4. 多股票策略的进阶优化技巧4.1 信号过滤与确认为了避免频繁交易和假信号可以引入以下过滤机制成交量确认只有当成交量放大时才确认信号时间延迟确认信号出现后观察1-2天再执行相关性过滤避免同时买入高度相关的股票# 添加成交量过滤的示例代码 def handle_bar_with_volume_filter(context, bar_dict): all_data history(context.security_list, [close, volume], 30, 1d, False, pre, is_panel1) for security in context.security_list: stock_data all_data.minor_xs(security) closeprice stock_data[close] volume stock_data[volume] MA20 closeprice.mean() MA5 closeprice.iloc[-5:].mean() avg_volume volume.mean() current_volume bar_dict[security].volume # 只有当成交量超过平均且出现信号时才交易 if MA5 MA20 and current_volume avg_volume * 1.5: order_target_percent(security, context.max_weight) elif MA5 MA20: order_target(security, 0)4.2 组合风险控制多股票策略需要从组合层面考虑风险控制最大回撤控制当组合回撤达到阈值时暂停交易个股止损对每只股票设置单独的止损线行业分散避免过度集中在单一行业# 组合风险控制示例 def handle_bar_with_risk_control(context, bar_dict): # 计算组合当前回撤 portfolio_value context.portfolio.total_value max_portfolio_value context.portfolio.max_portfolio_value drawdown (max_portfolio_value - portfolio_value) / max_portfolio_value if drawdown 0.1: # 回撤超过10%时停止交易 log.warn(组合回撤超过10%暂停交易) return # 正常交易逻辑 # ...5. 策略回测与性能分析要点在多股票策略回测时需要特别关注以下指标组合夏普比率衡量风险调整后收益个股贡献度分析每只股票对组合的贡献换手率评估交易成本影响最大回撤持续时间了解恢复周期信号分布检查信号是否集中在特定时间段在Supermind平台上进行多股票策略回测时可以使用以下代码记录关键指标def after_trading_end(context): # 记录每日组合表现 record( portfolio_valuecontext.portfolio.total_value, cashcontext.portfolio.cash, positionslen(context.portfolio.positions), leveragecontext.portfolio.portfolio_value / context.portfolio.total_value ) # 分析个股表现 for security in context.security_list: if security in context.portfolio.positions: position context.portfolio.positions[security] record(**{ f{security}_weight: position.value_percent, f{security}_pnl: position.pnl })6. 从回测到实盘的注意事项将多股票策略部署到实盘时需要特别注意交易成本影响多股票策略通常换手率更高流动性考量确保目标股票有足够流动性数据延迟处理部分股票可能停牌或数据延迟订单执行策略大额订单需要分拆执行# 实盘订单执行优化示例 def optimized_order_execution(context, security, target_weight): current_weight context.portfolio.positions[security].value_percent delta target_weight - current_weight if abs(delta) 0.01: # 变化小于1%时不交易 return # 大额订单分拆执行 if abs(delta) 0.05: steps int(abs(delta) / 0.02) 1 incremental_weight delta / steps for i in range(steps): order_target_percent(security, current_weight incremental_weight * (i 1)) log.info(分步执行订单 %s: 步骤 %d/%d % (security, i1, steps)) else: order_target_percent(security, target_weight)在实际项目中我发现多股票策略成功的关键在于平衡信号的准确性和组合的分散性。过度分散会稀释优质信号的收益而过度集中又失去了多股票策略的优势。经过多次迭代我通常会将股票数量控制在10-30只并根据市场波动率动态调整仓位集中度。