AI助手–小白自然语言生成工作流入门期货回测工作流
  17715853540 30天前 83 0

AI助手–小白自然语言生成工作流入门期货回测工作流

1.1 代码框代码助手

  • 专业的量化助手,合格的大语言模型。
  • 能够帮助小白在实践中快速学习专业领域知识。
  • 下面是我让他帮我讲解的这个策略核心逻辑和核心概念,不错不错!

一、这个策略整体在干什么?

一句话概括:

用“短期均线”和“长期均线”的金叉/死叉信号,在白银期货主力合约上自动做多、做空,并按照一套风险规则控制每次开的手数。

交易标的:

AG_DOMINANT.SHF:白银期货的“主力连续合约”(后面详细解释)。

实际真正下单是当天的主力合约,比如 AG2506.SHF 这样的具体月份合约。

核心逻辑:

每天收盘后,拿到白银主力合约当天收盘价,把它记到历史价格里。
用最近 10 天价格算“短期均线”,用最近 30 天价格算“长期均线”。
看短期均线和长期均线的关系:

短期均线从下往上,穿过长期均线 = 金叉 → 看多

短期均线从上往下,穿过长期均线 = 死叉 → 看空

有了“看多/看空”信号,就根据当前账户总资产、保证金率、最大杠杆等条件计算出本次应该开多少手。
如果是金叉:

先把现有空单全部平掉

再按计算好的手数开多(买入开仓)

如果是死叉:

先把现有多单全部平掉

再按计算好的手数开空(卖出开仓)

同时,这个策略还会在:

开盘前(before_trading) 打印账户资金情况

每次成交(on_future_trade_rtn) 打印订单成交信息

收盘后(after_trading) 打印当天的收益情况

二、代码结构对应的策略流程

  1. initialize(context) – 初始化

你可以理解为:

回测/实盘一开始,只执行一次的“策略设置”阶段。

里面主要做了几件事:

指定账户
context.account = ‘5588’

在回测框架里,5588 是期货账户的编号,相当于“用哪个期货账号来交易”。

指定交易标的
context.underlying_symbol = ‘AG_DOMINANT.SHF’

这是“白银主力连续合约”的代码。

它不是一个真正可以直接下单的合约,而是一个“主力合约的别名”。

每天需要再查一次当日真正的主力月份合约,例如 AG2506.SHF。

设置均线参数
context.short_window = 10 # 短期均线天数
context.long_window = 30 # 长期均线天数

短期均线:最近 10 天收盘价的平均值。

长期均线:最近 30 天收盘价的平均值。

用短 vs 长 的交叉来产生买卖信号。

准备保存历史价格与信号
context.close_history = [] # 保存真实合约的历史收盘价
context.prev_signal = 0 # 上一日信号:1多,-1空,0无
风险与仓位管理参数
context.risk_fraction = 0.2 # 每次最多用 20% 总权益做保证金
context.max_leverage = 5.0 # 总敞口不超过 5 倍杠杆
context.min_hands = 1 # 最少交易 1 手

context.commission_rate = 0.00005 # 假设万五手续费(单边)
context.margin_rate = 0.12 # 假设保证金率 12%

这些参数都是用来限制“本次最多开多少手”,防止满仓梭哈。

订单列表用于记录
context.order_ids = []

保存下单返回的订单 ID,方便在成交回报里核对和调试。

  1. _get_main_contract_symbol() – 找主力月合约

_get_main_contract_symbol(trade_date, underlying_symbol)
作用:

给它一个日期 trade_date 和主力连续代码 AG_DOMINANT.SHF,它去 panda_data 查询这一天到底哪一个具体合约是主力,比如 AG2506.SHF,然后返回这个真正可以交易的代码。

使用的接口是:panda_data.get_market_data(…, type=“future”)

返回的表里有两列:

dominant_id:主力月的短代码,比如 AG2506

exchange:交易所,比如 SHF

最后拼成 AG2506.SHF 这样的标准代码。

  1. _calc_position_size() – 计算应该开多少手

函数签名:

_calc_position_size(total_value, price, contract_multiplier,
risk_fraction, max_leverage,
margin_rate, min_hands)
它要解决一个问题:

在我现在有 total_value 这么多总权益,合约价格是 price,合约乘数是 contract_multiplier,并且我设定了“风险资金最大用多少”“总杠杆最大多少”这几条规则的情况下,本次最多可以开多少手?

关键约束:

风险资金上限:

可用保证金上限 = total_value * risk_fraction

杠杆限制:

总名义敞口 <= total_value * max_leverage

保证金 = 名义敞口 × 保证金率:

名义敞口:合约价格 × 合约乘数 × 手数

手数必须是整数,且 >= 最低手数 min_hands。

步骤:

