请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  量化平台 帖子:3365785 新帖:17

【API解析】| 关于下单函数的说明

不做外汇索罗斯发表于:5 月 9 日 17:36回复(1)

经常有这样的疑问:

  1. 为什么我明明下单了,但是在交易记录中却找不到?
  2. 为什么我用获取到的order对象(实际上是None)查看order信息,总是报错 'NoneType' object has no attribute XXX?
  3. 期货应该如何下单,以及如何平仓呢?
    希望这篇帖子能帮助您解决您的疑惑。

可用于下单的函数:


  • 注意!这四个函数是有区别的,下边用红色字体标出 *
  • 注意!这里没有考虑滑点,关于滑点对成交价的影响:https://www.joinquant.com/post/16439 *

(1) order(security, amount,...)

    按股(手)数下单

  将仓位中的股票数量调整至目标数量比较容易理解,直接下多少股/手的单

  • 示例:
    • order('000001.XSHE',100) 买进100股平安银行
    • order('000001.XSHE',-100) 卖出100股平安银行,如果没有仓位,会有相关的warning
    • order('000001.XSHE',99) 下单数不足一手,调整为0股,订单取消,返回None,会有相关的warning
    • order('IF1901',10,side='long') 开多10手IF1901 默认side='long',所以当开多仓或者平多仓时可以不指定side
    • order('IF1901',-5,side='short') 平空5手IF1901,如果空仓仓位不足5手,则平掉所有空仓,有相关warning

