In this article we repeat some of the most important points when configuring a TradingView strategy programmatically. Follow the links to the full articles for more information.
In this article:
- Configuring the settings of a strategy programmatically
title: setting a strategy’s name
overlay: display a strategy on the price chart or not
precision: setting the number of displayed decimals
scale: specifying the price scale
initial_capital: setting the strategy’s starting funds
currency: setting the strategy’s base currency
pyramiding: limit the number of entries in the same direction
default_qty_value: specifying the default order size
max_bars_back: setting the number of historical bars referenced
backtest_fill_limits_assumption: specifying how strict backtested limit orders fill
calc_on_order_fills: performing an intra-bar calculation after an order fills
calc_on_every_tick: calculating a strategy with every real-time price update
Configuring the settings of a TradingView strategy programmatically
After the chapter’s introduction we discussed configuring a TradingView strategy with code. This is done with
strategy(), a function that needs to be added to every TradingView strategy (Pine Script Language Tutorial, n.d.). And this function’s
title argument, which specifies the strategy’s name, always needs to be set too (TradingView, n.d.).
Configuring the strategy’s options by hand is possible too. Because the manual options override the settings specified with
strategy(), multiple instances of the same strategy can be configured differently. Furthermore, the manual options make it possible to quickly change a setting without having to edit the script’s code. However, configuring a strategy’s settings programmatically has benefits too: it saves time otherwise spend configuring the strategy, prevents forgetting to configure something, and makes sharing the script with the right settings easier.
strategy(title, shorttitle, overlay, precision, scale, max_bars_back, pyramiding, calc_on_order_fills, calc_on_every_tick, backtest_fill_limits_assumption, default_qty_type, default_qty_value, initial_capital, currency)
These arguments mean the following (Pine Script Language Tutorial, n.d.; TradingView, n.d.):
title: required string argument that sets the name of the trading strategy. This name is used in several TradingView windows, and can be different from the filename that the script is saved under in the Pine Editor. For more on
title, see setting the name of a TradingView strategy.
shorttitle: optional string argument that also names the strategy. This argument overrides the value set by
titleand, as we discuss in naming a TradingView strategy, doesn’t provide capabilities beyond what
overlay: optional true/false argument that, when set to
true, displays the strategy in the chart area of the chart’s instrument. With
overlay=falsethe strategy instead appears in a separate chart panel below the chart’s instrument. For more, see overlaying a strategy on the chart’s instrument.
precision: optional integer argument that specifies how many digits to show after the decimal point of the plotted strategy values. This argument defaults to 4 and has a minimum of 0. With that latter large numbers are formatted with the ‘K’ (for thousands) and ’M’ (for millions) suffixes. See setting the displayed precision of a trading strategy for more.
scale: optional argument that defines which price scale the strategy attaches to. Possible values are
scale.right(the default value when we don’t set the
scale.none. With that latter the strategy uses the full chart area when plotting, and this requires that the
overlayargument is set to
true. For more on the
scaleargument, see configuring the scale of a TradingView strategy programmatically.
pyramiding: optional integer argument that specifies how many entries are allowed in the same direction. This argument defaults to 0, and with that value only one long or short entry order can be filled while additional entries will be rejected. We take a closer look at this argument in setting pyramiding settings programmatically in TradingView.
calc_on_order_fills: optional Boolean argument that, when set to
true, makes the strategy perform an additional intra-bar order calculation immediately after an order fills. That extra calculation happens on both historical and real-time price bars. When omitted,
falseand the strategy then calculates on the close of each bar. See calculating a TradingView strategy immediately after an order fills for more.
calc_on_every_tick: optional true/false value that, when set to
true, makes the strategy calculate with every real-time tick rather than only on bar close. On historical bars the strategy keeps calculating at the close of each price bar. The default value of
false. We examine this argument closely in calculating a TradingView strategy with every real-time price update.
max_bars_back: optional integer argument that specifies the maximum number of historical bars that the strategy references to perform its calculations. That number of bars is automatically calculated by TradingView, but can be changed with this argument. For more on
max_bars_backsee setting the number of historical bars a strategy uses programmatically.
backtest_fill_limits_assumption: optional integer argument that configures how strict TradingView deals with limit orders when backtesting. Before a limit order fills, the bar’s price has to exceed the limit order price with the number of ticks set by
backtest_fill_limits_assumption. We take a closer look at this argument in specifying TradingView’s backtest assumptions of limit orders.
default_qty_type: optional argument that specifies the default order size (that is, the order size used when we submit an order without specifying its quantity). This argument can be set to three values:
strategy.fixed(order sizing with a fixed quantity; the default setting),
strategy.cash(sizing orders based on a cash amount), and
strategy.percent_of_equity(sizing orders based on an equity percentage).
default_qty_value: optional float argument that specifies the quantity of the default order size. Whereas the
default_qty_typeargument specifies how the default order size is calculated,
default_qty_valuesets the standard order size. And so
default_qty_valuespecifies the number of contracts or shares, the cash amount of each order, or the equity percentage to invest with each order depending on the
initial_capital: optional argument that sets the strategy’s starting funds, and this value defaults to 100,000. See setting a strategy’s initial capital programmatically for more.
currency: optional argument that specifies the account currency. Whenever the strategy’s currency differs from the currency used by the chart’s instrument, TradingView performs currency conversion of things like the strategy’s net profit and equity. This argument defaults to
currency.NONE, and with that no currency conversion takes place. Other values for
currency.HKD(Hong Kong dollar),
currency.NZD(New Zealand dollar),
currency.USD(US dollar), and
currency.ZAR(South African rand). See setting the currency of a TradingView strategy programmatically for more.
Let’s take a closer look at these different arguments of the
title: setting a TradingView strategy’s name with code
title argument of the
strategy() function specifies the strategy’s name (TradingView, n.d.). This argument always needs to be set and we use it like this:
strategy(title="Moving average crossover")
title accepts a literal string (like we see here); it doesn’t accept a built-in or user-defined string variable nor does it accept a concatenated TradingView string. Furthermore, we also cannot set the strategy’s name manually. That means the
title argument is the only way to set a strategy’s name.
The name that we give a strategy with
title appears in the chart’s legend:
And displays in the ‘Data Window’:
And appears in the ‘Strategy Tester’ window too:
shorttitle argument sets the strategy’s abbreviated name (TradingView, n.d.). However, this latter argument does the same thing
title does. And since
title is required whereas
shorttitle is not (TradingView, n.d.), it’s more convenient to just use
title for naming our strategy.
A thing to keep in mind is that
title doesn’t specify how the strategy is named in the list of indicators and strategies. Instead, the script’s filename is used in that window.
We set that filename in the Pine Editor, the window where we edit the script’s code:
title sets the strategy’s name we see 95% of the time, but when we want to add the strategy to the chart then we need to look for its filename (and not the strategy name displayed on the chart, which
title sets). To prevent confusion and not being able to find the strategy, set the strategy’s filename to something that closely resembles its displayed name on the chart.
overlay: showing a strategy on the instrument’s price bars or not
When the optional
overlay argument of the
strategy() function is set to
true, the strategy displays on the chart’s instrument. With
overlay=false or not set, the strategy displays in a separate chart panel below the instrument (TradingView, n.d.).
overlay like so:
strategy(title="My example strategy", overlay=true)
overlay argument only accepts literal true/false values; we cannot set it to a built-in or user-defined variable, nor can
overlay work with a Boolean true/false input option.
The visual difference between
overlay set to
A couple of insights when working with this argument are:
- When the strategy is added to the chart before we set or change the
overlayargument, the strategy needs to be removed from the chart and re-added to see the effect of the updated code.
- We cannot specify in which subchart the strategy displays – with
overlay=falsethe strategy simply appears in a new chart panel below the instrument’s price chart.
- Each strategy can be overlaid on the chart’s instrument, even when its values are much higher or lower than the instrument’s prices. In that case, we’ll need to adjust the strategy’s scaling to prevent skewing the instrument’s price axis.
- A strategy’s trades always appear in the chart area of the instrument, even when the strategy itself plots in a subchart.
- Most TradingView functions follow the
overlayargument setting, but some (like
barcolor()that colours the instrument’s price bars) always work in the instrument’s chart area regardless of the
precision: setting the number of displayed decimals programmatically
precision argument of the
strategy() function specifies the number of digits after the floating point of the strategy’s values (TradingView, n.d.). We use
precision as follows:
strategy(name="My example strategy", precision=3)
precision argument can only be set to a literal integer that has a value of 0 or greater; it doesn’t accept a variable nor does it work with a numerical input option.
The default value of this argument is 4, and when we set it to 0 large values display with special formatting (TradingView, n.d.). That is, thousands show with the ‘K’ and millions with the ’M’ suffix. With that large strategy values don’t take up a lot of screen space.
precision=3, a strategy displays like this:
The value of the
precision argument also affect how the values appear in the ‘Data Window’:
Noteworthy features of
precisiononly affects how the strategy’s plotted values display; it doesn’t affect the script’s calculations nor does it influence at which price orders are submitted.
- All values that the strategy plots are affected by
precision. It’s not possible to, for example, have one plot display with 2 decimals while another uses 4 digits after the floating point.
- A strategy that’s overlaid on the price chart uses the same precision as the chart’s instrument. In that case, TradingView doesn’t respect our
precisionsetting. We take a closer look at this and the workarounds in a TradingView strategy that displays with a different precision than configured.
scale: setting a TradingView strategy’s price scale with code
scale argument of the
strategy() function sets which price scale the strategy’s plotted values attach to (TradingView, n.d.). When we don’t specify this argument, the strategy uses the chart’s right price scale.
scale argument is useful when a strategy plots values much higher or lower than the chart’s prices. By attaching the strategy to a different price scale than the instrument uses, we prevent the strategy’s values from distorting the instrument’s price scale.
scale like this:
strategy(title="My example strategy", scale=scale.left)
The different values that the
scale argument can be set to are (TradingView, n.d.):
|Attaches the strategy to the chart’s right price scale. This is the standard option when we don’t set |
|Attaches the strategy to the left price scale. This value is typically used to prevent skewing the right price axis when more than one script plots in the same window or when we overlay the strategy on the chart’s instrument.|
|Doesn’t attach the strategy to any price scale. This way the plotted values cannot be read from a price scale, but it does allow the strategy to use the full chart area when plotting – and sometimes even plots beyond the chart’s margins. This scaling option requires that the strategy displays on the chart’s instrument.|
For a visual idea of the different scaling options, on the following chart the Bollinger Bands use the right price scale:
When we change the script’s scaling to the left axis (
scale=scale.left), the chart looks as follows:
Now the Bollinger Bands display as a horizontal line. This happens because the left scale, which is already used by the volume indicator, has a strongly different range of values.
When we plot the script with
scale.none, it doesn’t attach to any price scale but uses the full chart area instead:
The Bollinger Bands look the same here as when they were attached to the right price scale. However, the Euro Bund price action is better visible now since the right price scale doesn’t need to accommodate the Bollinger Band values anymore.
Features of the
scale argument include:
- When we change the value of the
scaleargument or add it to the
strategy()function, we need to remove the strategy from the chart and re-add it before the effect of the updated code is visible.
scaledoesn’t influence the strategy’s calculations and only has a visual effect, just like when we overlay the strategy on the instrument or change the strategy’s precision.
initial_capital: setting the strategy’s starting funds programmatically
initial_capital argument of the
strategy() function sets the strategy’s initial capital (TradingView, n.d.). This argument’s default value is 100,000 and to start the strategy with initial funds of 25k we use it like:
strategy(title="Example - initial_capital", initial_capital=25000)
We can set
initial_capital only to a literal integer; it doesn’t accept a variable nor works with a numerical input option.
initial_capital specifies the strategy’s starting funds, it also influences the default order size when sizing orders based on an equity percentage. The initial capital setting is also reflected in built-in variables like
strategy.equity (which returns the sum of initial capital, net profit, and open profit) and
strategy.initial_capital that returns the strategy’s initial capital (TradingView, n.d.). A strategy’s initial capital and currency setting together affect its equity, as we discussed in initial capital, currency conversion, and a strategy’s equity.
currency: setting a TradingView strategy’s currency with code
currency argument of the
strategy() function configures the strategy’s currency setting (TradingView, n.d.). This way a strategy can calculate with a different currency than used by the instrument it trades (Pine Script Language Tutorial, n.d.). A consequence is that the strategy’s profit, equity, initial capital, drawdowns, and other performance metrics are reported in the strategy’s currency (and not in the currency of the traded instrument).
To have our strategy behave like it’s trading a Japanese Yen broker account, we use
strategy(title="Example - strategy currency", currency=currency.JPY)
The values that we can set the
currency argument to are (TradingView, n.d.):
|Currency used by the strategy|
|Hong Kong dollar|
|Unspecified currency. With this setting, the strategy always uses the same currency as the instrument it trades and no currency conversion happens.|
|New Zealand dollar|
|United States dollar|
|South African rand|
There are three different situations in TradingView when it comes to currency conversion:
- When we don’t set the
currencyargument, it defaults to
currency.NONEand then no current conversion takes place. Instead, the strategy implicitly uses (and reports in) the same currency as the instrument it trades.
currencyset to the same currency as the instrument uses, then currency conversion also doesn’t happen.
currencyis set to a different currency than used by the instrument, then currency conversion does happen. Since the strategy then reports its results in the currency we specified, we get a more accurate estimate of how the strategy would perform in the currency of our trading capital.
Besides influencing the values in the strategy’s performance report, the
currency argument affects other features too:
- The initial capital is denominated in the strategy’s currency, and so our buying power differs depending on the currency of the instrument we’re trading. We discussed this in initial capital and currency conversion.
- When we size orders with an amount of cash, TradingView converts that cash amount to the currency of the instrument that we’re trading. And with that,
currencyaffects the order size. We examined this more closely in sizing orders with a cash amount that’s converted to another currency.
- Because a strategy’s equity (that is, initial capital + net profit + open profit; TradingView, n.d.) is influenced by
currency, a strategy’s currency setting also affects order sizing based on a currency-converted equity.
pyramiding: limiting a TradingView strategy’s entries in the same direction
pyramiding argument of the
strategy() function specifies how many entries in the same direction are allowed (TradingView, n.d.). This argument’s default value is 0, and with that only one entry order in the same direction is possible while the strategy will reject additional entries (TradingView, n.d.).
To allow multiple entries in the same direction, we can use
pyramiding like this:
strategy(title="My example strategy", pyramiding=4)
pyramiding argument can only be set to a literal integer (like we do above); it doesn’t accept a variable nor a numerical input option.
Noteworthy features of
pyramidingspecifies the number of entries in the same direction, but doesn’t set the total position size. This latter consists out of the sum of each individual order’s size. We can set a strategy’s default order size to a fixed quantity, a cash amount, or an equity percentage.
- TradingView evaluates an order’s conditions when it generates, not when the order executes (Pine Script Language Tutorial, n.d.). This has an important consequence for the strategy’s pyramiding setting. When we generate several orders at the same time (or quickly after each other), then all of them are approved when the strategy’s current position hasn’t reached the pyramiding limit yet. But when all of those orders execute, we can easily end up with a position that’s bigger than allowed by
pyramiding. For an analysis and possible workarounds, see the impact of multiple entry orders on a strategy’s pyramiding setting.
- A strategy that doesn’t respect its pyramiding setting can also be caused by how we submit entry orders. While the
strategy.entry()function respects the pyramiding option, the
strategy.order()function submits orders without checking the strategy’s pyramiding setting (Pine Script Language Tutorial, n.d.; TradingView, n.d.). See the impact of
strategy.order()on a strategy’s pyramiding setting for more (including a workaround).
default_qty_value: setting default order size
Configuring the default order size with the
strategy() function is possible too. This order size is used by the strategy when we don’t set the
qty argument of the
strategy.order() functions when submitting an order.
The default order size is set with the
default_qty_value arguments of
strategy(), and these can be combined in three ways (TradingView, n.d.):
strategy.fixedor not set at all,
default_qty_valuespecifies the number of contracts to trade with each order. This gives a default order size set to a fixed amount.
default_qty_valuespecifies how much of the strategy’s cash to invest in each order. This creates a default order size based on a fixed amount of cash.
- And with
default_qty_valuespecifies the percentage of the strategy’s equity to invest with each order. This sets the default order size to a percentage of trading equity.
So to have a strategy trade with a default order size of 10 contracts, we use
strategy(title="Example - fixed number of contracts", default_qty_type=strategy.fixed, default_qty_value=10)
And sizing orders based on 2,000 cash is done like:
strategy(title="Example - fixed cash amount", default_qty_type=strategy.cash, default_qty_value=2000)
Noteworthy features of he
default_qty_value arguments are:
- When we size orders based on a cash amount (
default_qty_type=strategy.cash) and set the strategy’s currency setting, then that cash amount is converted into the currency of the instrument we’re trading. We discussed this in order sizing with a fixed cash amount that’s currency converted.
- Likewise, the currency setting also affects the default order size when we base those orders on an equity percentage (
default_qty_type=strategy.percent_of_equity), provided that the instrument trades in a different currency than used by the instrument (otherwise no currency conversion happens). We explored this in order sizing with an equity percentage and currency conversion.
- The default order size that we define when using the
strategy.cashoption is independent from the strategy’s equity. And so when a strategy has an equity of 10,000 it can still submit orders with a cash size of 20,000. This means sizing orders based on a fixed cash amount isn’t related to the strategy’s equity whereas sizing orders based on an equity percentage is.
max_bars_back: the number of bars a strategy calculates on
max_bars_back argument of the
strategy() function sets the number of historical bars the strategy references in its calculations (TradingView, n.d.). By default, TradingView automatically calculates how many price bars a strategy needs for its calculations (TradingView, n.d.). But in rare circumstances, the code is so complex that TradingView cannot correctly estimate that required amount of price bars.
When TradingView cannot determine the bar amount programmatically, the script generates the ‘out of depth at index’ error message. We fix that error message by setting
max_bars_back to the number of bars that we think the strategy should use for its calculations.
max_bars_back goes like:
strategy(title="My example strategy", max_bars_back=50)
max_bars_back argument needs to be set to a literal integer; it doesn’t accept numerical variables nor numerical input options.
A visual explanation of the
max_bars_back argument is the following:
Here the strategy plots the highest high and lowest low of the last 20 bars. Because these extreme prices need at least 20 price bars (including the current bar) to calculate successfully, we see the script ‘waiting’ until there are enough price bars on the chart.
Having to set the
max_bars_back argument ourselves is quite rare; currently, there are only two functions that can require that
max_bars_back is set:
pivotlow() (TradingView, n.d.). It’s also possible that in other cases we set the
max_bars_back argument, but that only happens when the code logic is so complex that TradingView cannot ‘read’ from the code how many historical bars the script’s calculations use.
And even then we only need to set the
max_bars_back argument when TradingView generates the ‘out of depth’ at index error message. The exact value that we set to this argument depends on how many bars the strategy references in its calculations, and that differs with every script.
As a rule of thumb, an approximate
max_bars_back value for short-term strategies is 50. A value of 100 is more suitable for medium-term strategies, whereas a long-term strategy can require 200 bars back or more. Note that if we do set
max_bars_back but give it a too low value, then TradingView still attempts to calculate this value automatically (TradingView, n.d.). In that case the script can still trigger an error even though we’ve set
backtest_fill_limits_assumption: specifying how strict limit orders fill
backtest_fill_limits_assumption argument of the
strategy() function specifies how strict TradingView fills limit orders during backtesting. On historical bars, limit orders are only considered filled when the bar’s range exceeds the limit price by the number of ticks set by this argument (Pine Script Language Tutorial, n.d.; TradingView, n.d.).
backtest_fill_limits_assumption feature makes our backtesting more robust since in real-time trading, not all limit orders fill at their limit price or better (that is, higher for sell orders and lower for buy orders) depending on our position in the order queue and the volume traded at the limit price or better.
backtest_fill_limits_assumption like this:
strategy(title="Example - backtest_fill_limits_assumption", backtest_fill_limits_assumption=1)
backtest_fill_limits_assumption argument can only be set to literal integers; it doesn’t accept variables nor numerical input options. It has a default value of 0, and so without setting this argument, a strategy’s limit orders fill at their limit price during backtesting.
Noteworthy features of the
backtest_fill_limits_assumption argument are:
- The value set by
backtest_fill_limits_assumptiononly influences when TradingView considers our limit order filled during backtesting; it has no influence on the actual order fill price (Pine Script Language Tutorial, n.d.).
backtest_fill_limits_assumptiononly affects backtesting; when the strategy runs on real-time data, orders are triggered and filled with real-time prices (Pine Script Language Tutorial, n.d.).
- During backtesting, limit orders fill at their limit price – even though they might be triggered at a much higher or lower price due to
backtest_fill_limits_assumption. This can give the surprising situation that limit orders fill on price bars that did not reach the limit price (see example image below).
- When TradingView calculates a strategy on historical data, it assumes there are no price gaps inside a bar and that each price inside the bar’s range is traded with sufficient volume. This means that a limit order can fill at any price inside a bar (Pine Script Language Tutorial, n.d.).
To see how
backtest_fill_limits_assumption influences when a limit order fills, let’s examine the same order multiple times:
Here we used
backtest_fill_limits_assumption=1. This means that our sell limit order at 3012 is considered filled by TradingView when the range of the historical bar reaches 3013. We see that happening in the annotated bar, which has a range of 3008-3014.
Here we have the same order but this time
backtest_fill_limits_assumption is set to 4:
Now the same sell limit order of 3012 requires that the 3016 price is touched before this order is considered filled. That limit order price plus 4 ticks is now reached a bar later than in the previous chart.
A more extreme example is when we set
backtest_fill_limits_assumption to 12. The order then fills like this:
Here our sell limit order at 3012 only fills when the bar reaches 3024. Now it takes several more price bars before this order is fills during backtesting, and if it weren’t for the uptrend then the sell limit order wouldn’t been filled at all. Note that, when this order fills, it does so at the limit price of 3012 even though the bar on which it fills doesn’t even reach that price.
calc_on_order_fills: an intra-bar calculation when an order fills
calc_on_order_fills argument of the
strategy() function makes the strategy perform, when set to
true, an additional intra-bar calculation after an order fills (Pine Script Language Tutorial, n.d.; TradingView, n.d.). This argument’s default value is
false, and in that case the strategy doesn’t perform an extra intra-bar calculation after an order fills during backtesting or real-time trading (TradingView, n.d.).
calc_on_order_fills argument is used like this:
strategy(title="Example - calc_on_order_fills", calc_on_order_fills=true)
This argument can only be set to literal true/false values; it doesn’t accept variables nor can work with a true/false input option.
The default behaviour of TradingView strategies on real-time and historical data is to only calculate when the price bar closes (Pine Script Language Tutorial, n.d.). During that script calculation, the strategy can generate an order to submit at the open of the next bar and which can fill sometime during that price bar. But our script then also has to wait till that next bar closes before calculating again and performing additional actions based on whether the order filled or not. Depending on the chart’s time frame, there can be a long ‘waiting period’ between when an order fills and the bar closes.
Now with the
calc_on_order_fills argument set to
true, the strategy still calculates when the real-time and historical bars close (Pine Script Language Tutorial, n.d.). But the script then also calculates one additional time after an order fills during backtesting or real-time trading. This way our strategy can perform an extra action immediately after the order fills, like placing another order or updating the profit target based on the order fill price.
- The backtest results of a strategy that uses
calc_on_order_fills=truedo not indicate how the script would perform in real-time trading. The cause for this difference is that, during backtesting, at most 4 calculations happen per bar; but during real-time trading, there can be as many intra-bar calculations as there are real-time price updates (Pine Script Language Tutorial, n.d.). Depending on the strategy’s code, this can have a minor to big effect on its behaviour. For more, see inaccurate backtest results with
- We can quickly build up a position with
calc_on_order_fillssince each filled order triggers an intra-bar script calculation, which we can then use to submit yet another order. And when that order fills, the script performs yet another extra calculation. This does, however, require that the order’s entry or exit conditions are still valid when the strategy performs those extra intra-bar calculations. See why an order doesn’t fill during an intra-bar calculation for more.
calc_on_every_tick: calculating a strategy with every real-time price update
calc_on_every_tick argument of the
strategy() function makes the strategy process every real-time price update when set to
true (TradingView, n.d.). This argument defaults to
false, and in that case the script only calculates on the close of each price bar.
To calculate with every real-time tick, we set
calc_on_every_tick like this:
strategy(title="My example strategy", calc_on_every_tick=true)
calc_on_every_tick argument only accepts literal true/false values; it doesn’t work with variables nor with a true/false input option.
The advantage of processing every real-time tick is a greater speed. Let’s say we want to submit 5 entry orders, one with each script calculation. Since a strategy by default calculates on the close of each price bar (Pine Script Language Tutorial, n.d.), it takes 5 bars to submit those orders. But with
calc_on_every_tick=true, it can take 10 seconds (depending on how many real-time price updates there are for the traded instrument).
Depending on the price data that the strategy runs on,
calc_on_every_tick has a different influence on the strategy’s calculations (Pine Script Language Tutorial, n.d.; TradingView, n.d.):
- On historical data, the strategy calculates on the close of each price bar, regardless of whether
calc_on_every_tickis enabled or not.
- On real-time data, the strategy calculates with every price update (when
calc_on_every_tick=true) or only on bar close (when
calc_on_every_tick=falseor missing from the
This different behaviour on historical and real-time data has several consequences:
- The backtest results of a script that uses
calc_on_every_tick=truedo not indicate how the strategy performs during real-time trading. Due to the extra calculations on real-time data, it can seem were trading two different strategies when comparing backtest results with real-time performance. We examined this in inaccurate backtest results when backtesting
- Since a strategy with
calc_on_every_tick=truecan perform dozens to hundreds of calculations per bar, its speed is much higher than we’d normally see. This also means that a small error or misconfiguration becomes a problem quickly. For instance, the strategy’s pyramiding limit can easily be violated by submitting orders quickly after each other. Things like this make it even more important that
calc_on_every_tick=truestrategies are extensively tested on real-time data.
Besides calculating a strategy with every real-time tick (
calc_on_every_tick), a strategy can also calculate after an order fills (
calc_on_order_fills). The difference between these two related arguments is (Pine Script Language Tutorial, n.d.; TradingView, n.d.):
calc_on_every_tick=true, the strategy calculates on every real-time price update. This feature only affects the strategy’s behaviour on real-time data but doesn’t change its backtest performance.
calc_on_order_fills=true, the strategy performs an additional intra-bar calculation when an order fills. This extra calculation happens on real-time and historical price bars. But while on historical bars the strategy can calculate on the bar’s open, high, low, and close; on real-time data that extra intra-bar calculation can happen with every tick. This means there are a lot more calculation opportunities in real time than there are on historical bars.
This ends our overview of the different ways to programmatically configure a trading strategy in TradingView and the different caveats when doing so. See all TradingView programming articles to learn more about other topics.
- See the summary of configuring indicators programmatically for learning about the
study()function, and how we configure TradingView indicators with it.
Pine Script Language Tutorial (n.d.). Retrieved on February 24, 2016, from https://docs.google.com/document/d/1sCfC873xJEMV7MGzt1L70JTStTE9kcG2q-LDuWWkBeY/
TradingView (n.d.). Script Language Reference Manual. Retrieved on July 18, 2016, from https://www.tradingview.com/study-script-reference/