经常有这样的疑问:
- 为什么我明明下单了,但是在交易记录中却找不到?
- 为什么我用获取到的order对象(实际上是None)查看order信息,总是报错
'NoneType' object has no attribute XXX
?
- 期货应该如何下单,以及如何平仓呢?
希望这篇帖子能帮助您解决您的疑惑。
可用于下单的函数:
- 注意!这四个函数是有区别的,下边用红色字体标出 *
- 注意!这里没有考虑滑点,关于滑点对成交价的影响: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
(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))
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的整数倍, 但是卖光所有股票时不受这个限制
根据交易所规则, 每天结束时会取消所有未完成交易