【多策略调整与优化】
  114514孙笑川 20天前 69 0

一、整体功能总结

我的这个策略是面向期货(贵金属品种)的自动化交易策略,基于1分钟K线行情,实现“轮换合约+阴阳线开仓+5分钟定时平仓”的完整交易逻辑。

二、逐模块详细解释

1. 导入依赖(代码开头)
from datetime import datetime import panda_quant from panda_backtest.api.future_api import future_api_quotation # 获取期货行情数据 from panda_trading.trading_common.api.api import target_future_group_order, buy_open, sell_open, buy_close, sell_close # 期货下单函数 from panda_trading import SRLogger # 日志工具
  • datetime:处理时间相关逻辑(如计算持仓时长、获取当前时间);
  • panda_quant:量化框架核心库;
  • future_api_quotation:获取期货合约的K线行情数据(如1分钟线);
  • 下单函数:
    • buy_open:买入开多(建立多头持仓);
    • sell_open:卖出开空(建立空头持仓);
    • buy_close:买入平空(平掉空头持仓);
    • sell_close:卖出平多(平掉多头持仓);
  • SRLogger:框架日志工具,用于记录策略运行信息(比print更规范)。
2. 合约列表定义
SYMBOLS = [ "AG2604.SHF", "AU2604.SHF", "AG2605.SHF", "AU2605.SHF", "AG_DOMINANT.SHF" (便于跟踪主力合约) ]
  • 定义5个待交易的贵金属合约,后续按“分钟数取模”轮换交易(0分交易第一个、1分第二个、5分回到第一个)。
3. 框架生命周期函数(核心)

量化框架会按“初始化→交易前→行情推送(handle_data)→交易后”的顺序执行函数,核心逻辑在handle_data中。

(1) 初始化函数(initialize)
def initialize(context): SRLogger.info("initialize") # 记录初始化日志 SRLogger.info('context.now: ' + str(context.now)) # 打印框架上下文的当前时间(回测/实盘时间) now = datetime.now() # 获取本地系统时间 print('时间', now)
  • 策略启动时执行一次,用于初始化全局变量、打印启动日志;
  • 注意:datetime.now()本地系统时间,回测或可改用context.now
  • (2) 交易前函数(before_trading)
def before_trading(context): SRLogger.info("before_trading")
  • 每日交易开始前执行,当前仅打印日志,可扩展:如初始化当日参数、查询账户资金等。
(3) 核心交易逻辑(handle_data)

每次行情数据推送时执行(如1分钟推送一次),是策略的核心:

def handle_data(context, data): SRLogger.info("handle_data") account = context.run_info.future_account # 获取交易账户信息 # 1. 按分钟轮换合约:当前分钟数 % 合约数量 = 选中合约索引 now = datetime.now() print('时间', now) idx = now.minute % len(SYMBOLS) symbol = SYMBOLS[idx] SRLogger.info(f"当前分钟: {now.minute}, 选择合约: {symbol}") # 2. 获取行情数据:上一交易日到当日的1分钟K线 today_str = datetime.now().strftime('%Y%m%d') start_date = panda_quant.get_previous_trading_date(today_str) # 上一交易日 end_date = today_str SRLogger.info(f"调用参数: symbol_list={[symbol]}, start_date={start_date}, end_date={end_date}, period='1m'") quotation_df_1m = future_api_quotation(symbol_list=[symbol], start_date=start_date, end_date=end_date, period='1m') SRLogger.info(quotation_df_1m) # 3. 数据校验:至少需要2根K线(才能取前一根判断阴阳) if quotation_df_1m is None or len(quotation_df_1m) < 2: SRLogger.info(f"合约 {symbol} 的1分钟数据不足以判断K线阴阳") return # 4. 排序K线:确保按时间从早到晚排列,取倒数第二根(前一根)K线 if "time" in quotation_df_1m.columns: quotation_df_1m = quotation_df_1m.sort_values(by=["date", "time"]) else: quotation_df_1m = quotation_df_1m.sort_values(by=["date"]) prev_bar = quotation_df_1m.iloc[-2] # 前一根1分钟K线(排除最新未收盘的) open_price = float(prev_bar["open"]) # 开盘价 close_price = float(prev_bar["close"]) # 收盘价 # 5. 查询持仓:获取该合约的多头/空头持仓数量 position = context.future_account_dict[account].positions.get(symbol) if position is None: long_quantity = 0 # 多头持仓数 short_quantity = 0 # 空头持仓数 else: long_quantity = position.buy_quantity short_quantity = position.sell_quantity # 6. 开仓逻辑:无持仓时,阳线开多、阴线开空、十字线不操作 if long_quantity == 0 and short_quantity == 0: if close_price > open_price: # 阳线(收盘价>开盘价) buy_open(account, symbol, 1) # 买入开多1手 SRLogger.info(f"前一分钟K线为阳线(开={open_price}, 收={close_price}),无多空持仓,买入开多 {symbol}") # 记录开仓状态(方向+时间) context.trade_state = getattr(context, "trade_state", {}) context.trade_state[symbol] = {"side": "long", "open_minute": now} elif close_price < open_price: # 阴线(收盘价<开盘价) sell_open(account, symbol, 1) # 卖出开空1手 SRLogger.info(f"前一分钟K线为阴线(开={open_price}, 收={close_price}),无多空持仓,卖出开空 {symbol}") # 记录开仓状态 context.trade_state = getattr(context, "trade_state", {}) context.trade_state[symbol] = {"side": "short", "open_minute": now} else: # 十字线(收盘价=开盘价) SRLogger.info(f"前一分钟K线为十字线(开={open_price}, 收={close_price}),无多空持仓,不开仓 {symbol}") return # 7. 平仓逻辑:持仓满5分钟则平仓 else: context.trade_state = getattr(context, "trade_state", {}) state = context.trade_state.get(symbol, None) if state is None: return open_minute = state.get("open_minute") side = state.get("side") # 计算持仓时长(分钟) if isinstance(open_minute, datetime): held_minutes = (now - open_minute).total_seconds() / 60.0 else: SRLogger.info(f"开仓时间记录异常,无法计算持仓时间: {open_minute}") return # 持仓满5分钟,对应平仓 if held_minutes >= 5: if side == "long" and long_quantity > 0: sell_close(account, symbol, long_quantity) # 卖平多头 SRLogger.info(f"多头持仓已满5分钟,平仓 {symbol},数量={long_quantity}") elif side == "short" and short_quantity > 0: buy_close(account, symbol, short_quantity) # 买平空头 SRLogger.info(f"空头持仓已满5分钟,平仓 {symbol},数量={short_quantity}") # 清除该合约的开仓记录 context.trade_state.pop(symbol, None)
(4) 交易后函数(after_trading)
def after_trading(context): SRLogger.info("after_trading")
  • 每日交易结束后执行,当前仅打印日志,可扩展:如统计当日盈亏、持仓情况等。
最后一次编辑于 20天前 0

暂无评论

推荐阅读