默认情况下,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。
—-
编译者/作者:金金
玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。
|