Double SupertrendThis strategy is based on a custom indicator that was created based on the Supertrend indicator. At its core, there are always 2 super trend indicators with different factors to reduce market noise (false signals).
The strategy/indicator has some parameters to improve the signals and filters.
TECHNICAL ANALYSIS
☑ Show Indicators
This option will enable/disable the Supertrend indicators on the chart.
☑ Length
The length will be used on the Supertrend Indicator to calculate its values.
☑ Dev Fast
The fast deviation or factor from one of the super trend indicators. This will be the leading indicator for entry signals, as well as for the exit signals.
☑ Dev Slow
The slow deviation or factor from one of the super trend indicators. This will be the confirmation indicator for entry and exit signals.
☑ Exit Type
It's possible to select from 4 options for the exit signals. Exit signals always take profit target.
☑ ⥹ Reversals
This option will make the strategy/indicator calculate the exit signals based on the difference between the given period's highest and lowest candle value (see Period on this list). It's displayed on the chart with the cross. As it's possible to verify in the image below, there are multiple exit spots for every entry.
☑ ⥹ ATR
Using ATR as a base indicator for exit signals will make the strategy/indicator place limit/stop orders. Candle High + ATR for longs, Candle Low - ATR for shorts. The strategy will show the ATR level for take profit and stick with it until the next signal. This way, the take profit value remains based on the candle of the entry signal.
☑ ⥹ Fast Supertrend
With this option selected, the exit signals will be based on the Fast Supertsignal value, mirrored to make a profit.
☑ ⥹ Slow Supertrend
With this option selected, the exit signals will be based on the Slow Supertsignal value, which is mirrored to take profit.
☑ Period
This will represent the number of candles used on the exit signals when Reversals is selected as Exit Type. It's also used to calculate the gradient used on the Fills and Supertrend signals.
☑ Multiplier
It's used on the take profit when the ATR option is selected on the Exit Type.
STRATEGY
☑ Use The Strategy
This will enable/disable the strategy to show the trades calculations.
☑ Show Use Long/Short Entries
Option to make the strategy show/use Long or Short signals. Available only if Use The Strategy is enabled
☑ Show Use Exit Long/Short
Option to make the strategy show/use Exit Long or Short signals (valid when Reversals option is selected on the Exit Type). Available only if Use The Strategy is enabled
☑ Show Use Add Long/Short
Option to make the strategy show/use Add Long or Short signals. With this option enabled, the strategy will place multiple trades in the same direction, almost the same concept as a pyramiding parameter. It's based on the Fast Supersignal when the candle fails to cross and reverses. Available only if Use The Strategy is enabled
☑ Trades Date Start/End
The date range that the strategy will check the market data and make the trades
HOW TO USE
It's very straightforward. A long signal will appear as a green arrow with a text Long below it. A short signal will appear as a red arrow with a text Short above it. It's ideal to wait for the candle to finish to validate the signal.
The exit signals are optional but give a good idea of the configuration used when backtesting. Each market and timeframe will have its own configuration for the best results. On average, sticking to ATR as an exit signal will have less risk than the other options.
☑ Entry Signals
Follow the arrows with Long/Short texts on them. Wait for the signal candle to close to validate the entry.
☑ Exit Signals
Use them to close your position or to trail stop your orders and maximize profits. Select the exit type suitable for each timeframe and market
☑ Add Entries
It's possible to increase the position following the add margin/contracts based on the Add signals. Not mandatory, but may work as reentries or late entries using the same signal.
☑ What about Stop Loss?
The stop-loss levels were not included as a separated signal because it's already in the chart. There are some possible ideas for the stop loss:
☑⥹ Candle High/Low (2nd recommend option)
When it's a Long signal from the entry signal candle, the stop loss can be the Low value of the same candle. Very tight stop loss in some cases, depending on the candle range
☑⥹ Local Top/Bottom
Selecting the local top/bottom as stop loss will give the strategy more room for false breakouts or reversals, keeping the trade open and minimizing noises. Increases the risk
☑⥹ Fast Supertrend (1st recommend option)
The fast supertrend can be used as stop-loss as well. making it a moving level and working close to trail stop management
☑⥹ Fixed Percentage
It's possible to use a fixed risk percentage for the trades, making the risk easier to control and project. Since the market volatility is not fixed, this may affect the accuracy of the trades
☑⥹ Based on the ATR (3rd recommend option)
When the exit type option ATR is selected, it will display the take profit level for that entry. Just mirror that value and put it as stop-loss, or multiply that amount by 1.5 to have more room for market noise.
EXAMPLE CONFIGURATIONS
Here are some configuration ideas for some markets (all of them are from crypto, especially futures markets)
BTCUSDT 15min - Default configuration
BTCUSDT 1h - Length 10 | Dev Fast 3 | Dev Slow 4 | Exit Type ATR | Period 50 | Multiplier 1
BTCUSDT 4h - Length 10 | Dev Fast 2 | Dev Slow 4 | Exit Type ATR | Period 50 | Multiplier 1
ETHUSDT 15min - Length 20 | Dev Fast 1 | Dev Slow 3 | Exit Type Fast Supertrend | Period 50 | Multiplier 1
IOTAUSDT 15min - Length 10 | Dev Fast 1 | Dev Slow 2 | Exit Type Slow Supertrend | Period 50 | Multiplier 1
OMGUSDT 15min - Length 10 | Dev Fast 1 | Dev Slow 4 | Exit Type Slow Supertrend | Period 50 | Multiplier 1
VETUSDT 15min - Length 10 | Dev Fast 3 | Dev Slow 4 | Exit Type Slow Supertrend | Period 50 | Multiplier 1
HOW TO FIND OTHER CONFIGURATIONS
Here are some steps to find suitable configurations
select a market and time frame
enable the Use This Strategy option on the strategy
open the strategy tester panel and select the performance summary
open the strategy configuration and go to properties
change the balance to the same price of the symbol (example: BTCUSDT 60.000, use 60.000 as balance)
go back to the inputs tab and keep changing the parameters until you see the net profit be positive and bigger than the absolute value of the drawdown
in case you can't find a suitable configuration, try other timeframes
Since the tester reflects what happened in the past candles, it's not guaranteed to give the same results. However, this indicator/Strategy can be used with other indicators as a leading signal or confirmation signal.
Buscar en scripts para "backtesting"
Advanced Comparison ToolWith the new Pine Script features you can build pretty interesting scripts.
Here is my try to expand functionality of basic comparison tool you have in TradingView.
When you apply it on your chart you can select a bar when do you want to start comparing your instrument from.
In parameters you can specify up to 32 symbols to compare. You can also disable symbols and change color for them as well.
As a result you'll see a table with summary and line for every instrument you selected as if it started from the close of the selected bar.
Disclaimer.
Please remember that past performance may not be indicative of future results.
Due to various factors, including changing market conditions, the strategy may no longer perform as well as in historical backtesting.
This post and the script don’t provide any financial advice
Two Moving Average CrossChoose two completely different moving averages and determine crossover points. Feel free to copy and paste the code into any strategy using MA crosses in order to optimize backtesting.
Learning Built-in VarsI'm currently working on v5 of my Pine Script Programming Course.
As a part of it, I'm building a few tools/widgets to help students get the content easier.
Here is one of the tools. It's quite basic with it you can select a bar and see all the build-in variables for this bar (Except strategy variables)
I hope it will help you in learning Pine Script!
Disclaimer
Please remember that past performance may not be indicative of future results.
Due to various factors, including changing market conditions, the strategy may no longer perform as well as in historical backtesting.
This post and the script don’t provide any financial advice.
52 Weeks High/Low WidgetSome time ago I published my "All-Time High/Low Widget". I was asked to build and 52w weeks version.
So finally it's ready. It works pretty much the same way but uses a time period only of 52weeks.
You can also change the number of weeks in the parameters.
You can plot the levels and display some stats when 52W high/low happened and how far away are we at this moment.
Also, you can create alerts to get notified on 52W levels breakouts.
Disclaimer
Please remember that past performance may not be indicative of future results.
Due to various factors, including changing market conditions, the strategy may no longer perform as well as in historical backtesting.
This post and the script don’t provide any financial advice.
Monthly Returns in Strategies with Market BenchmarkThis is a modified version of this excellent script Monthly Returns in PineScript Strategues by QuantNomad
I liked and used the script but wanted to see how strategy performed vs market on each month/year. So I am sharing back.
The modification consists in adding Market or Buy & Hold performance between parenthesis inside each cell to better see how strategy performed vs market.
Also, 3 red levels and 3 green levels have been used :
For green :
1/ Light when strategy pnl > 0 but < market
2/ medium when strategy pnl > 0 and > market
3/ Dark when strategy pnl > 0 and market < 0 or pnl > market x 2
Same logic in the opposite direction for red.
The strategy provided here is just a showcase of how to use the table in pine script.
Disclaimer
Please remember that past performance may not be indicative of future results.
Due to various factors, including changing market conditions, the strategy may no longer perform as well as in historical backtesting.
This post and the script don’t provide any financial advice.
%R Trend Exhaustion [upslidedown]I love Williams %R! This indicator mixes two %R periods... a standard %R with a longer period %R. The longer period of 112 has interesting results for trend following strategies in the crypto market through backtesting.
Alone these are fairly ordinary but together they provide a very interesting trend exhaustion/reversal system while filtering out some noise. I have highlighted key areas of interest with filled boxes. An "area of interest" is when there is confluence between the short and long period %R values along with being overbought or oversold. Once there is a break in the overbought or oversold trend, an arrow will print.
This is one of my odder ideas that appears to have some merit and detects interesting tops or bottoms (or confirms a trend reversal) so I'm publicly publishing for the community to find. If you find this useful please reach out and let me know how you use it as it's fairly unique... and thus different than anything I've ever seen or used.
Multiple Indicators ScreenerA screener for multiple indicators with nice table output.
I was asked many times to update custom screener to display results in a table form. This way it looks much better.
You can play with background colors depend on values you're looking for.
In the screener, for example, I'm highlighting overbought/oversold RSI values, big ADX levels and trend of the Supertrend.
In parameters you can change settings for all indicators and change/disable tickers if 40 is too many for you.
There is only 1 function that calculates all these indicators. Potentially you can change and even add more indicators to this function.
Writing code for these kind of screener is a bit time consuming, so I even created a code generator in Python for these kind of indicators :) .
Disclaimer
Please remember that past performance may not be indicative of future results.
Due to various factors, including changing market conditions, the strategy may no longer perform as well as in historical backtesting.
This post and the script don’t provide any financial advice.
All-Time High/Low WidgetIt's a pretty simple widget to track all-time high and all-time low values.
You can plot the levels and display some stats when all-time happened and how far away are we at this moment.
Also, you can create alerts to get notified on ATH/ATL breakout.
Thanks to @Verleiht for helping me with the code.
Disclaimer
Please remember that past performance may not be indicative of future results.
Due to various factors, including changing market conditions, the strategy may no longer perform as well as in historical backtesting.
This post and the script don’t provide any financial advice.
Monthly Returns in PineScript StrategiesI'm not 100% satisfied with the strategy performance output I receive from TradingView. Quite often I want to see something that is not available by default. I usually export raw trades/metrics from TradingView and then do additional analysis manually.
But with tables, you can build additional metrics and tools for your strategies quite easily.
This script will just show a table with monthly/yearly performance of your script. Quite a lot of traders/investors used to look at returns like that. Also, it might help you to identify periods of time when your strategy performed good/bad than expected and try to analyze that better.
The script is very simple and I believe you can easily apply it to your own strategies.
Disclaimer
Please remember that past performance may not be indicative of future results.
Due to various factors, including changing market conditions, the strategy may no longer perform as well as in historical backtesting.
This post and the script don’t provide any financial advice.
[Advanced] Hilega-Milega IndicatorThis Indicator Name is Hilega Milega, and the original Idea given by Nitish Kumar, I just coded it and add some signals for backtesting.
it works on RSI + WMA and EMA plotted.
Default Values Used :
RSI = 9
WMA = 21
EMA = 3
But i added some extra, now everyone can change the Type of WMA and EMA, also SMA for trend confirmation,
How it works ??
Buy : When RSI crossover WMA or any Type of Moving Average you choose,
Sell : When RSI crossunder WMA or any Type of Moving Average you choose,
also:
Buy : When EMA crossover WMA or any Type of Moving Average you choose,
Sell : When EMA crossunder WMA or any Type of Moving Average you choose,
also:
Buy : When RSI + EMA crossover WMA or any Type of Moving Average you choose at the Same time,
Sell : When RSI + EMA crossunder WMA or any Type of Moving Average you choose at the Same time,
and Much More...! hope so you like it,
[astropark] Moon Phases [strategy]Dear Followers,
today I'm glad to present you an indicator which calculates Moon Phases and let's you backtest the simplest strategy over it: buy/sell on full moon and do the opposite on new moon.
This is a public free indicator based on the public one by @paaax:
I added my usual backtesting logic, plus some more customization inputs for easy coloring.
The lower the timeframe you backtest on, the more backtesting data are effective.
Enjoy!
-- astropark
MACD Long StratFirst script I've written, but the concept is pretty simple. This uses the MACD with settings fast_SMA = 6 and slow SMA=16 and uses the distance between the 2 (histogram) to look for potential trend reversals to flag potential entries for Long trades. It waits for the confirmation looking backward 2 x timeframes (to reduce false calls slightly). You can adjust it to open / close quicker (1 timeframe instread of 2) but backtesting shows 2 timeframe delay is best to avoid false signals.
The script suggests Long entry points based on this criteria and uses the converse (reducing histogram / SMA difference delayed by 2 timeframes) to suggest exit or trade close points for downward reversal. It was originally written looking at 1m scalps but backtesting shows this is even more effective on higher timeframes (1D).
[Sidders] MACDEMASAR IndicatorCame across a cool idea for a strategy that couldn't find in the indicator database, so decided to code it up myself for your pleasure.
Indicators consists of 3 indicators: EMA(200) to determine the overall trend, and the MACD & Parabolic SAR to determine entries (and exits).
Long entry contains 4 conditions and is generated when price is above the 200EMA (1), the MACD crosses above the signal line (2), while they are both below 0 line (3) and when the parabolic SAR is below the closing price of the bar (4).
Short entry is build up the same but in reverse: price is below the 200EMA(1), signal line crosses below the MACD line (2), while they are both above the 0 line (3) and when the parabolic SAR is above the closing price of the bar (4).
Place the stoploss on the parabolic SAR dot below/above the candle that created the signal. Profit target 1:1 risk:reward ratio, but can ofcourse be changed according to your risk apetite. Might add automatically drawn SL/TPs in a later update.
Concept behind the strategy should work on all timeframes, but will require proper backtesting. I think with additional filters the strategy can also be way more finetuned and profitable, personally haven't had the time yet to dive into that.
Have also added alerts for your convenience.
Enjoy!
Logging in Pine ScriptI'm building quite a lot of pretty complicated indicators/strategies in Pine Script. Quite often they don't work from the 1 try so I have to debug them heavily.
In Pine Script there are no fancy debuggers so you have to be creative. You can plot values on your screens, check them in the data window, etc.
If you want to display some textual information, you can plot some info as labels on the screen.
It's not the most convenient way, so with the appearance of tables in Pine Script, I decided to implement a custom logger that will allow me to track some useful information about my indicator over time.
Tables work much better for this kind of thing than labels. They're attached to your screen, you can nicely scale them and you can style them much better.
The idea behind it is very simple. I used few arrays to store the message, bar number, timestamp, and type of the message (you can color messages depend on the type for example).
There is a function log_msg that just append new messages to these arrays.
In the end, for the last bar, I create the table and display the last X messages in it.
In parameters, you can show/hide the entire journal, change the number of messages displayed and choose an offset. With offset, you can basically scroll through the history of messages.
Currently, I implemented 3 types of messages, and I color messages according to these types:
Message - gray
Warning - yellow
Error - red
Of course, it's a pretty simple example, you can create a much fancier way of styling your logs.
What do you think about it? Is it useful for you? What do you use to debug code in Pine Script?
Disclaimer
Please remember that past performance may not be indicative of future results.
Due to various factors, including changing market conditions, the strategy may no longer perform as good as in historical backtesting.
This post and the script don’t provide any financial advice.
Custom Multi-Timeframe Screener with AlertsThis is a multi-timeframe screener with alerts. Use this way you can create a screener on indicators using 2 or more timeframes.
In TradingView there is a limit of 40 security function calls. Every timeframe requires another security call so you can screen fewer symbols with any additional timeframe.
In this example, I use 2 timeframes, so the maximum amount of symbols you can scan is 40/2 = 20.
For 3 timeframes - 13, 4tfs - 10, 5tfs - 8 symbols and so on.
In this simplistic example, I require a cross of EMAs on the current timeframe and confirmation that one EMA above/below another from the second timeframe.
Of course, you can create much more complicated functions for this screener.
Params
- higher timeframe
- ema params
- 20 symbol inputs for instruments you want to use in this screener
Alerts
You can create an alert from it easily by selecting the screener name from the list and then selecting "Any alert() function call".
No additional configuration is required, message and alert on close is generated in the code.
You should better change the default name for your alert. Sometimes because of big amount of inputs you might receive an error.
Disclaimer
Please remember that past performance may not be indicative of future results.
Due to various factors, including changing market conditions, the strategy may no longer perform as good as in historical backtesting.
This post and the script don’t provide any financial advice.
Multiple Screeners with AlertsI already published few version of my custom screeners. Unfortunately, because of TradingView's security function call limit you can't use more than 40 stocks in 1 screener.
Fortunately, you can compute multiple values in your function and screen few indicators at once.
In this script I show how you can compute 5 indicators at the same time for 40 instruments. I display then in different labels.
Every label consist of list of instruments satisfying current indicator conditions and a value for it. It can be absolute value as for RSI or -1/1 representing Bullish/Bearish event.
Also you can create 1 alert with result of all screeners inside.
In this example I took 5 indicators with following conditions:
RSI - "RSI < 30" or "RSI > 70"
TSI - "TSI < -30" or "RSI >30"
ADX - "ADX > 40"
MACD - "MACD Bullish Cross" or "MACD Bearish Cross" (1 and -1 in screener)
AO - "AO Crosses 0 UP" or "AO Crosses 0 DOWN" (1 and -1 in screener)
Params
- bars_apart - this parameter define how may bars apart you labels are on your chart. If you see labels overlapping, increase this number.
- Parameters for all used indicators
- 40 symbol inputs for instruments you want to use in this screener
Alerts
You can create an alert from it easily by selecting screener name from the list and then selecting "Any alert() function call".
No additional configuration is required, message and alert on close is generated in the code.
You should better change default name for your alert. Sometimes because of big amount of inputs you might receive an error.
Disclaimer
Please remember that past performance may not be indicative of future results.
Due to various factors, including changing market conditions, the strategy may no longer perform as good as in historical backtesting.
This post and the script don’t provide any financial advice.
Delta-RSI Strategy (with filters)Delta-RSI Strategy (with filters):
This is a version of the Delta-RSI Oscillator strategy with several criteria available to filter entry and exit signals. This script is also suitable for backtesting over a user-defined period and offers several risk management options (take profit and stop loss).
Since the publication of the Delta-RSI Oscillator script, I have been asked many times to make it compatible with the Strategy Tester and add filtering criteria to minimize "false" signals. This version covers many of these requests. Feel free to insert your favorite D-RSI parameters and play around!
ABOUT DELTA-RSI
Delta-RSI represents a smoothed time derivative of the RSI designed as a momentum indicator (see links below):
INPUT DESCTIPTION
MODEL PARAMETERS
Polynomial Order : The order of local polynomial used to interpolate the relative strength index (RSI).
Length : The length of the lookback frame where local regression is applied.
RSI Length : The timeframe of RSI used as input.
Signal Length : The signal line is a EMA of the D-RSI time series. This input parameter defines the EMA length.
ALLOWED ENTRIES
The strategy can include long entries, short entries or both.
ENTRY AND EXIT CONDITIONS
Zero-crossing : bullish trade signal triggered when D-RSI crosses zero from negative to positive values (bearish otherwise)
Signal Line Crossing : bullish trade signal triggered when D-RSI crosses from below to above the signal line (bearish otherwise)
Direction Change : bullish trade signal triggered when D-RSI was negative and starts ascending (bearish otherwise)
APPLY FILTERS TO
The filters (described below) can be applied to long entry, short entry and exit signals.
RELATIVE VOLUME FILTER
When activated, the D-RSI-driven entries and exits will be triggered only if the current volume is greater than N times the average over the last M bars.
VOLATILITY FILTER
When activated, the D-RSI-driven entries and exits will be triggered only if the N-period average true range, ATR, is greater than the M-period ATR. If N < M, this condition implies increasing volatility.
OVERBOUGHT/OVERSOLD FILTER
When activated, the D-RSI-driven entries and exits will be triggered only if the value of 14-period RSI is in the range between N and M.
STOP LOSS/TAKE PROFIT
Fixed and trailing stop loss as well as take profit options are available.
FIXED BACKTESTING START/END DATES
If the checkboxes are not checked, the strategy will backtest all available price bars.
Hurst ExponentMy first try to implement Full Hurst Exponent.
The Hurst exponent is used as a measure of long-term memory of time series. It relates to the autocorrelations of the time series and the rate at which these decrease as the lag between pairs of values increases
The Hurst exponent is referred to as the "index of dependence" or "index of long-range dependence". It quantifies the relative tendency of a time series either to regress strongly to the mean or to cluster in a direction.
In short, depending on the value you can spot the trending / reversing market.
Values 0.5 to 1 - market trending
Values 0 to 0.5 - market tend to mean revert
Hurst Exponent is computed using Rescaled range (R/S) analysis.
I split the lookback period (N) in the number of shorter samples (for ex. N/2, N/4, N/8, etc.). Then I calculate rescaled range for each sample size.
The Hurst exponent is estimated by fitting the power law. Basically finding the slope of log(samples_size) to log(RS).
You can choose lookback and sample sizes yourself. Max 8 possible at the moment, if you want to use less use 0 in inputs.
It's pretty computational intensive, so I added an input so you can limit from what date you want it to be calculated. If you hit the time limit in PineScript - limit the history you're using for calculations.
####################
Disclaimer
Please remember that past performance may not be indicative of future results.
Due to various factors, including changing market conditions, the strategy may no longer perform as good as in historical backtesting.
This post and the script don’t provide any financial advice.
Custom Screener with Alerts V2 [QuantNomad]TradingView just recently announced the alert() function that allows you to create dynamic alerts from both strategies and studies.
So I decided to update custom screener I published before. It was based on alerts from orders in strategies, that was the only way to create dynamic alerts in PineScript at that point.
With the alert() function code become cleaner and more readable.
It works for up to 40 symbols at the same time.
You can create an alert from it easily by selecting screener name from the list and then selecting "Any alert() function call".
No additional configuration is required, message and alert on close I set up in the code.
I created as an example a screener that tracks both overbought (RSI > 70) and oversold stocks (RSI < 30).
To create your own screener you have to change only screenerFunc().
By design it should output 2 values:
cond - True/False Boolean variable. Should this instrument be displayed in the screener?
value - Additional numeric value you can display in your screener. I display RSI level for selected stocks for example.
Link to the old screener:
Disclaimer
Please remember that past performance may not be indicative of future results.
Due to various factors, including changing market conditions, the strategy may no longer perform as good as in historical backtesting.
This post and the script don’t provide any financial advice.
Simple Hurst Exponent [QuantNomad]This is a simplified version of the Hurst Exponent indicator.
In the meantime, I'm working on the full version. It's computationally intensive, so it's a challenge to squeeze it to PineScript limits. It will require some time to optimize it, so I decided to publish a simplified version for now.
The Hurst exponent is used as a measure of long-term memory of time series. It relates to the autocorrelations of the time series, and the rate at which these decrease as the lag between pairs of values increases
The Hurst exponent is referred to as the "index of dependence" or "index of long-range dependence". It quantifies the relative tendency of a time series either to regress strongly to the mean or to cluster in a direction.
In short depend on value you can spot trending / reversing market.
Values 0.5 to 1 - market trending
Values 0 to 0.5 - market tend to mean revert
####################
Disclaimer
Please remember that past performance may not be indicative of future results.
Due to various factors, including changing market conditions, the strategy may no longer perform as good as in historical backtesting.
This post and the script don’t provide any financial advice.
MA Divergences StrategyThis is the Strategy version of the Study I published. It is a Moving Average that can be applied to any plot to plot divergences on any oscillator, as well as perform backtesting. You'll need a REALLY good oscillator to perform live trades using this alone, but I think it is a valuable tool and had the Strategy hanging around and for some reason didn't upload it yet.
So here it is.
Turn Length to 1 to follow the oscillator without lag. Turn Length up if you are getting too many false signals or tweak the original oscillator settings.
`security()` revisited [PineCoders]NOTE
The non-repainting technique in this publication that relies on bar states is now deprecated, as we have identified inconsistencies that undermine its credibility as a universal solution. The outputs that use the technique are still available for reference in this publication. However, we do not endorse its usage. See this publication for more information about the current best practices for requesting HTF data and why they work.
█ OVERVIEW
This script presents a new function to help coders use security() in both repainting and non-repainting modes. We revisit this often misunderstood and misused function, and explain its behavior in different contexts, in the hope of dispelling some of the coder lure surrounding it. The function is incredibly powerful, yet misused, it can become a dangerous WMD and an instrument of deception, for both coders and traders.
We will discuss:
• How to use our new `f_security()` function.
• The behavior of Pine code and security() on the three very different types of bars that make up any chart.
• Why what you see on a chart is a simulation, and should be taken with a grain of salt.
• Why we are presenting a new version of a function handling security() calls.
• Other topics of interest to coders using higher timeframe (HTF) data.
█ WARNING
We have tried to deliver a function that is simple to use and will, in non-repainting mode, produce reliable results for both experienced and novice coders. If you are a novice coder, stick to our recommendations to avoid getting into trouble, and DO NOT change our `f_security()` function when using it. Use `false` as the function's last argument and refrain from using your script at smaller timeframes than the chart's. To call our function to fetch a non-repainting value of close from the 1D timeframe, use:
f_security(_sym, _res, _src, _rep) => security(_sym, _res, _src )
previousDayClose = f_security(syminfo.tickerid, "D", close, false)
If that's all you're interested in, you are done.
If you choose to ignore our recommendation and use the function in repainting mode by changing the `false` in there for `true`, we sincerely hope you read the rest of our ramblings before you do so, to understand the consequences of your choice.
Let's now have a look at what security() is showing you. There is a lot to cover, so buckle up! But before we dig in, one last thing.
What is a chart?
A chart is a graphic representation of events that occur in markets. As any representation, it is not reality, but rather a model of reality. As Scott Page eloquently states in The Model Thinker : "All models are wrong; many are useful". Having in mind that both chart bars and plots on our charts are imperfect and incomplete renderings of what actually occurred in realtime markets puts us coders in a place from where we can better understand the nature of, and the causes underlying the inevitable compromises necessary to build the data series our code uses, and print chart bars.
Traders or coders complaining that charts do not reflect reality act like someone who would complain that the word "dog" is not a real dog. Let's recognize that we are dealing with models here, and try to understand them the best we can. Sure, models can be improved; TradingView is constantly improving the quality of the information displayed on charts, but charts nevertheless remain mere translations. Plots of data fetched through security() being modelized renderings of what occurs at higher timeframes, coders will build more useful and reliable tools for both themselves and traders if they endeavor to perfect their understanding of the abstractions they are working with. We hope this publication helps you in this pursuit.
█ FEATURES
This script's "Inputs" tab has four settings:
• Repaint : Determines whether the functions will use their repainting or non-repainting mode.
Note that the setting will not affect the behavior of the yellow plot, as it always repaints.
• Source : The source fetched by the security() calls.
• Timeframe : The timeframe used for the security() calls. If it is lower than the chart's timeframe, a warning appears.
• Show timeframe reminder : Displays a reminder of the timeframe after the last bar.
█ THE CHART
The chart shows two different pieces of information and we want to discuss other topics in this section, so we will be covering:
A — The type of chart bars we are looking at, indicated by the colored band at the top.
B — The plots resulting of calling security() with the close price in different ways.
C — Points of interest on the chart.
A — Chart bars
The colored band at the top shows the three types of bars that any chart on a live market will print. It is critical for coders to understand the important distinctions between each type of bar:
1 — Gray : Historical bars, which are bars that were already closed when the script was run on them.
2 — Red : Elapsed realtime bars, i.e., realtime bars that have run their course and closed.
The state of script calculations showing on those bars is that of the last time they were made, when the realtime bar closed.
3 — Green : The realtime bar. Only the rightmost bar on the chart can be the realtime bar at any given time, and only when the chart's market is active.
Refer to the Pine User Manual's Execution model page for a more detailed explanation of these types of bars.
B — Plots
The chart shows the result of letting our 5sec chart run for a few minutes with the following settings: "Repaint" = "On" (the default is "Off"), "Source" = `close` and "Timeframe" = 1min. The five lines plotted are the following. They have progressively thinner widths:
1 — Yellow : A normal, repainting security() call.
2 — Silver : Our recommended security() function.
3 — Fuchsia : Our recommended way of achieving the same result as our security() function, for cases when the source used is a function returning a tuple.
4 — White : The method we previously recommended in our MTF Selection Framework , which uses two distinct security() calls.
5 — Black : A lame attempt at fooling traders that MUST be avoided.
All lines except the first one in yellow will vary depending on the "Repaint" setting in the script's inputs. The first plot does not change because, contrary to all other plots, it contains no conditional code to adapt to repainting/no-repainting modes; it is a simple security() call showing its default behavior.
C — Points of interest on the chart
Historical bars do not show actual repainting behavior
To appreciate what a repainting security() call will plot in realtime, one must look at the realtime bar and at elapsed realtime bars, the bars where the top line is green or red on the chart at the top of this page. There you can see how the plots go up and down, following the close value of each successive chart bar making up a single bar of the higher timeframe. You would see the same behavior in "Replay" mode. In the realtime bar, the movement of repainting plots will vary with the source you are fetching: open will not move after a new timeframe opens, low and high will change when a new low or high are found, close will follow the last feed update. If you are fetching a value calculated by a function, it may also change on each update.
Now notice how different the plots are on historical bars. There, the plot shows the close of the previously completed timeframe for the whole duration of the current timeframe, until on its last bar the price updates to the current timeframe's close when it is confirmed (if the timeframe's last bar is missing, the plot will only update on the next timeframe's first bar). That last bar is the only one showing where the plot would end if that timeframe's bars had elapsed in realtime. If one doesn't understand this, one cannot properly visualize how his script will calculate in realtime when using repainting. Additionally, as published scripts typically show charts where the script has only run on historical bars, they are, in fact, misleading traders who will naturally assume the script will behave the same way on realtime bars.
Non-repainting plots are more accurate on historical bars
Now consider this chart, where we are using the same settings as on the chart used to publish this script, except that we have turned "Repainting" off this time:
The yellow line here is our reference, repainting line, so although repainting is turned off, it is still repainting, as expected. Because repainting is now off, however, plots on historical bars show the previous timeframe's close until the first bar of a new timeframe, at which point the plot updates. This correctly reflects the behavior of the script in the realtime bar, where because we are offsetting the series by one, we are always showing the previously calculated—and thus confirmed—higher timeframe value. This means that in realtime, we will only get the previous timeframe's values one bar after the timeframe's last bar has elapsed, at the open of the first bar of a new timeframe. Historical and elapsed realtime bars will not actually show this nuance because they reflect the state of calculations made on their close , but we can see the plot update on that bar nonetheless.
► This more accurate representation on historical bars of what will happen in the realtime bar is one of the two key reasons why using non-repainting data is preferable.
The other is that in realtime, your script will be using more reliable data and behave more consistently.
Misleading plots
Valiant attempts by coders to show non-repainting, higher timeframe data updating earlier than on our chart are futile. If updates occur one bar earlier because coders use the repainting version of the function, then so be it, but they must then also accept that their historical bars are not displaying information that is as accurate. Not informing script users of this is to mislead them. Coders should also be aware that if they choose to use repainting data in realtime, they are sacrificing reliability to speed and may be running a strategy that behaves very differently from the one they backtested, thus invalidating their tests.
When, however, coders make what are supposed to be non-repainting plots plot artificially early on historical bars, as in examples "c4" and "c5" of our script, they would want us to believe they have achieved the miracle of time travel. Our understanding of the current state of science dictates that for now, this is impossible. Using such techniques in scripts is plainly misleading, and public scripts using them will be moderated. We are coding trading tools here—not video games. Elementary ethics prescribe that we should not mislead traders, even if it means not being able to show sexy plots. As the great Feynman said: You should not fool the layman when you're talking as a scientist.
You can readily appreciate the fantasy plot of "c4", the thinnest line in black, by comparing its supposedly non-repainting behavior between historical bars and realtime bars. After updating—by miracle—as early as the wide yellow line that is repainting, it suddenly moves in a more realistic place when the script is running in realtime, in synch with our non-repainting lines. The "c5" version does not plot on the chart, but it displays in the Data Window. It is even worse than "c4" in that it also updates magically early on historical bars, but goes on to evaluate like the repainting yellow line in realtime, except one bar late.
Data Window
The Data Window shows the values of the chart's plots, then the values of both the inside and outside offsets used in our calculations, so you can see them change bar by bar. Notice their differences between historical and elapsed realtime bars, and the realtime bar itself. If you do not know about the Data Window, have a look at this essential tool for Pine coders in the Pine User Manual's page on Debugging . The conditional expressions used to calculate the offsets may seem tortuous but their objective is quite simple. When repainting is on, we use this form, so with no offset on all bars:
security(ticker, i_timeframe, i_source )
// which is equivalent to:
security(ticker, i_timeframe, i_source)
When repainting is off, we use two different and inverted offsets on historical bars and the realtime bar:
// Historical bars:
security(ticker, i_timeframe, i_source )
// Realtime bar (and thus, elapsed realtime bars):
security(ticker, i_timeframe, i_source )
The offsets in the first line show how we prevent repainting on historical bars without the need for the `lookahead` parameter. We use the value of the function call on the chart's previous bar. Since values between the repainting and non-repainting versions only differ on the timeframe's last bar, we can use the previous value so that the update only occurs on the timeframe's first bar, as it will in realtime when not repainting.
In the realtime bar, we use the second call, where the offsets are inverted. This is because if we used the first call in realtime, we would be fetching the value of the repainting function on the previous bar, so the close of the last bar. What we want, instead, is the data from the previous, higher timeframe bar , which has elapsed and is confirmed, and thus will not change throughout realtime bars, except on the first constituent chart bar belonging to a new higher timeframe.
After the offsets, the Data Window shows values for the `barstate.*` variables we use in our calculations.
█ NOTES
Why are we revisiting security() ?
For four reasons:
1 — We were seeing coders misuse our `f_secureSecurity()` function presented in How to avoid repainting when using security() .
Some novice coders were modifying the offset used with the history-referencing operator in the function, making it zero instead of one,
which to our horror, caused look-ahead bias when used with `lookahead = barmerge.lookahead_on`.
We wanted to present a safer function which avoids introducing the dreaded "lookahead" in the scripts of unsuspecting coders.
2 — The popularity of security() in screener-type scripts where coders need to use the full 40 calls allowed per script made us want to propose
a solid method of allowing coders to offer a repainting/no-repainting choice to their script users with only one security() call.
3 — We wanted to explain why some alternatives we see circulating are inadequate and produce misleading behavior.
4 — Our previous publication on security() focused on how to avoid repainting, yet many other considerations worthy of attention are not related to repainting.
Handling tuples
When sending function calls that return tuples with security() , our `f_security()` function will not work because Pine does not allow us to use the history-referencing operator with tuple return values. The solution is to integrate the inside offset to your function's arguments, use it to offset the results the function is returning, and then add the outside offset in a reassignment of the tuple variables, after security() returns its values to the script, as we do in our "c2" example.
Does it repaint?
We're pretty sure Wilder was not asked very often if RSI repainted. Why? Because it wasn't in fashion—and largely unnecessary—to ask that sort of question in the 80's. Many traders back then used daily charts only, and indicator values were calculated at the day's close, so everybody knew what they were getting. Additionally, indicator values were calculated by generally reputable outfits or traders themselves, so data was pretty reliable. Today, almost anybody can write a simple indicator, and the programming languages used to write them are complex enough for some coders lacking the caution, know-how or ethics of the best professional coders, to get in over their heads and produce code that does not work the way they think it does.
As we hope to have clearly demonstrated, traders do have legitimate cause to ask if MTF scripts repaint or not when authors do not specify it in their script's description.
► We recommend that authors always use our `f_security()` with `false` as the last argument to avoid repainting when fetching data dependent on OHLCV information. This is the only way to obtain reliable HTF data. If you want to offer users a choice, make non-repainting mode the default, so that if users choose repainting, it will be their responsibility. Non-repainting security() calls are also the only way for scripts to show historical behavior that matches the script's realtime behavior, so you are not misleading traders. Additionally, non-repainting HTF data is the only way that non-repainting alerts can be configured on MTF scripts, as users of MTF scripts cannot prevent their alerts from repainting by simply configuring them to trigger on the bar's close.
Data feeds
A chart at one timeframe is made up of multiple feeds that mesh seamlessly to form one chart. Historical bars can use one feed, and the realtime bar another, which brokers/exchanges can sometimes update retroactively so that elapsed realtime bars will reappear with very slight modifications when the browser's tab is refreshed. Intraday and daily chart prices also very often originate from different feeds supplied by brokers/exchanges. That is why security() calls at higher timeframes may be using a completely different feed than the chart, and explains why the daily high value, for example, can vary between timeframes. Volume information can also vary considerably between intraday and daily feeds in markets like stocks, because more volume information becomes available at the end of day. It is thus expected behavior—and not a bug—to see data variations between timeframes.
Another point to keep in mind concerning feeds it that when you are using a repainting security() plot in realtime, you will sometimes see discrepancies between its plot and the realtime bars. An artefact revealing these inconsistencies can be seen when security() plots sometimes skip a realtime chart bar during periods of high market activity. This occurs because of races between the chart and the security() feeds, which are being monitored by independent, concurrent processes. A blue arrow on the chart indicates such an occurrence. This is another cause of repainting, where realtime bar-building logic can produce different outcomes on one closing price. It is also another argument supporting our recommendation to use non-repainting data.
Alternatives
There is an alternative to using security() in some conditions. If all you need are OHLC prices of a higher timeframe, you can use a technique like the one Duyck demonstrates in his security free MTF example - JD script. It has the great advantage of displaying actual repainting values on historical bars, which mimic the code's behavior in the realtime bar—or at least on elapsed realtime bars, contrary to a repainting security() plot. It has the disadvantage of using the current chart's TF data feed prices, whereas higher timeframe data feeds may contain different and more reliable prices when they are compiled at the end of the day. In its current state, it also does not allow for a repainting/no-repainting choice.
When `lookahead` is useful
When retrieving non-price data, or in special cases, for experiments, it can be useful to use `lookahead`. One example is our Backtesting on Non-Standard Charts: Caution! script where we are fetching prices of standard chart bars from non-standard charts.
Warning users
Normal use of security() dictates that it only be used at timeframes equal to or higher than the chart's. To prevent users from inadvertently using your script in contexts where it will not produce expected behavior, it is good practice to warn them when their chart is on a higher timeframe than the one in the script's "Timeframe" field. Our `f_tfReminderAndErrorCheck()` function in this script does that. It can also print a reminder of the higher timeframe. It uses one security() call.
Intrabar timeframes
security() is not supported by TradingView when used with timeframes lower than the chart's. While it is still possible to use security() at intrabar timeframes, it then behaves differently. If no care is taken to send a function specifically written to handle the successive intrabars, security() will return the value of the last intrabar in the chart's timeframe, so the last 1H bar in the current 1D bar, if called at "60" from a "D" chart timeframe. If you are an advanced coder, see our FAQ entry on the techniques involved in processing intrabar timeframes. Using intrabar timeframes comes with important limitations, which you must understand and explain to traders if you choose to make scripts using the technique available to others. Special care should also be taken to thoroughly test this type of script. Novice coders should refrain from getting involved in this.
█ TERMINOLOGY
Timeframe
Timeframe , interval and resolution are all being used to name the concept of timeframe. We have, in the past, used "timeframe" and "resolution" more or less interchangeably. Recently, members from the Pine and PineCoders team have decided to settle on "timeframe", so from hereon we will be sticking to that term.
Multi-timeframe (MTF)
Some coders use "multi-timeframe" or "MTF" to name what are in fact "multi-period" calculations, as when they use MAs of progressively longer periods. We consider that a misleading use of "multi-timeframe", which should be reserved for code using calculations actually made from another timeframe's context and using security() , safe for scripts like Duyck's one mentioned earlier, or TradingView's Relative Volume at Time , which use a user-selected timeframe as an anchor to reset calculations. Calculations made at the chart's timeframe by varying the period of MAs or other rolling window calculations should be called "multi-period", and "MTF-anchored" could be used for scripts that reset calculations on timeframe boundaries.
Colophon
Our script was written using the PineCoders Coding Conventions for Pine .
The description was formatted using the techniques explained in the How We Write and Format Script Descriptions PineCoders publication.
Snippets were lifted from our MTF Selection Framework , then massaged to create the `f_tfReminderAndErrorCheck()` function.
█ THANKS
Thanks to apozdnyakov for his help with the innards of security() .
Thanks to bmistiaen for proofreading our description.
Look first. Then leap.






















