按目前的机制,仓位是不可控的。


(chaoskey) #1

按目前的机制,仓位是不可控的

问题

我们知道,大宽今天的下单调用完全确定了第二天交易计划。

为了简单起见,我今天决定全仓买一只股票(也就是下个交易日的计划,比如,买入600股),计划明天开盘买入。

当然,今天计算出来的买入量完全由今天的收盘价决定,使得仓位接近100%。 如果下个交易日,开盘价远高于昨天的收盘价,那么实际上买入量应该小于600股,否则无法成交。

可悲剧的是, 系统在资金不够的前提下,依然可以以600股买入(使得仓位大于100%)。 更悲剧的是,这种系统买入成交,不由客户代码控制。

如果这个问题没有解决, 很难用于实盘。

建议

我的建议,既然第二天系统下单我们客户代码无法控制,那么系统就应该负责控制以合适的下单量成交,而不是按计划下单量成交。 进而确保仓位不超过100%.

简单验证

刚才我故意以 200%的仓位调用下单API,居然第二天也能成交(回测显示)。

context.order_target_percent(context.symbol(‘000613.SZA’), 2)

成交后的信息:

(总资产¥99945.97 剩余金额¥-80054.04 当日交易费用¥54.0)

即是我设置了: context.set_long_only() 也没用。


(iQuant) #2

您好,谢谢您反馈问题。你的描述如您所说,确实是这样。(这是事实但并不是真相)

目前的股票回测平台,国内的前几家都是采取统一的回测框架,其都是采取 前一个bar下单,下一个bar实际成交这样的机制,如果k线是日线数据,那么就是前一天下单,第二天成交,如果是分钟数据,那么就是前一分钟下单,下一分钟实际成交,这样的机制也被称作事件驱动机制,最大的好处是切合实际规避未来函数,目前是一种比较流行的做法。

回测引擎没有做限制仓位的设置,这是默认的设置,其最大的好处就是能够适当引入融资,最后分析的时候,如果可以做相应计算转换成没有杠杆下的实际策略指标,例如,如果杠杆始终为2,收益率是20%,可以最终转化为杠杆为1,收益为10%。我们承认,这样的设置可能给大家带来一定的困扰和麻烦,因此我们正在解决,希望能够解决您所说的这种情况。

此外,如果您对我们的订单(order接口)了解的话,其实也不会出现您帖子里所描述的情况。订单的文档介绍可以参考:文档-交易引擎-Order

您可以使用,order(),order_target(),order_value(),order_target_value() 这些接口并不会出现您帖子里描述的问题(帖子里使用的是order_target_percent)。

比如我资金1万,股价100元,我全仓买入,那么就可以买入100股,如果第二天价格高开涨到了200元,那么其实不会成交100股,而是只成交50股。按成交金额成交的话,就不会出现仓位不可控的情形。

set_long_only()是这个意思,表明不能做空。(做空和卖出是有差别的,有1手股票,然后卖出1手,这是卖出;如果卖出10手股票,多卖9手,这就是做空)。猜想,你提到的是不是set_max_leverage() ,这个表明,设置最大杠杆是多少,比如set_max_leverage(1)表明,最大杠杆就是1,不能融资。但,这个设置只表明当仓位超出1的时候会报错,程序停止运行,不能解决超出以后,遇到继续下单忽略下单的问题。

不管怎样,我们与用户做朋友,我们会继续优化下单接口。

非常感谢您的反馈!


(chaoskey) #3

@iQuant

谢谢,您的回复。 在发帖之前 order(),order_target(),order_value(),order_target_value() 我都试过了。 好像依然有问题。

既然,你提到到了,为谨慎起见。 我在再仔细运行确认一下。

“比如我资金1万,股价100元,我全仓买入,那么就可以买入100股,如果第二天价格高开涨到了200元,那么其实不会成交100股,而是只成交50股”

其实希望的就是上段话多对应的功能。

可能话,最好限定为100股100股的买入。 虽然代码里可以控制,但只能控制计划,无法控制你们依然可能以50股成交。。 但实际情况, 比如计划买一百股, 如果资金不够的话,正确情况是买0股,也就是就是不买。

谢谢。


(chaoskey) #4

@iQuant 经过我的初步验证, 按成交金额成交。 问题依旧。

print("-------[%s]----------"%today)
#我故意设置初始资金为:10000元, 然后故意以20000元资金下单。, 故意使得下单资金大于可用资金。
#看看系统能否自动限制下单量。
context.order_target_value(context.symbol(‘002193.SZA’), 20000)

然后查看每日持仓和收益:

日期 股票代码 收盘价(元) 股数 持仓(元) 收益(元)
2017-09-22 002193.SZA 34.19 591.66 20228.86 151.08
(总资产¥10151.08 剩余金额¥-10078.53 当日交易费用¥6.02) ¥20228.86 ¥151.08

剩余金额¥-10078.53 ,这说明即使 按成交金额成交 , 系统也无法控制实际下单量。


(chaoskey) #5

@iQuant 针对你说的 “ 前一个bar下单,下一个bar实际成交这样的机制。” 并不是所有的平台都是这样。

1) 你们或有些平台: 前一个bar下单,下一个bar实际成交。

下一个bar的成交是不受客户代码控制的。无法做到比如:一个单子无论其成功成交与否,都可以立刻获取其成交状态,然后决定下一个单子是否继续还是换股。

