账户与下单示例

策略算出信号后,下一步就是下单。极智量化提供两套下单函数:一套简单、自动管理策略仓,适合回测;一套精细、直连真实账户,适合实盘。本章讲清它们的区别、常用账户函数,以及回测与实盘的切换。

两套下单函数

组别函数特点适用场景
简单组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 的值避免闪烁。下一步进入 套利与常用示例,把多合约、止损止盈和参数优化串起来。