LOADING...
LOADING...
LOADING...
当前位置: 玩币族首页 > 行情分析 > Pine语言入门(十二)如何定义策略回测的时间范围

Pine语言入门(十二)如何定义策略回测的时间范围

2020-11-16 金金 来源:区块链网络

默认情况下,TradingView策略会回测图表上所有可用的价格柱。在大多数时候都可以。但是,如果我们想在特定时间段内测试我们的交易想法怎么办?让我们看看我们如何做到这一点。

本文主要内容:

概述:两个日期之间进行回测的步骤
步骤1.使用输入设置回测日期范围(可选)
步骤2.查看栏的时间是否在范围内
步骤3.在日期范围内提交条的入场订单
步骤4.当日期范围结束时,平仓未平仓交易
策略示例:仅在两个日期之间进行交易

当我们向K线图表添加一个TradingView策略时,它将自动处理整个K线历史上所有可用的价格柱。但如果我们希望回测特定时间段,或着只对之前一年的时间进行回测,就可以用两个代码来限制策略的回测范围。

首先是time,该变量返回价格柱的开盘时间。另一个是timestamp(),该函数需要一个日期和时间,然后返回该特定时刻的时间值。

两者time和timestamp()以相同的方式测量时间(使用UNIX时间值)。这样就可以将一个值与另一个值进行比较。因此,我们可以查看条形图的时间time是否落在回测timestamp()定义的日期范围内。

Unix时间(也称为epoch time和POSIX time)是一种系统,它根据1970年1月1日星期四00:00 UTC以来经过的秒数来描述一个时间点。这意味着Unix时间戳是某个日期和时间与1970年1月1日之间的秒数差。

这意味着time和timestamp()都是基于这个Unix时间点来测量时间的,前者代表当下时间离Unix时间点经过了多少毫秒,后者代表函数里自变量确定的特定时间点离Unix时间点经过了多少毫秒,所以本质上,time和timestamp()都是时间长度,因为基点一样,可以直接比较大小。

概述:在两个日期之间进行回测的步骤

先梳理总体逻辑和步骤,为了使TradingView策略仅在两个日期之间进行交易,我们要做的是:

1、使用输入选项设置日期范围。
2、查看栏的时间是否在日期范围内。
3、仅在时间位于该范围内时才提交策略的入场订单。
4、当日期范围结束时,关闭平仓交易。

具体步骤

步骤1.使用输入设置回测日期范围

配置策略的回测范围的一种简单方法是使用输入函数实现输入选项。这样,我们不必更改策略代码即可更改该时间段。

为了有更大的灵活性,我们设置输入开始日期和结束日期的日期,月份和年份:

// Make input options that configure backtest date range
startDate = input(title=”Start Date”, type=input.integer,
defval=1, minval=1, maxval=31)
startMonth = input(title=”Start Month”, type=input.integer,
defval=1, minval=1, maxval=12)
startYear = input(title=”Start Year”, type=input.integer,
defval=2018, minval=1800, maxval=2100)

endDate = input(title=”End Date”, type=input.integer,
defval=1, minval=1, maxval=31)
endMonth = input(title=”End Month”, type=input.integer,
defval=7, minval=1, maxval=12)
endYear = input(title=”End Year”, type=input.integer,
defval=2019, minval=1800, maxval=2100)

为了进行输入,调用input()函数,使用整数输入选项(type=input.integer)。

前三个输入定义开始日期:

“开始日期”选项定义了回测应该开始的月份。该默认值是1,因此是每月的第一天。
“开始月份”指定一年中的月份。它的默认值为1(即一月)。
“开始年份”定义了该策略应该在哪一年开始交易。此输入的默认值为2018。

最后三个输入定义回测的结束日期:

“结束日期”表示该策略应在每月的哪一天停止。其默认值为1。
“结束月份”是一年中月份的选项。默认设置为7,该策略将在7月停止。
而“结束年度”表示该策略应该在哪一年退出交易。其默认值为2019。
每个输入使用的minval和maxval参数input()。这些指定输入值的可接受范围。这样可以防止用户出错,并确保我们的代码使用正确的值。

我们存储我们的输入值到startDate,startMonth,startYear,endDate,endMonth,和endYear变量中用于之后的脚本编写。

步骤2.查看价格柱的时间是否在范围内

因此,现在我们定义了回测应该何时开始和结束。接下来,我们必须查看当前价格柱是否在该范围内。脚本如下:

// Look if the close time of the current bar
// falls inside the date range
inDateRange = (time >= timestamp(syminfo.timezone, startYear,
startMonth, startDate, 0, 0)) and
(time < timestamp(syminfo.timezone, endYear, endMonth, endDate, 0, 0))

在此创建的变量inDateRange通过两次比较获得其true / false值。这里用了and运算符,因此,两个条件全为真,inDateRange才为真。(如果一个或两个都是false,则变量也是false。)

第一个比较是看价格柱的开盘时间(time)是否大于或等于(>=)函数返回的某个值timestamp()。使用该函数,我们可以确定回测的开始日期的时间值。