(2) order_target(security, amount, ...)

     按目标股(手)数下单
  将仓位中的标的数量调整至目标数量,比如下单前仓位中有500股平安银行,如果使用order_target('000001.XSHE',100

  • 股票示例(假设下单前已经持有了平安银行500股且全部可平仓):

    • order_target('000001.XSHE',700) 调整平安银行的持股数至700股,也就是再买入200股平安银行
    • order_target('000001.XSHE',200) 调整平安银行的持股数至200股,也就是卖出300股平安银行
    • order_target('000001.XSHE',500) 目标数量已满足,不再调整

    • 注:当value为0时,即时有不足100股的股票,也会全部进行平仓

  • 期货示例(假设下单前已经持有了IF1901空单5手,多单3手)
    • order_target('IF901.CCFX',2,side='long') 调整多单仓位至2手,之前已经有3手多单,所以平掉一手多单
    • order_target('IF901.CCFX',7,side='short') 调整空单仓位至7手,之前已经有5手空单,所以在开2手空单
    • order_target('IF901.CCFX',5,side='short') 空单仓位数量已经满足,不再调整,不会创建order对象,返回None,会有相关日志输出

(3) order_value(security, value, ....)

     按价值下单
  按照标的的价值进行下单,会根据下单的value调整交易的数量,当下单的手数不足一手的整数倍时,向下调整至一手的整数倍

  • 股票示例(假设平安银行下单时最新价为10元):

    • order_value('000001.XSHE',10000) 10000/10 = 1000股 ,买入平安银行1000股
    • order_value('000001.XSHE',750) 7500/10 = 750股,调整为700股,买入平安银行700股
    • order_value('000001.XSHE',999) 999/10 = 99.9股,调整为0股,不会创建order对象,返回None,会有相关日志输出
    • order_value('000001.XSHE',-2000) -2000/10 = -200 股,等同于order('000001.XSHE',-200)
  • 期货部分

    • 期货是保证金交易,下边将单独进行讲解期货的order_value和order_target_value

(4) order_target_value(security, value, ...)

     按目标价值下单
  可以参考order_value和order_target,按照满足标的在仓位中的目标价值下单,会根据下单的value和已有的仓位调整下单手数,不足一手的整数倍时,向下调整为一手的整数倍

  • 股票示例(假设目前已持有平安银行500股且全部可平仓,下单时最新价为10元):
    • order_target_values('000001.XSHE',10000) 10000/10 = 1000股,也就是再买入500股平安银行
    • order_target_values('000001.XSHE',5000) 5000/10 = 500股,目标数量已满足,不会创建order对象,返回None,会有相关日志输出
    • order_target_values('000001.XSHE',5999) 5999/10 = 599.9股,调整为500股,目标数量已满足,不会创建order对象,返回None,会有相关日志输出
    • order_target_values('000001.XSHE',3550) 3550/10 = 355股,应当卖出145股,调整为100股,卖出100股平安银行
    • 注:当value为0时,即时有不足100股的股票,也会全部进行平仓

期货部分

注意!期货是保证金交易,所以策略中涉及到的starting_cash,available_cash(可用资金)等是指的是可用于交易的保证金,下单所消耗的也是这些可用保证金。而order_value,order_target_value中的value参数也指的是消耗保证金,而不是标的资产的价值!


  • 情景1:
    • 比如说,使用order_value('CU1903.XSGE',10000000*0.05), 设置保证金比例为0.05,CU合约乘数为5。
      当前CU1903.XSGE为47690点,则会下单 int(10000000/(47690×5))= 41手
  • 情景2:已经持仓价值为1000万的股票,现在想使用等规模的IF1901货进行对冲,那么 value = 1000万×保证金比例(股指期货默认0.15)
    • order_target_value('IF1901.CCFX',1000000*0.15,side='short')
    • 计算方法:假设当前时刻IF1901的价格为3000点(IF合约乘数为300)
      1000万/(3000点*300) = 11.11 ,向下取整为11手,也就是下11手的空单,如果空单仓位中已经有底仓,调整方式和股票相同

期货部份下单计算的策略演示demo文末回测


关于下单函数中的其他参数

style 设置下单的类型

  • MarketOrderStyle() 下市价单,默认 style = MarketOrderStyle()
  • LimitOrderStyle(P) 下限价单,买入时价格不得高于P,卖出时价格不得低于P(期货开平空逻辑和开平多逻辑相反)
  • 按天回测中,由于都是使用天bar线撮合,所以下限价单时,如果当前价不满足限价 滑点,那么都是盘后才成交,盘中仓位及成交信息不会进行更新,15:00后才会进行更新,所以限价单建议使用分钟频率。
  • 限价单并不是以一个指定的价格成交,而是以等于或者低于设置的委托价的价格成交
    示例:
    order('000001.XSHE', 100) # 下一个市价单  
    order('000001.XSHE', 100, MarketOrderStyle()) # 下一个市价单, 功能同上  
    order('000001.XSHE', 100, LimitOrderStyle(10.0)) # 以10块价格下一个限价单
    

side 设置下单多空方向

  • side = 'long' 开/平多仓,默认为'long'
  • side = 'short' 开/品空仓,股票,基金不能开空

  • 注意,我们不会主动帮您将多空直接对冲掉,而是在long_position和short_position中分别操作,side也是分别对这两个仓位进行操作。
    比如您之前仓位中有IF1901十手多单,现在如果下一个order('IF1901.CCFX',10,side='short'),那么long_position和short_position中将各自有一个10手的单,而不是将IF1901的多单对冲掉

pindex 指定仓位

  • 在使用set_subportfolios创建了多个仓位时,指定subportfolio 的序号, 从 0 开始, 比如 0 指定第一个 subportfolio, 1 指定第二个 subportfolio,默认为0。

close_today 是否优先平今仓

注意!这个参数对不同交易所的逻辑是不一样的:

  • close_today = True, 对非上期所交易的期货标的优先平今,超出则平昨仓,上期所交易的期货标的则仅仅表示平今仓
  • close_today = False, 对非上期所交易的期货标的优先平昨,超出则平今仓,上期所交易的期货标的则仅仅表示平昨仓
  • close_today 仅仅对上海国际能源中心,上海期货交易所,中金所起作用,平仓数量超出则报错

为什么已经下单了,却没有成交?

可能失败的原因:

  • 1.使用order_target或者order_target_value,经过调整后目标数量已满足,不再下单,交易函数返回None
  • 2.可用资金不足,调整后不足一手,不再下单,交易函数返回None
  • 3.股票停牌,交易函数返回None
  • 4.股票未上市或者退市,交易函数返回None
  • 5.股票不存在/代码错误(注意代码的后缀,另外平台不提供05年之前已经退市的股票数据),交易函数返回None
  • 6.为股票、基金开了空单,交易函数返回None
  • 7.选择了不存在的仓位号,如没有建立多个仓位,而设定pindex的数大于0,交易函数返回None
  • 8.限价单未满足(注意滑点对于限价单的影响),返回order对象,在未成交之前订单状态为open
  • 9.为了避免以不合理的价格对标的进行下单,模拟盘在下单时会检查开盘(9:25)到下单时刻的累积成交量,若为0则会拒绝,提示:WARNING - 该标的截至到目前成交量为0 ,暂时无法成交。

注意:
当订单直接变为废单时,下单函数会返回None而不是order对象,此时直接调用order对象的属性会引发报错'NoneType' object has no attribute "XXX"

解决方法:

 Order = order('000001.XSHE',1000)
 if not Order:
     print('下单失败')
 if Order:
     print(Order.filled)  #打印已成交数量

注意:

因为下列原因, 有时候实际买入或者卖出的股票数量跟您设置的不一样,这个时候我们会在您的log中添加警告信息。

  • 买入时会根据您当前的现金来限制您买入的数量
  • 卖出时会根据您持有股票的数量来限制您卖出的数量
  • 我们会遵守A股交易规则: 每次交易数量只能是100的整数倍, 但是卖光所有股票时不受这个限制
    根据交易所规则, 每天结束时会取消所有未完成交易

全部回复

0/140

量化课程

    移动端课程