优点: 不可能有未来数据

2)当前bar下单并成交,但获取的数据是上一个bar的数据。

在当前bar下单后(仅对市价单而言)立刻就能获取其成交状态,进而可以决定下一个单子是否继续还是换股。

缺点: 可能能获取到未来数据。 但只要客户代码始终确保获取上一个bar的数据,这个缺点都不是缺点。


(iQuant) #6

是的,如果成交额超过剩余现金,依然会成交。
因此控制好仓位的更好办法还是要在代码里实现。


(chaoskey) #7

@iQuant 问题就出在这里:在代码里也可能无法控制 明天的情况。

比如: 今天总持仓价值20000元, 剩余现金100元。 而今天计算的结果(也就是明天的下单计划): 先卖出10000元股票A,再买入10000元股票B (这种计划是完全合理的,暂时不考虑手续费)。 A,B股票在今天都没有停牌 也没有涨跌停。

        可是,第二天开盘后发现,  股票A停牌 或 开盘跌停了, 股票B正常交易。

按你们的当前逻辑:  A股无法卖出,  B股可以正常买入(实盘是不可能的)。

于是 成交后, 剩余资金变成: -10000元左右, 而总持仓价值变成了30000元, 进而仓位变成 150%.


(chaoskey) #8

@iQuant

如果你们能在第二天成交时, 系统发现资金不足, 自动减量成交,或如果发现可买股票小于100股,自动不成交。

问题就解决了。

我们的客户代码无法预测明天的资金是否足够(至少停牌、开盘跌停的事无法预测),这件事只能能你们系统干。 因为,你们系统成交时,应该已经能知道下单的资金是否足够,而头一天我们的客户代码无法知道。


(chaoskey) #9

@iQuant

前面已经谈及:即使用户试图主动控制仓位, 用户的代码也可能无法完全控制明天系统成交后的仓位。

现在谈另一个方面:用户故意不进行仓位控制, 比如下面我举的一个极端例子:

“如果成交额超过剩余现金,依然会成交。” 本质上就是说系统允许具有无穷现金的可能。

而拥有无穷现金的可能进而意味着: 对网格交易策略而言可以造假。

因为网格交易策略之所以可能失败,是因为资金不够。 而拥有无穷现金的可能,导致网格交易在你们系统中是一个永远不可能失败的策略。 因为价格下跌一格就加仓(拥有无穷现金所以放心加仓,而价格不可能永远跌下去),价格上涨一格就减仓。


(iQuant) #10

你说,如果我们平台设置,下单买入金额不能超过剩余现金,是不是就解决你的疑惑了呢?


(chaoskey) #11

@iQuant “下单买入预估金额不超过剩余现金” 不能推导出 “第二天,下单实际成交金额不超过剩余现金”。 所以我的疑惑还是没有解决。 关键是第二天可能不可控。

比如: 今天总持仓价值20000元, 剩余现金100元。 而今天计算的结果(也就是明天的下单计划): 先卖出10000元股票A,再买入10000元股票B (这种计划是完全合理的,暂时不考虑手续费)。 A,B股票在今天都没有停牌 也没有涨跌停。

    可是,第二天开盘后发现,  股票A停牌 或 开盘跌停了, 股票B正常交易。

按你们的当前逻辑: A股无法卖出, B股可以正常买入(实盘是不可能的)。
于是 成交后, 剩余资金变成: -10000元左右, 而总持仓价值变成了30000元, 进而仓位变成 150%.

关键是,如果你们能够保证第二天,资金不够,减量成交 。 (极端情况,只能买0股,即不成交) 就OK了。


(iQuant) #12

那这样的话,我们引进四个字段,分别为下一交易日是否一字涨停、是否一字跌停、停牌、正常。在前一日生成信号的时候就可以过滤订单,这样在回测中是没有问题的。


(chaoskey) #14

@iQuant

但你这样做感觉上不合理呀。 你头一天并不知道第二天的情况。

你们的系统为何就不在第二天系统撮合成交时: 资金不够,减量成交 。 (极端情况,只能买0股,即不成交)


(iQuant) #15

之所以采取上一个bar出信号,下一个bar成交是为了为以后分钟线回测做基础。


(iQuant) #16

我们目前的想法就是这样的,支持好了我们通知你。


(chaoskey) #17

期待你们的系统越做越好。 :)


(飞天猫大浩) #18

您好,请问一下,您知道您反馈的这个问题,在聚宽平台是怎么处理的吗?


(chaoskey) #19

聚宽的处理方式:

当一个Bar被触发后:

1) 在当前Bar, 客户代码负责读取上一个Bar以及之前的历史数据进行分析 。
【当然如果客户代码执意要读取当前Bar的数据,比如收盘价,可能存在未来数据。 只要客户代码注意这点,也就不会存在未来数据】

2) 在当前Bar,经过1)分析后,如果决定要下单。 下单后可以同步返回单子的成交与否的状态以及成交量,同时系统持仓也会同步变化。 并且,如果某笔下单资金不足,聚宽会自动减量成交(极端情况下0股,即不成交)
【也就是说:当前Bar下单当前Bar成交, 当然都是对市价单而言】

而 大宽的系统是: 当前Bar下单, 下一个Bar成交。 大宽的机制导致客户代码无法控制下一个Bar的成交,及其后续处理。