根据风险资金算一个 “允许的最大名义敞口”:
notional_by_margin = (total_value * risk_fraction) / margin_rate
根据杠杆限制算另一个最大名义敞口:
notional_by_leverage = total_value * max_leverage
取两者中的较小者:
max_notional = min(notional_by_margin, notional_by_leverage)
算单手名义价值:
per_hand_notional = price * contract_multiplier
用 max_notional 除以每手价值:
hands = int(max_notional // per_hand_notional)

这里用了整除 //,自动向下取整。

如果算出来小于最小手数 min_hands,就不开仓(返回 0)。

  1. handle_data(context, data) – 每天的交易逻辑

这个是策略最核心的部分,每个交易日执行一次。

(1) 拿到当日主力月合约代码

real_symbol = _get_main_contract_symbol(trade_date, context.underlying_symbol)

比如得到 AG2506.SHF。

(2) 从 data 中取出它的行情 bar

bar = data[real_symbol]
close_price = bar.close

这里用的是 日线 bar:

open/high/low/close/volume 等信息

策略只用收盘价 close。

(3) 维护价格历史

context.close_history.append(close_price)
if len(context.close_history) > context.long_window:
context.close_history.pop(0)

只保存最近 long_window(30)天的数据。

如果不足 30 天,就先不做交易:
if len(context.close_history) < context.long_window:
print(“历史数据不足…等待累积”)
return

(4) 计算短期/长期均线

short_ma = np.mean(context.close_history[-context.short_window:])
long_ma = np.mean(context.close_history)

短期均线 = 最近 10 天收盘价的平均值

长期均线 = 最近 30 天收盘价的平均值

(5) 判定当前信号方向

if short_ma > long_ma:
current_signal = 1 # 看多
elif short_ma < long_ma:
current_signal = -1 # 看空
else:
current_signal = 0 # 无方向
(6) 读取当前持仓

futures_account = context.future_account_dict.get(context.account)
positions = futures_account.positions
position = positions.get(real_symbol) if positions else None

long_qty = position.buy_quantity if position else 0
short_qty = position.sell_quantity if position else 0
closable_long = position.closable_buy_quantity if position else 0
closable_short = position.closable_sell_quantity if position else 0

buy_quantity = 当前多头持仓手数

sell_quantity = 当前空头持仓手数

closable_* = 今日可以平掉的部分

(7) 只在“信号发生变化”时交易

prev_signal = context.prev_signal
context.prev_signal = current_signal

if current_signal == prev_signal:
return # 信号没变,不调仓

避免每天都调仓,只在“从多变空/从空变多/从无变成有信号”等这些交叉点操作。

(8) 获取合约乘数并计算本次目标手数

先从 panda_data.get_future_list 拿到合约乘数:

contract_df = panda_data.get_future_list(
symbol=[real_symbol],
fields=[“symbol”, “contract_multiplier”],
is_trading=None
)
contract_multiplier = float(contract_df.iloc[0][“contract_multiplier”])
再用刚才讲的 _calc_position_size() 计算:

target_hands = _calc_position_size(
total_value=futures_account.total_value,
price=close_price,
contract_multiplier=contract_multiplier,
risk_fraction=context.risk_fraction,
max_leverage=context.max_leverage,
margin_rate=context.margin_rate,
min_hands=context.min_hands,
)

total_value = 总资产(含持仓市值和现金)

若算出来 target_hands == 0,直接放弃这次信号,不开仓。

(9) 根据信号执行交易

1)金叉:从空/空仓 → 看多

if current_signal == 1 and prev_signal <= 0:
# 1) 平掉所有空头
if closable_short > 0:
buy_close(context.account, real_symbol, closable_short)
# 2) 开多至目标手数
if long_qty < target_hands:
open_hands = target_hands - long_qty
buy_open(context.account, real_symbol, open_hands)
2)死叉:从多/空仓 → 看空

elif current_signal == -1 and prev_signal >= 0:
# 1) 平掉所有多头
if closable_long > 0:
sell_close(context.account, real_symbol, closable_long)
# 2) 开空至目标手数
if short_qty < target_hands:
open_hands = target_hands - short_qty
sell_open(context.account, real_symbol, open_hands)
这里用到的交易函数:

buy_open :买入开仓(建立多头)

sell_open :卖出开仓(建立空头)

buy_close :买入平仓(平掉空头)

sell_close :卖出平仓(平掉多头)

MarketOrderStyle:市价单,即按当前市场价成交。

  1. 报单回报 & 开盘前/收盘后

on_future_trade_rtn(context, order)

每当有期货订单成交,就会触发这里:

打印:订单ID、合约代码、买卖方向、开仓/平仓、价格、数量、状态等

如果订单已成交,且在 context.order_ids 里,就移除(表示这笔订单已经结束)。

before_trading(context)

开盘前(每天一次):

打印当前日期、账户总权益、可用资金、保证金占用。

after_trading(context)

收盘后(每天一次):

打印总权益、持仓浮动盈亏、已实现平仓盈亏。

三、策略中涉及的关键专有名词解释

下面集中把刚才已提到的名词,再用更系统的方式解释一下。

  1. 主力连续合约(AG_DOMINANT.SHF)

