大家好,今天我们来学习Pine语言中交易函数strategy系列。在学习完所有指标计算和信号判断语法结构后,我们对接真实的市场面对最后一道关卡:交易。期货交易之所以引人入胜,与其独有的T+0交易机制密切相关。一个点的波动就是盈利或者损失,成功的进行交易操作就可以将盈利立即收入囊中。所以怎样在合适的点位进行正确交易方向的操作,就需要strategy系列函数的应用。
在交易信号判断确定后,我们需要立即进行开仓操作,以免错过黄金交易时间。
strategy.entry函数是我们写策略时比较重要的一个下单函数,该函数比较重要的几个参数为:id, direction, qty, when等。
参数:
strategy(pyramiding=2)
strategy.entry("enter long1", strategy.long, 1, when = bar_index==1)
strategy.entry("enter long2", strategy.long, 2, when = bar_index==2)
strategy.entry("enter long3", strategy.long, 3, when = bar_index==3)
设置pyramiding=2,因此只能进行两次的加仓,第三次开仓不成功,设置条件when,在第一根k线,第二根k线开仓,这里也可以设置价格比如open>close等,qty设置开仓的数量。
我们再加上一个开空仓,看看有什么变化。
strategy.entry("enter short1", strategy.short, 1, when = bar_index==4)
可以发现,在开空仓之前,会平掉所有的多头仓位。由于Pine语言脚本持仓只能有一个方向,即如果有和当前持仓方向相反的信号触发会平掉当前持仓再根据信号触发开仓。
strategy.entry函数的具体执行细节受strategy函数调用时的参数设置控制,也可以通过「Pine语言交易类库模版参数」设置控制,Pine语言交易类库模版参数控制的交易细节更多,具体可以查看链接的文档。
strategy.opentrades 未关闭或者继续持有的交易数量。如果没有,则显示0。
strategy.opentrades.entry_bar_index(trade_num) 返回未平仓交易的入场的ID。trade_num (series int)是未平仓交易的交易编号。第一笔交易的编号为零。所以可以用strategy.opentrades-1代替。
strategy.opentrades.entry_price(trade_num) 返回未平仓交易的入场价格。
strategy.opentrades.profit(trade_num) 返回未平仓交易的盈亏。损失表示为负值。
strategy.opentrades.size(trade_num) 返回未平仓交易中的交易方向和合约数量。如果该值>0,则市场仓位为多头。如果该值<0,则市场仓位为空头。
strategy.opentrades.entry_time(trade_num) 返回未平仓交易入场的UNIX时间。
if bar_index == 1
strategy.entry("Long1", strategy.long)
runtime.log('opentrades',strategy.opentrades)
runtime.log('bar_index',strategy.opentrades.entry_bar_index(0))
runtime.log('entry_price',strategy.opentrades.entry_price(0))
runtime.log('entry_profit',strategy.opentrades.profit(0))
runtime.log('entry_size',strategy.opentrades.size(0))
runtime.log('entry_time',strategy.opentrades.entry_time(0))
strategy.close函数用于平仓指定标识ID的入场持仓仓位。主要参数有:id,when,qty。
参数:
通过一个例子来熟悉这个函数的使用细节:
strategy("close Demo", pyramiding=3)
strategy.entry("long1", strategy.long, 1)
if strategy.opentrades >= 3
// strategy.close("long1") // 多个入场订单,不指定qty参数,全部平仓
// strategy.close() // 不指定id参数,会平掉当前的持仓
// strategy.close("long2") // 如果指定一个不存在的id则什么都不操作
// strategy.close("long1", qty=1) // 指定qty参数平仓
// strategy.close("long1", qty_percent=70) // qty_percent设置50即为平掉long1标识仓位的50%持仓
// strategy.close("long1", qty_percent=80, when=close>open) // 指定when参数
测试策略展示了开始连续三次做多入场,入场标识ID均为“long1”,然后使用strategy.close函数的不同参数设置平仓时回测出的不同结果。可以发现strategy.close这个函数没有参数可以指定平仓下单价格,这个函数主要用于立即以当前市场价格平仓。
strategy.close_all函数用于平掉当前所有持仓。所以strategy.close_all被调用时会平掉当前方向上的所有持仓。strategy.close_all函数的主要参数为:when。
参数:
我们使用一个例子来观察:
strategy.entry("long1", strategy.long, 1, when=bar_index==1)
strategy.entry("long2", strategy.long, 1, when=bar_index==2)
strategy.close_all(when=bar_index==3)
可以发现strategy.close_all这个函数没有参数可以指定平仓下单价格,这个函数主要用于立即以当前市场价格平仓。
strategy.exit函数被用于入场持仓的平仓操作,与该函数不同的是strategy.close和strategy.close_all函数是以当前市场价格立即平仓。strategy.exit函数会根据参数设置进行计划平仓。
参数:
strategy("strategy.exit Demo")
strategy.entry("long1", strategy.long, 1, limit=1)
strategy.entry("long2", strategy.long, 1)
strategy.exit("exit1", "long1", profit=50) // 由于long1入场订单没有成交,因此ID为exit1的出场订单也处于暂待状态,直到对应的入场订单成交才会放置exit1
//strategy.exit("exit2", "long2", qty=1, profit=20) // 指定参数qty,当盈利20的时候,平掉ID为long2的持仓
strategy.exit("exit2", "long2", qty=1), profit=20, loss=20) // 指定参数qty,当盈利20或者亏损20的时候,平掉ID为long2的持仓
strategy.exit("exit2", "long2", qty=1) // 所有参数 'profit', 'limit', 'loss', 'stop', 'trail_points', 'trail_offset' 皆为“NaN”,则命令将失败。
使用实时价模型回测测试,这个测试策略开始执行了2个入场操作(strategy.entry函数),“long1”故意设置了limit参数,挂单价格为1使其无法成交。然后测试条件出场函数strategy.exit。使用了按点数止盈、按价格止盈。价格一跳乘以10作为止盈价差,价格一跳即内置变量syminfo.mintick。例如玻璃和纯碱的价格一跳是20元,而螺纹钢和甲醇等价格一跳是10元。
当然还有strategy.closetrades查询已平仓交易的一些信息,大家也可以尝试下。
strategy.cancel函数用来取消/停用所有预挂单的命令。这些函数strategy.order, strategy.entry , strategy.exit可以产生入场ID。该函数主要参数为:id、when。
参数:
strategy("strategy.cancel Demo",)
strategy.entry("long1", strategy.long, 0.1, limit=1)
strategy.cancel("long1")
strategy.cancel_all函数和strategy.cancel函数类似。取消/停用所有预挂单命令。可以指定when参数。
参数:
strategy("strategy.cancel Demo", pyramiding=3)
strategy.entry("long1", strategy.long, 0.1, limit=1)
strategy.entry("long2", strategy.long, 0.2, limit=2)
strategy.entry("long3", strategy.long, 0.3, limit=3)
strategy.cancel_all()
strategy.order函数的功能、参数设置等几乎与strategy.entry一致,区别为strategy.order函数不受strategy函数的pyramiding参数设置影响,没有下单次数限制。
参数:
strategy(title = "simple strategy order example")
strategy.order("buy", strategy.long, 1, when = open > high[1]) // buy by market if current open great then previous high
strategy.order("sell", strategy.short, 1, when = open < low[1]) // sell by market if current open less then previous low
交易是一门高深的学问,需要考验你的认知,耐心,毅力和决心。你需要根据你的交易理念和策略,选择做日内短线交易或者长期趋势交易,,因此反应在代码里就是你的交易函数的选择和交易参数的使用。本章内容一开始听起来确实让人比较迷惑,因为内容很多,灵活运用比较困难。幸好我们具有发明者平台,免费的代码回测可以帮助你进行足够多次数的试错,从而了解到每个函数的用法,进而不断优化你的量化策略系统。我们下节课再见!