账户与下单示例
策略算出信号后,下一步就是下单。极智量化提供两套下单函数:一套简单、自动管理策略仓,适合回测;一套精细、直连真实账户,适合实盘。本章讲清它们的区别、常用账户函数,以及回测与实盘的切换。
两套下单函数
| 组别 | 函数 | 特点 | 适用场景 |
|---|---|---|---|
| 简单组 | Buy / Sell / SellShort / BuyToCover | 参数少、自动管理虚拟策略仓 | 历史回测首选 |
| 账户组 | A_SendOrder / A_DeleteOrder / A_ModifyOrder | 可指定账户、价格、开平标志、订单类型 | 实盘精细控制 |
简单组的四个函数对应期货四类操作:
| 函数 | 含义 |
|---|---|
Buy(qty, price) | 多头建仓(买开) |
Sell(qty, price) | 多头平仓(卖平) |
SellShort(qty, price) | 空头建仓(卖开) |
BuyToCover(qty, price) | 空头平仓(买平) |
# 以最新收盘价买开 1 手基准合约;needCover=True 时若有反向仓先平后开
Buy(1, Close()[-1])
# 指定合约下单
Buy(1, Close()[-1], contractNo="ZCE|Z|AP|MAIN")
回测阶段,
Buy/Sell系列会向虚拟撮合引擎发单并立即成交(只要资金和仓位允许);实盘阶段,它们同时向虚拟引擎和真实交易后台发单。
A_SendOrder:精细下单
A_SendOrder 针对指定账户、合约发送委托,返回 retCode, retMsg:成功时 retCode 为 0、retMsg 为下单编号;失败时 retCode 为负数。常用参数:
retCode, retMsg = A_SendOrder(
Enum_Buy(), # 买卖方向:Enum_Buy/Enum_Sell
Enum_Entry(), # 开平类型:Enum_Entry开/Enum_Exit平/Enum_ExitToday平今
1, # 委托数量
Q_AskPrice(), # 委托价格
ContractId, # 合约号
UserId, # 账户号
Enum_Order_Limit(), # 订单类型:限价单/市价单
Enum_GFD(), # 有效类型:当日有效
Enum_Speculate() # 投保标志:投机/套保/套利
)
撤单与改单:
A_DeleteOrder(orderId) # 撤指定订单
DeleteAllOrders() # 撤当前策略订阅合约的所有排队单
A_SendOrder直接发单、不经过确认,会在每次公式计算时发送,务必配合仓位和条件判断使用,不清楚机制时慎用。
常用账户函数
账户函数以 A_ 开头,用于读取真实账户的资金、持仓、订单状态(需先在客户端登录账户):
| 函数 | 含义 |
|---|---|
A_AccountID() | 当前交易账户 ID |
A_Available() | 可用资金 |
A_Assets() | 账户权益(动态权益) |
A_BuyPosition() | 买仓(多)总量 |
A_SellPosition() | 卖仓(空)总量 |
A_BuyPositionCanCover() | 多仓可平数量 |
A_SellPositionCanCover() | 空仓可平数量 |
A_TotalPosition() | 总持仓(正多负空) |
A_OrderStatus(id) | 查询订单状态 |
A_OrderFilledPrice(id) | 订单成交价 |
订单状态用枚举判断:Enum_Filled()(完全成交)、Enum_PartFilled()(部分成交)、Enum_Canceled()(已撤)、Enum_Suspended()(已挂起/排队中)等。
持仓状态:MarketPosition
MarketPosition() 返回当前虚拟策略仓的状态,是简单组下单最常用的判断依据:
1:多头持仓(买仓 > 卖仓)-1:空头持仓(卖仓 > 买仓)0:持平
if MarketPosition() <= 0 and 金叉条件:
Buy(1, Close()[-1]) # 持平或空头时,金叉买开
elif MarketPosition() >= 0 and 死叉条件:
SellShort(1, Close()[-1]) # 持平或多头时,死叉卖开
回测 vs 实盘
| 项目 | 历史回测 | 实盘 |
|---|---|---|
| 撮合 | 虚拟后台,资金仓位满足即成交 | 交易所撮合 |
| 初始资金 | 用户设置 | 真实账户资金 |
| 发单方式 | 只能 K 线稳定后发单 | 可选实时发单 / K 线稳定后发单 |
| 触发方式 | 只能 K 线触发 | 八种触发可组合 |
开启实盘需要两步:在代码里调 SetActual()(或在界面勾选「实盘运行」)+ 登录并关联对应交易账户(SetUserNo 或界面选择)。连接状态变化时可用 StartTrade() / StopTrade() 恢复或暂停实盘下单。
只想回测、不跑实盘?在
handle_data开头加if context.triggerType() != 'H': return,过滤掉实时事件。
一个双均线回测示例
import talib
g_params['FastLength'] = 5
g_params['SlowLength'] = 20
def initialize(context):
SetBarInterval('ZCE|Z|TA|MAIN', 'M', 1, 500)
SetTriggerType(5)
SetOrderWay(2) # K线稳定后发单
def handle_data(context):
if CurrentBar() < g_params['SlowLength']:
return
ma1 = talib.MA(Close(), g_params['FastLength'])
ma2 = talib.MA(Close(), g_params['SlowLength'])
PlotNumeric('ma1', ma1[-1], 0xFF0000)
PlotNumeric('ma2', ma2[-1], 0x00aa00)
# 用上一根 Bar 的均线关系判断,避免信号闪烁
if MarketPosition() <= 0 and ma1[-2] > ma2[-2]:
Buy(1, Close()[-1])
if MarketPosition() >= 0 and ma1[-2] < ma2[-2]:
SellShort(1, Close()[-1])
用
ma1[-2] > ma2[-2](上一根 Bar 的关系)而非[-1],是因为实时 K 线未稳定时最新价会跳动,容易造成「信号出现又消失」。实盘精细下单还要结合A_BuyPositionCanCover()等账户函数管理委托状态,可参考系统示例「账户示例」目录下的完整代码。
小结
回测用 Buy/Sell 简单组 + MarketPosition 判断;实盘用 A_SendOrder 账户组 + 订单状态枚举精细管理;开启实盘需 SetActual + 登录账户两步。信号判断尽量用上一根 Bar 的值避免闪烁。下一步进入 套利与常用示例,把多合约、止损止盈和参数优化串起来。