商品期货量化交易-TradingviewPine语言基础课程(十六):交易函数:strategy系列

Author: ianzeng123, Created: 2023-03-09 17:11:38, Updated:

大家好,今天我们来学习Pine语言中交易函数strategy系列。在学习完所有指标计算和信号判断语法结构后,我们对接真实的市场面对最后一道关卡:交易。期货交易之所以引人入胜,与其独有的T+0交易机制密切相关。一个点的波动就是盈利或者损失,成功的进行交易操作就可以将盈利立即收入囊中。所以怎样在合适的点位进行正确交易方向的操作,就需要strategy系列函数的应用。

开仓

在交易信号判断确定后,我们需要立即进行开仓操作,以免错过黄金交易时间。

strategy.entry

strategy.entry函数是我们写策略时比较重要的一个下单函数,该函数比较重要的几个参数为:id, direction, qty, when等。

参数:

  • id:可以理解为给某个交易头寸起个名字用于引用。可以引用这个id撤销、修改订单、平仓。
  • direction:如果下单方向是做多(买入)该参数就传strategy.long这个内置变量,如果要做空(卖出)就传strategy.short这个变量。
  • qty:指定下单的量,如果不传这个参数使用的就是默认下单量。
  • when:执行条件,可以指定这个参数来控制当前这个下单操作是否触发。
  • pyramiding: 同一个方向交易交易的次数。
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

strategy.close函数用于平仓指定标识ID的入场持仓仓位。主要参数有:id,when,qty。

参数:

  • id:需要平仓的入场ID,就是我们使用strategy.entry等入场下单函数开仓时指定的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被调用时会平掉当前方向上的所有持仓。strategy.close_all函数的主要参数为:when。

参数:

  • 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.exit函数被用于入场持仓的平仓操作,与该函数不同的是strategy.close和strategy.close_all函数是以当前市场价格立即平仓。strategy.exit函数会根据参数设置进行计划平仓。

参数:

  • id:当前这个平仓条件单的订单标识符ID。
  • from_entry:用于指定要进行平仓操作的入场ID。
  • qty:平仓数量。
  • qty_percent:平仓百分比,范围:0 ~ 100。
  • profit:利润目标,以点数表示。
  • loss:止损目标,以点数表示。
  • limit:利润目标,以价格指定。
  • stop:止损目标,以价格指定。
  • when:执行条件。 使用一个测试策略来理解各个参数使用。
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.closedtrades.entry_bar_index:已平仓进场bar_index
  • strategy.closedtrades.exit_price:已平仓出场价格
  • strategy.closedtrades.exit_bar_index:已平仓出场bar_index
  • strategy.closedtrades.entry_id:已平仓进场id
  • strategy.closedtrades.entry_price:已平仓入场价格
  • strategy.closedtrades.entry_time:已平仓入场时间
  • strategy.closedtrades.profit:已平仓利润
  • strategy.closedtrades.size:已平仓数量
  • strategy.closedtrades.exit_time:已平仓出场时间

strategy.cancel

strategy.cancel函数用来取消/停用所有预挂单的命令。这些函数strategy.order, strategy.entry , strategy.exit可以产生入场ID。该函数主要参数为:id、when。

参数:

  • id:所要取消的入场ID。
  • when:执行条件。 这个函数很好理解,就是用来取消没有成交的入场命令的。
strategy("strategy.cancel Demo",)

strategy.entry("long1", strategy.long, 0.1, limit=1)

strategy.cancel("long1")

strategy.cancel_all

strategy.cancel_all函数和strategy.cancel函数类似。取消/停用所有预挂单命令。可以指定when参数。

参数:

  • 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.order函数的功能、参数设置等几乎与strategy.entry一致,区别为strategy.order函数不受strategy函数的pyramiding参数设置影响,没有下单次数限制。

参数:

  • id:可以理解为给某个交易头寸起个名字用于引用。可以引用这个id撤销、修改订单、平仓。
  • direction:下单方向
  • qty:指定下单的量,如果不传这个参数使用的就是默认下单量。
  • when:执行条件,可以指定这个参数来控制当前这个下单操作是否触发。
  • limit:指定订单限价价格。
  • stop:止损价格。 我们就使用strategy.order没有下单次数限制这个特性,构造一个脚本帮助我们理解:
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

交易是一门高深的学问,需要考验你的认知,耐心,毅力和决心。你需要根据你的交易理念和策略,选择做日内短线交易或者长期趋势交易,,因此反应在代码里就是你的交易函数的选择和交易参数的使用。本章内容一开始听起来确实让人比较迷惑,因为内容很多,灵活运用比较困难。幸好我们具有发明者平台,免费的代码回测可以帮助你进行足够多次数的试错,从而了解到每个函数的用法,进而不断优化你的量化策略系统。我们下节课再见!


更多内容