因此,设置起始时间,即startYear,startMonth以及startDate输入变量,以及0和0。(第一个零代表小时,第二个零代表分钟。)如果输入使用其默认值,则将获取我们2019年1月1日00:00(午夜)的时间戳。

如果当前时间超过该时间,则不进行回测。

进行比较后,可以看到价格柱的时间(time)是否小于(<)生成的函数timestamp()回测的结束日期。这里我们调用函数与endYear,endMonth和endDate输入变量(以及0和0),其默认值为2020年11月15日00:00。

因此可以得出结论:如果当前柱线落在回测的日期范围内,则inDateRange变量为true(false否则)。

步骤3.在日期范围内提交酒吧的入场订单

上一步为我们提供了一个变量,该变量指示当前条形是否落在回测窗口内。现在,我们将该信息与策略如何生成订单一起使用。

这可能是这样的:

// Submit entry orders, but only when bar is inside date range
if (inDateRange and enterLong)
strategy.entry(id=”EL”, long=true)

if (inDateRange and enterShort)
strategy.entry(id=”ES”, long=false)

第一个if语句检查两个表达式。首先是inDateRange。那是之前的变量。true当当前柱线落入我们的日期范围内时,它将保留。enterLong是另一个变量。这只是策略实际购买条件的占位符。当两者均为时true,该strategy.entry()函数将打开多头交易(long=true)。

第二个if语句类似。这一个需要inDateRange和替代enterShort变量为true。在这种情况下,我们strategy.entry()开设了一个空头交易(long=false)。仅当当前柱位于回测窗口内时,才打开短裤。

第三步的策略代码可能看起来完全不同。那没问题。只要让您的代码inDateRange在打开交易时检查变量即可。这样,这些订单只会在策略的日期范围内发送。

由于TradingView具有两个生成挂单的功能,因此请在您的策略中查找该strategy.entry()功能和该strategy.order()功能。然后扩展其订购条件以包含inDateRange变量。

步骤4.当日期范围结束时,平仓未平仓交易

现在,我们的代码仅在日期范围内开仓交易,我们还必须实现相反的操作:在该范围外平仓交易。当回测的日期范围结束时,该策略将保持不变。

这是一种方法:

// Exit open market position when date range ends
if (not inDateRange)
strategy.close_all()

该if语句使用not运算符查看inDateRangeis是否false。当具有该值时,该strategy.clos_all()功能通过市场订单关闭策略的整个市场头寸。(当该策略没有公开交易时,则strategy.close_all()什么都不做。)

#示例策略:仅在两个日期之间进行交易
我们上面讨论的步骤包含在下面的示例策略中。脚本的输入选项配置了从2019年1月1日到2020年11月15日的回测期。在此期间,该策略交易20条指数移动平均线。

就是说,当柱线收高并超过移动平均线时,我们做多。每当柱线收低并跌破均线时,我们便开始做空交易。通过这些交易,我们还会逆转未平仓头寸(如果有)。

该策略的整个代码是:

//@version=4
strategy(title=”Only trade between two dates”, overlay=true)

// **** 1:
// Make input options that configure backtest date range
startDate = input(title=”Start Date”, type=input.integer,
defval=1, minval=1, maxval=31)
startMonth = input(title=”Start Month”, type=input.integer,
defval=1, minval=1, maxval=12)
startYear = input(title=”Start Year”, type=input.integer,
defval=2018, minval=1800, maxval=2100)

endDate = input(title=”End Date”, type=input.integer,
defval=15, minval=1, maxval=31)
endMonth = input(title=”End Month”, type=input.integer,
defval=11, minval=1, maxval=12)
endYear = input(title=”End Year”, type=input.integer,
defval=2020, minval=1800, maxval=2100)

// **** 2:
// Look if the close time of the current bar
// falls inside the date range
inDateRange = (time >= timestamp(syminfo.timezone, startYear,
startMonth, startDate, 0, 0)) and
(time < timestamp(syminfo.timezone, endYear, endMonth, endDate, 0, 0))

// Calculate strategy values
emaValue = ema(close, 20)

plot(series=emaValue, color=color.teal, linewidth=2)

// Set trade entry conditions
enterLong = (close > close[1]) and crossover(close, emaValue)
enterShort = (close < close[1]) and crossunder(close, emaValue)

// **** 3:
// Submit entry orders, but only when bar is inside date range
if (inDateRange and enterLong)
strategy.entry(id=”EL”, long=true)

if (inDateRange and enterShort)
strategy.entry(id=”ES”, long=false)

// **** 4:
// Exit open market position when date range ends
if (not inDateRange)
strategy.close_all()

回测如下图所示,之后,该策略不再进行交易。

本文内容相对比较简单,有兴趣的可以复制脚本进行试验。

有想制定自己的指标和交易策略的伙伴,欢迎大家添加微信jinvlog交流。

注册Tradingview平台,点击Tradingview。

—-

编译者/作者:金金

玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。

LOADING...
LOADING...