主力合约:某个期货品种里,当前成交最活跃、持仓量最大的那个月份合约。

连续合约:平台帮你自动“拼接”主力合约的历史:

2024年主力是 2406 → 就用 2406

过一段时间主力换到 2412 → 就自动切到 2412

主力连续合约代码:AG_DOMINANT.SHF 就是“白银主力”的一个虚拟代码。

真实下单时还是要用具体合约,比如 AG2506.SHF。

在你的代码里:

context.underlying_symbol = ‘AG_DOMINANT.SHF’
real_symbol = _get_main_contract_symbol(…)
就是先用连续代码找出当日真正的主力月。

  1. 合约乘数(contract_multiplier)

每一手期货代表的“标的数量”,比如:

假设白银期货是 “1 手 = 15kg 白银”(具体数值以交易所真实规则为准)

在代码里:

每手名义价值 = 价格 × 合约乘数

用于计算名义敞口、保证金等。

  1. 名义敞口 / 杠杆

名义敞口(notional exposure):

持仓规模折算成“标的价值”的金额

= 合约价格 × 合约乘数 × 手数

杠杆倍数(leverage):

= 名义敞口 ÷ 账户总权益

如果总权益 100万,名义敞口 500万,杠杆 = 5 倍

你的代码里:

max_leverage = 5.0 → 名义敞口最多控制在 5 倍以内。

  1. 保证金 / 保证金率(margin_rate)

期货不是一次性付全款,而是只需要先缴纳一部分作为保证金。

保证金率:

比如保证金率 12%,意味着:

做 100 万的名义敞口,只需要交 12 万保证金。

在代码里:

margin_rate = 0.12
notional_by_margin = (total_value * risk_fraction) / margin_rate
意思是:

先规定:我愿意拿 20% 账户总资产做保证金(risk_fraction)

再根据保证金率反推回,最多可以承受多少名义敞口。

  1. 手续费率(commission_rate)

这里设的是 0.00005,就是万分之 0.5(万五)

实际回测中的真实费用由回测引擎决定,这个参数更多是用来预估与风险控制。

  1. 均线、金叉、死叉

移动平均线(Moving Average, MA):

N 日均线就是:最近 N 天的收盘价平均值。

短期均线:这里是 10 日均线

长期均线:这里是 30 日均线

金叉(Golden Cross):

短期均线从下向上穿过长期均线。

一般被解读为“趋势由空转多”,买入信号。

死叉(Dead Cross):

短期均线从上向下穿过长期均线。

一般被解读为“趋势由多转空”,卖出或做空信号。

代码中用 prev_signal 和 current_signal 来识别“交叉”:

current_signal == 1 且 prev_signal <= 0 → 金叉

current_signal == -1 且 prev_signal >= 0 → 死叉

  1. 多头 / 空头 / 开仓 / 平仓

多头(long):

你买入一手白银期货,赌的是“价格会上涨”。

空头(short):

你先卖出一手期货(不需要事先持有),赌的是“价格会下跌”。

开仓:建立新的仓位。

多头开仓:buy_open

空头开仓:sell_open

平仓:了结现有仓位。

多头平仓:sell_close

空头平仓:buy_close

在这个策略:

金叉 → 平空 + 开多

死叉 → 平多 + 开空

  1. 市价单(MarketOrderStyle)

市价单:以当前市场能成交的价格尽快成交,不事先指定具体价位。

优点:基本能成交

缺点:成交价格可能有一定滑点(与当前看到的价格略有差距)。

  1. 持仓量字段

在期货持仓对象里:

buy_quantity:当前多头手数

sell_quantity:当前空头手数

closable_buy_quantity:今日可平的多头手数

closable_sell_quantity:今日可平的空头手数

策略里的用法:

closable_* 用于平仓;

*_quantity 用于判断已经有多少仓位,避免重复加仓到超过目标值。

四、如果你完全是小白,可以先这样理解

你只需要看:

白银期货价格趋势 → 用两条均线去判断。

只在“趋势发生拐点”的时刻进场:

短期线从下穿上 → 市场可能转多 → 做多白银。

短期线从上穿下 → 市场可能转空 → 做空白银。

每次下多大仓位,不是凭感觉,而是根据:

当前总资产有多少

你愿意冒多大风险(最多用资产的 20% 做保证金)

不让杠杆超过 5 倍

程序会自动:

先平掉当前反方向的仓位

再建立新的方向仓位到目标规模

如果你希望,我可以在下一步帮你:

画一张“时间线 + 价格 + 均线 + 交易点”的示意图来解释一次完整的交易;

或者,把参数改成更保守 / 更激进的版本,告诉你会有什么风险变化。

1.2 ai工作流助手

  1. 自然语言交互直接生成完整工作流
    image.png
  2. 完整的回测模块;
    image.png
最后一次编辑于 30天前 0

暂无评论

推荐阅读
  tyler   23小时前   15   0   0 新手入门