In this weeks post, we are going to take a look at working with ticks in Tradingview. In particular, we will focus on the loss
andprofit
parameters of strategy.exit()
. Since these parameters require us to work with ticks instead of monetary unit, some newer users may avoid using them. After all, what is a tick anyway?
Official Docs
Before we start, let’s take a look at the parameters in question. As always, it is good to have a look at the official documentation first. When reading through the snippet of parameters below, you will see there are 2 different ways to set a stop loss or take profit.
profit (float) An optional parameter. Profit target (specified in ticks). If it is specified, a limit order is placed to exit market position when the specified amount of profit (in ticks) is reached. The default value is ‘NaN’.limit (float) An optional parameter. Profit target (requires a specific price). If it is specified, a limit order is placed to exit market position at the specified price (or better). Priority of the parameter ‘limit’ is higher than priority of the parameter ‘profit’ (‘limit’ is used instead of ‘profit’, if its value is not ‘NaN’). The default value is ‘NaN’.loss (float) An optional parameter. Stop loss (specified in ticks). If it is specified, a stop order is placed to exit market position when the specified amount of loss (in ticks) is reached. The default value is ‘NaN’.stop (float) An optional parameter. Stop loss (requires a specific price). If it is specified, a stop order is placed to exit market position at the specified price (or worse). Priority of the parameter ‘stop’ is higher than priority of the parameter ‘loss’ (‘stop’ is used instead of ‘loss’, if its value is not ‘NaN’). The default value is ‘NaN’.
loss
and profit
expect you to provide the number of ticks away from the entry price that you would like to exit. On the other hand, stop
andlimit
are set using a price level. Of the two, it is generally easier to work with price levels as these are readily available to us through OHLC
data, indicators and simple calculations. Additionally, most users will be familiar with setting stops at price level when manually trading and filling out an order form through their broker. However, that does not mean tick based stop and limit orders should be cast out of our armoury.The Advantage to Working With Ticks
Working in ticks does have one key advantage. Ticks allow us to really fix our risk and reward ratios. Let’s imagine we want to set a stop and take profit with a risk-reward ratio of exactly 2:1, using the stop
parameter (i.e. price levels) we have a couple of options:
- Calculate it from the
close
value at the time we send our entry order. This is not perfect though because we do not enter at theclose
. We actually enter at theopen
of the following bar. If that following bar gaps up or down, then our stop and profit levels will be skewed. - We can wait until our entry order is filled before calculating it. However, this again is not ideal because the order would not be in the market until one bar later, leaving us unprotected for one bar.
By using ticks with the profit
parametersloss
, our stop and profit orders are immediately in the market and are measured from the entry price.
Minimum Ticks
Before we can use either parameter, we should take some time to understand what a tick is and the concept of a “minimum tick”. For those unfamiliar with the terms, a tick is the minimum value that the price can change/move up or down. So for example, if Barclays on the London Stock Exchange is quoted at 203.10 and has a minimum tick value of 0.05 pence, then the next closest prices which we could trade would be 203.15 or 203.05. Of course, we could blow past these values but we could never end up at 203.7 as it is not a multiple of 0.05.
As you might deduce, knowing the minimum tick level is useful for knowing where price could go next and for converting ticks back to a £ amount. 20 ticks with a min tick value of 0.5 pence is different to 20 ticks with a min tick of 0.2 (10 pence vs 4 pence).
So if the minimum tick value can vary so much, how can know what the tick value is? Fortunately, Tradingview has a built-in variable syminfo.mintick
that provides the minimum tick value of the instrument/asset you are trading.
Does a Minimum Tick Impact Stop and Limit Parameters?
Now we have a bit of background knowledge, it seems like a good time to take a little detour. If we know that an asset moves in fixed increments then do we need to be careful when setting stop
andlimit
price levels?
Continuing from the example above, Barclays was quoted at 203.10 pence. Now let’s imagine we are going long and want a 10% stop loss. Normally we would just calculate 203.1 * 0.9 = 182.79
and send a stop loss order at that level. Now you might rightly point out that 182.79 is not a multiple of 0.05 so let’s look at what happens if we do that…
Min Tick Test – Order Level
The following example must be run on BARC in order to replicate the results we see lower down. The code simply sends a stop order at the open on 3rd May 2018 (assuming you are using the daily timeframe) and sends it at a level that is not a multiple of the min tick.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
//@version=3 // This is an example showing what happens when you send a stop loss order at // a level not supported by the symbols minimum tick size. // it must be run on BARC (Barclays on the London Stock Exchange) using the daily // timeframe. strategy("Tick Test", overlay=true) // Inputs st_yr_inp = input(defval=2018, title='Backtest Start Year', type=integer) st_mn_inp = input(defval=05, title='Backtest Start Month', type=integer) st_dy_inp = input(defval=02, title='Backtest Start Day', type=integer) en_yr_inp = input(defval=2018, title='Backtest End Year', type=integer) en_mn_inp = input(defval=05, title='Backtest End Month', type=integer) en_dy_inp = input(defval=03, title='Backtest End Day', type=integer) // Timestamp start = timestamp(st_yr_inp, st_mn_inp, st_dy_inp,00,00) end = timestamp(en_yr_inp, en_mn_inp, en_dy_inp,00,00) can_trade = time >= start and time <= end if (can_trade) strategy.order("Stop Order", false, stop=205.49) |
Running the code we can see the actual fill level:
As you can see, we were filled at 205.45
. This makes sense as it is the first available price below the requested stop level. So in conclusion, you do not need to accurately calculate your stop/limit orders to the nearest tick level. However, you should be aware, that the price you get filled at could be a little further out than expected.
Ticks With Loss And Profit
Ok, now time to revert back to the loss
and profit
parameters. Let’s take a look at a simple use case for setting loss
in ticks and what that means in terms of price difference. Again, this should be run on BARC to replicate the result below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
//@version=3 // This is an example showing what happens when you send a stop loss order at // a level not supported by the symbols minimum tick size. // it must be run on BARC (Barclays on the London Stock Exchange) using the daily // timeframe. strategy("Tick Test 2", overlay=true) // Inputs st_yr_inp = input(defval=2018, title='Backtest Start Year', type=integer) st_mn_inp = input(defval=05, title='Backtest Start Month', type=integer) st_dy_inp = input(defval=02, title='Backtest Start Day', type=integer) en_yr_inp = input(defval=2018, title='Backtest End Year', type=integer) en_mn_inp = input(defval=05, title='Backtest End Month', type=integer) en_dy_inp = input(defval=03, title='Backtest End Day', type=integer) ticks = input(defval=20, title='Stop Loss in Ticks', type=integer) // Timestamp start = timestamp(st_yr_inp, st_mn_inp, st_dy_inp,00,00) end = timestamp(en_yr_inp, en_mn_inp, en_dy_inp,00,00) can_trade = time >= start and time <= end if (can_trade) strategy.entry("long", strategy.long) strategy.exit("Stop Order","long", loss=ticks) |
You may nite that the code above has been edited slightly. An extra ticks
input has been added and we also have a stratey.entry()
call to enter a position. We must enter a position first in order to use the strategy.exit()
function.
Using the default setting of 20 ticks we can see that it resulted in a 1 pence stop loss level. This is expected given that we know the minimum tick level is 0.05 pence.
What happens if you give a negative tick value?
It may seem logical to use a negative tick value for Long position stop losses and a positive tick value for Short positions. After all, for a long position, we want our stop to be below the entry price right? Well, Tradingview’s engine will do this conversion for you. As a result, you must use a positive tick value. Let’s take a look at what happens with a negative value:
We can use the same code as above but change the “Stoploss in Ticks” input value to -20
instead of 20
. As we can see when we run the script, the order is filled immediately.
FX Has No Minimum Tick
Some inquisitive readers who use plot(syminfo.mintick)
to see what the actual tick level is may notice that FX pairs tend to have a tick value of 0.
So what does that mean for us? Nothing really…. This is because FX pairs are quoted in pips/pipettes. As such, we do not need to specify a minimum tick. A pipette IS the minimum tick value. We can’t divide it any further and we do not move in multiples of pipettes. Therefore if you input a 20 tick stop loss on a non-japanese pair, your stop will be 2 pips. This can be seen with the following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
//@version=3 strategy("Tick Test FX", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100) // Inputs st_yr_inp = input(defval=2018, title='Backtest Start Year', type=integer) st_mn_inp = input(defval=05, title='Backtest Start Month', type=integer) st_dy_inp = input(defval=02, title='Backtest Start Day', type=integer) en_yr_inp = input(defval=2022, title='Backtest End Year', type=integer) en_mn_inp = input(defval=05, title='Backtest End Month', type=integer) en_dy_inp = input(defval=03, title='Backtest End Day', type=integer) loss_ticks = input(defval=20, title='Stop Loss in Ticks', type=integer) profit_ticks = input(defval=40, title='Profit in Ticks', type=integer) // Timestamp start = timestamp(st_yr_inp, st_mn_inp, st_dy_inp,00,00) end = timestamp(en_yr_inp, en_mn_inp, en_dy_inp,00,00) can_trade = time >= start and time <= end ma = sma(close, 100) if (can_trade and crossover(close, ma)) strategy.entry("long", strategy.long) strategy.exit("SL/TP","long", loss=loss_ticks, profit=profit_ticks) plot(ma, linewidth=2) |
List of Trades
As we can see from the list of trades, a 20 tick stop loss resulted in a 2 pip price difference. The 40 tick profit level resulted in a 4 pip difference. So we can see that price is able to tick without a minimum level and as such, a minimum tick level of zero is appropriate.
How do you track changes between ticks or order-fills? We can use variables with [ ] to differentiate changes between bars, but how about between ticks? For example, we placed an order at the end of last bar, and once the order gets filled, a script was called, and we can track changes from last bar by comparing variables between this bar and last bar using operator [ ]. Now we set stop loss and other actions in handling the newly filled orders. When the stop loss order gets filled, the same script function is called. Then how can we track what happened during last tick?
Thanks a lot
Yes I was wondering the same thing. I have a script running calculating at ever tick. I want to see how many ticks my buy condition stayed true for to imply how strong that signal is.. If buy = true for x ticks within a candle then take the action now, instead of waiting for candle close.
How are stock prices stored in trading view database? What is the variable that refers to a unit price of a stock ?
Hi,
How do we add tick to a price level?
example:
if I know ema(5)=0.9226.
however I want to add 5 pips to that value and use as my Stop Loss level
SL= 0.9226+50 ticks ?
Regards
SC Lai
There is a variable call
syminfo.mintick
. This provides the smallest tick level. In the case of Forex, that is 1 pip. For other instruments it might be 25 cents. So if you always want 5 ticks then you would do5 * syminfo.mintick
.Hope that helps!