ScalpyScalpy is made up of a 2 main parts.
- The cloud comprising of a 10 period SMA and a 30 period SMA.
- When the cloud is green you should be looking for long entries.
- When the cloud is red you should be looking for short entries.
- Price is most bullish above a green cloud and most bearish below a red cloud.
- Being within the cloud indicates indecision.
The blue and white lines on the indicator show the relationship between price and momentum.
They can be used to spot reversals in two ways:
- The first is a divergence between price (blue line) and RSI (white line)
- If the price makes a lower low but the RSI makes a higher low this shows the trend is weakening and may be reversing soon (as can be seen by the two yellow lines on the chart).
The second is a simple crossover:
- When the white line crosses the blue line to the upside this signals a long entry.
- When the white line crosses the blue line to the downside this signals a short entry.
Cari skrip untuk "entry"
Study for Squeeze Momentum Indicator [LazyBear]This study is based on LazyBear Squeeze Momentum Indicator and my strategy developed using it.
I added some custom feature and filters.
Main improvements are:
1- study is updated to version 4 of pine script;
2- I added alerts for entry rules and exit rules.
3- Alert syntax can be customized for webhooks: I added one example only for long entry.
You can customize a lot of features to get a profitable strategy.
Here is a link to original study.
Please use comment section for any feedback.
Volatility Traders Minds Strategy (VTM Strategy)Volatility Traders Minds Strategy (VTM Strategy)
I found this startegy on internet, with a video explaingin how it works.
Conditions for entry:
1 - Candles must to be above or bellow the 48 MA (Yellow line)
2 - Candles must to break the middle of bollinger bands
3 - Macd must to be above or bellow zero level;
4 - ADX must to be above 25 level
Credits to who developed this startegy (google it).
Thanks to all pinescripters mentined in the code for their snippets.
It could be improved with stop loss based on ATR etc.
I have also a study with alerts.
Please use comment section for any feedback or contact me if you need support.
DW-RSI EMA with EMA of RSIThis is an RSI Oscillator with an EMA of the RSI for a signal line. The RSI line is Green when above the signal line and Red when below the signal line.
This does not use the traditional 30% / 70% over sold / over bought analysis. Therefore the levels are not shown.
The analysis is this:
When the RSI is above the signal line then price has a bullish bias.
When the RSI is below the signal line then price has a bearish bias.
I wrote use this for Forex Spot Currencies where I feel overbought and oversold may be less valid than it may be in other markets such as stocks.
As with all indicators, do not use as your sole reason to enter the market, but use with other indicators or price action signals to get a confluence of signals to confirm your entry.
I use it with an 8, 21 and 50 EMA to confirm entry and exit. I give it more weight for exits than I do for entries.
Easy to Use Stochastic + RSI StrategyA simple strategy that yields some great results.
CODE VARIABLES
LINE 2 - Here you can change your currency and amount you want to invest on each entry.
LINE 10/11/12 - Here we establish what date we want to start backtesting from. Simply change the defval on each line to change the date (In the code below we start on Jan 1st, 2014).
LINES 19 through 27 - Here we set our Stochastic and RSI sensitivity (Currently %K = 14, %D = 3, RSI = 14). Change these to your preference.
LINE 39/41 - Here we execute our orders (Currently set when %K crosses %D under the 20 value and RSI is less than 50 to BUY, %K crosses %D above the 80 value and RSI is greater than 60 to SELL). Change these to your preference.
NOTE: As a beginner you may not want to short stock, therefore LINE 6 was added to only allow long positions.
I didn't overlay the RSI value over the Stochastics because it was too cluttered. Just add the RSI indictor seperately to your layout.
As always, couple this with trend following and exit/entry rules to make the profitability even higher!
Cheers!
Easy to Use 50/100/200 Day Moving Average StrategyWhenever you see someone publish a chart or idea, what's the one thing you almost always see? Moving Averages!
Many investors focus on these indictors solely as entry and exit points, so here's an easy to manipulate strategy to backtest and see if this is feasible on your security.
CODE VARIABLES
LINE 2 - Here you can change your currency and amount you want to invest on each entry.
LINE 8/9/10 - Here we establish the 50 (Fast), 100 (Medium) and 200 (Slow) day variables. These can be adjusted to your choosing.
LINE 13/14/15 - Here we establish what date we want to start backtesting from. Simple change the defval on each line to change the date (In the code below we start on Jan 1st, 2010).
LINE 20/23 - Here, within the crossover and crossunder functions, we set which MA's must cross to enter and exit a trade. Below we have the 50 day moving above and under the 200 day. Simple change the variables to FastMA, MediumMA and SlowMA to your choosing.
NOTE: As a beginner you may not want to short stock, therefore LINE 5 was added to only allow long positions.
Hope this helps, from one beginner to another.
Cheers!
PPO Divergence and Aggregate Signal ComboThis is a further development of the last two posts on aggregated signal generation. It shows how to implement the idea in conjunction with another indicator. In this case general rule for long and short entry: the aggregated curve (gray) must cross the mid-line. Colored columns serve as an early warning. Settings were tested with EURUSD in 5m, 30m and 1H TFs.
Amazing Crossover System - 100+ pips per day!I got the main concept for this system on another site. While I have made one important change, I must stress that the heart of this system was created by someone else! We must give credit where credit is due!
Y'all know baby pips. @ForexPhantom published about this system and did both back and forward test around 10 years ago.
I found it on the sit and now I put it to code to see how it performs. I assume 10 points spread for every trade. I use Renesource or AxiTrader to get the low spreads.
There are 2 mods, the single trades and constant trading on the direction.
Main concept
Indicators
5 EMA -- YELLOW
10 EMA -- RED
RSI (10 - Apply to Median Price: HL/2) -- One level at 50.
TIME FRAME
1 Hour Only (very important!)
PAIRS
Virtually any pair seems to work as this is strictly technical analysis.
I recommend sticking to the main currencies and avoiding cross currencies (just his preference).
WHEN TO ENTER A TRADE
Enter LONG when the Yellow EMA crosses the Red EMA from underneath.
RSI must be approaching 50 from the BOTTOM and cross 50 to warrant entry.
Enter SHORT when the Yellow EMA crosses the Red EMA from the top.
RSI must be approaching 50 from the TOP and cross 50 to warrant entry.
I've attached a picture which demonstrates all these conditions.
That's it!
f.bpcdn.co
On Balance Volume +This is the standard On Balance Volume indicator, with the addition of four things:
10-SMA
20-SMA
100-SMA
Bollinger Bands
I have found intriguing and surprising results with this indicator.
I often see OBV bouncing off of the Moving Average lines, much like support and resistance points.
More interesting is the fact that it "obeys" the bollinger bands. Often times, if OBV sneaks outside of the Bollinger Band, it will almost always correct and get back in the next day.
I would recommend that you find your own method, and PLEASE post in the comments as to how you use this, but I'll tell you
How I use this indicator:
I usually use this on the daily view. I tend to wait until OBV has moved above the red 20-Day SMA before considering an entry. Below that doesn't show enough positive volume for me to identify enough interest in the security. Once it breaks the red SMA, I'll look at other indicators for confirmation. If price is above the Bollinger Band up above, and my OBV is above Bollinger Band, I will not buy. Also, if MACD is dropping, or if the Stochastic RSI is pegged out in overbought land, I won't buy that either.
If, however, I'm seeing good stuff from Stochastic RSI, RSI, MACD, and price BB, then I'll take a long entry at that OBV + 20SMA crossover.
If I'm in a long position and I see a few signals like the OBV is above the BB, and price is above BB, and StochRSI or RSI are in/near overbought land, I'll often sell that day, expecting a pullback on price.
I really like this one, it's been quite helpful in my trading. This is my first venture into using Volume for trading, and it's been good so far.
Leave me a note in the comments to tell me how it goes and how you use this thing!
Build A BotThis is the Robot we built during the 60 Minute Build-A-Bot webinar on September 12, 2018. We had a great time, and a lot of participation and the best part was that we finished up this robot and even ran a backtest in exactly 60 minutes! We built this robot based on recommendations and suggestions from those who were attending live. Lots of pieces in this robot, but you can always tinker with it, remove stuff, add things, whatever you want!
This version uses the CCI as a trigger for trade entry. The other version uses the Hull Moving Average as a trigger for trade entry.
Hoffman A/D BreakoutStudy based on Rob Hoffman's Accumulation/Distribution Breakout strategy.
- Green circle on the top wick indicates a "Distribution" wick
- Red circle on the bottom wick indicates an "Accumulation" wick
- A distribution wick in an uptrend gets marked as a Key Resistance. This is marked with green crosses
- An Accumulation wick in a downtrend gets marked as a Key Support. This is marked with red crosses
- Breaking above the Key Resistance indicates a buy entry. This is marked by a green background.
- Breaking below the Key Support indicates a sell entry. This is marked by a red background
Understanding contract sizes in a strategyThis simple strat fires up on green bars, down on red bars. cannot get any simpler. So, it's a good example to check how returns are calculated.
First, the internal firing mechanism for the strategy.entry function is something hardcore. As result, the entry points can be confusing, and seem to appear in a wrong bar (as the 2nd and 3rd signals are good examples), but i'll put that aside to keep it simple. And, because i don't yet get it myself ;)
The example is simple, so that numbers can be followed easy. Chart in BTC/USD, so USD is the "base" currency used by strat to calculate. A contract/unit is the value of 1 unit in base currency. 1 Apple share is 600$, 1 bitcoin is 600$, 1 oz gold is 1330 bucks. So, here in each bar, the value of 1 contract is the value of the BTC in USD. simple as that.
The strat properties, can be passed as input fields (line 2) or accessed/changed in the right click->properties pop-up. To make it easier, initial capital is 1000 bucks, and "order size" is 1 contract. This means that the strat will open a position of 1 BTC when it fires. Value "Initial capital" makes no difference at all, at least with these choices. It's just for show. Try to put 1$ and 1 contract, the strat will still trade anyway. It manages to trade 1 contract(or BTC) values at ~600$, with a single dollar. nice ;)
Check the chart. see the little blue "BarUp +1" ? that's it, strat goes long 1 BTC. there's a little blue triangle on the bar, points to the value of entry.
Then later, on second move, the "BarDn -2", the strat goes short 2BTC. 1BTC to close the long +1 more to open a short.
The profit here is the difference between the value of the long opening and the long closing. The extra BTC (shorted) is part of the next position. Since this dumb strat just reverses the direction, there are always +2, -2 , +2.... 1 to close previous position, 1 to open another. At the strategy tester tab, the option "list of trades" shows in details each of the moves
Checking each move and comparing what we see with the chart itself helps to achieve ilumination :)
Bonus feature: as soon as you get it, try to increase the option "pyramiding" and see how the strat adds more contracts, and how it reverses the positions. sometimes it even makes sense!!!! :)
Ichimoku-Hausky_v2.1Made a little update to my trading system. This system is made so that you can easily follow the trend and know when to get out. You still have to know basic market structure to find a good entry.
NB!! I see that i placed the entry wrong on the example, you have too wait for the EMA to go below the MA :)
I have posted the right one at the bottom.
Take profit can be set at last low or you can use trail stop on the EMA, MA, Kijun-sen or Tenkan-sen.
Example rules:
Buy:
IF Market is in a trend or are possibly close to break out of range
THEN see if price has closed above cloud
IF price has closed above cloud
THEN see if EMA has crossed above MA
IF EMA has crossed above MA
THEN buy or wait for pullback
Sell:
IF Market is in a trend or are possibly close to break out of range
THEN see if price has closed below cloud
IF price has closed below cloud
THEN see if EMA has crossed below MA
IF EMA has crossed below MA
THEN buy or wait for pullback
Vervoort Heiken-Ashi LongTerm Candlestick Oscillator [LazyBear]HACOLT (Heikin Ashi Candles Oscillator Long Term) is a technical indicator designed by Sylvain Vervoort. It is based on Mr.Vervoort's other indicator, HACO (Heikin-Ashi Candles Oscillator - posted here: ).
Optimized for long-term trading, HACOLT shows three levels: -1, 0 and 1. These levels suggest "an open short position", "no open position", and "an open long position", respectively. Passing from a certain level to another is viewed as a trading signal:
- Rising from -1 or 0 to 1 suggests a Long Entry and Short exit;
- Falling from 1 to 0 or -1 suggests a Long Exit;
- Falling from 1 or 0 to -1 indicates a Short Entry.
Fits in nicely with any trading setup as a confirmation indicator
More info:
- tlc.thinkorswim.com
- www.motivewave.com
List of my other indicators:
- GDoc: docs.google.com
- Chart:
Milvetti_Pineconnector_LibraryLibrary "Milvetti_Pineconnector_Library"
This library has methods that provide practical signal transmission for Pineconnector.Developed By Milvetti
buy(licenseId, symbol, risk, sl, tp, beTrigger, beOffset, trailTrig, trailDist, trailStep, atrTimeframe, atrTrigger, atrPeriod, atrMultiplier, atrShift, spread, accFilter, secret, comment)
Create a buy order message
Parameters:
licenseId (string) : License Id. This is a unique identifier found in the Pineconnector Licensing Dashboard.
symbol (string) : Symbol. Default is syminfo.ticker
risk (float) : Risk. Function depends on the “Volume Type” selected in the EA
sl (float) : StopLoss. Place stop-loss. Computation is based on the Target Type selected in the EA. Default is 0(inactive)
tp (float) : TakeProfit. Place take-profit. Computation is based on the Target Type selected in the EA. Default is 0(inactive)
beTrigger (float) : Breakeven will be activated after the position gains this number of pips. Ensure > 0
beOffset (float) : Offset from entry price. 0 means the SL will be placed exactly at entry price. 1 means 1 pip above the entry price for buy trades and 1 pip below for sell trades.
trailTrig (int) : Trailing stop-loss will be activated after a trade gains this number of pips. Default is 0(inactive)
trailDist (int) : SL will be opened at traildist after trailtrig is met, even if you do not have a SL placed.. Default is 0(inactive)
trailStep (int) : Moves trailing stop-loss once price moves to favourable by a specified number of pips. Default is 0(inactive)
atrTimeframe (string) : ATR Trailing Stop will be based on the specified timeframe in minutes and will only update once per bar close. Default is Timeframe.Period
atrTrigger (float) : Activate the trigger of ATR Trailing after market moves favourably by a number of pips. Default is 0(inactive)
atrPeriod (int) : ATR averaging period. Default is 0
atrMultiplier (float) : Multiple of ATR to utilise in the new SL computation. Default is 1
atrShift (float) : Relative shift of price information, 0 uses latest candle, 1 uses second last, etc. Default is 0
spread (float) : Enter the position only if the spread is equal or less than the specified value in pips. Default is 0(inactive)
accFilter (float) : Enter the position only if the account requirement is met. Default is 0(inactive)
secret (string)
comment (string) : Comment. Add a string into the order’s comment section. Default is "Symbol+Timeframe"
sell(licenseId, symbol, risk, sl, tp, beTrigger, beOffset, trailTrig, trailDist, trailStep, atrTimeframe, atrTrigger, atrPeriod, atrMultiplier, atrShift, spread, accFilter, secret, comment)
Create a buy order message
Parameters:
licenseId (string) : License Id. This is a unique identifier found in the Pineconnector Licensing Dashboard.
symbol (string) : Symbol. Default is syminfo.ticker
risk (float) : Risk. Function depends on the “Volume Type” selected in the EA
sl (float) : StopLoss. Place stop-loss. Computation is based on the Target Type selected in the EA. Default is 0(inactive)
tp (float) : TakeProfit. Place take-profit. Computation is based on the Target Type selected in the EA. Default is 0(inactive)
beTrigger (float) : Breakeven will be activated after the position gains this number of pips. Ensure > 0
beOffset (float) : Offset from entry price. 0 means the SL will be placed exactly at entry price. 1 means 1 pip above the entry price for buy trades and 1 pip below for sell trades.
trailTrig (int) : Trailing stop-loss will be activated after a trade gains this number of pips. Default is 0(inactive)
trailDist (int) : SL will be opened at traildist after trailtrig is met, even if you do not have a SL placed.. Default is 0(inactive)
trailStep (int) : Moves trailing stop-loss once price moves to favourable by a specified number of pips. Default is 0(inactive)
atrTimeframe (string) : ATR Trailing Stop will be based on the specified timeframe in minutes and will only update once per bar close. Default is Timeframe.Period
atrTrigger (float) : Activate the trigger of ATR Trailing after market moves favourably by a number of pips. Default is 0(inactive)
atrPeriod (int) : ATR averaging period. Default is 0
atrMultiplier (float) : Multiple of ATR to utilise in the new SL computation. Default is 1
atrShift (float) : Relative shift of price information, 0 uses latest candle, 1 uses second last, etc. Default is 0
spread (float) : Enter the position only if the spread is equal or less than the specified value in pips. Default is 0(inactive)
accFilter (float) : Enter the position only if the account requirement is met. Default is 0(inactive)
secret (string)
comment (string) : Comment. Add a string into the order’s comment section. Default is "Symbol+Timeframe"
buyLimit(licenseId, symbol, pending, risk, sl, tp, beTrigger, beOffset, trailTrig, trailDist, trailStep, atrTimeframe, atrTrigger, atrPeriod, atrMultiplier, atrShift, spread, accFilter, secret, comment)
Create a buy limit order message
Parameters:
licenseId (string) : License Id. This is a unique identifier found in the Pineconnector Licensing Dashboard.
symbol (string) : Symbol. Default is syminfo.ticker
pending (float) : Computing pending order entry price. EA Options: Pips, Specified Price, Percentage
risk (float) : Risk. Function depends on the “Volume Type” selected in the EA
sl (float) : StopLoss. Place stop-loss. Computation is based on the Target Type selected in the EA. Default is 0(inactive)
tp (float) : TakeProfit. Place take-profit. Computation is based on the Target Type selected in the EA. Default is 0(inactive)
beTrigger (float) : Breakeven will be activated after the position gains this number of pips. Ensure > 0
beOffset (float) : Offset from entry price. 0 means the SL will be placed exactly at entry price. 1 means 1 pip above the entry price for buy trades and 1 pip below for sell trades.
trailTrig (int) : Trailing stop-loss will be activated after a trade gains this number of pips. Default is 0(inactive)
trailDist (int) : SL will be opened at traildist after trailtrig is met, even if you do not have a SL placed.. Default is 0(inactive)
trailStep (int) : Moves trailing stop-loss once price moves to favourable by a specified number of pips. Default is 0(inactive)
atrTimeframe (string) : ATR Trailing Stop will be based on the specified timeframe in minutes and will only update once per bar close. Default is Timeframe.Period
atrTrigger (float) : Activate the trigger of ATR Trailing after market moves favourably by a number of pips. Default is 0(inactive)
atrPeriod (int) : ATR averaging period. Default is 0
atrMultiplier (float) : Multiple of ATR to utilise in the new SL computation. Default is 1
atrShift (float) : Relative shift of price information, 0 uses latest candle, 1 uses second last, etc. Default is 0
spread (float) : Enter the position only if the spread is equal or less than the specified value in pips. Default is 0(inactive)
accFilter (float) : Enter the position only if the account requirement is met. Default is 0(inactive)
secret (string)
comment (string) : Comment. Add a string into the order’s comment section. Default is "Symbol+Timeframe"
buyStop(licenseId, symbol, pending, risk, sl, tp, beTrigger, beOffset, trailTrig, trailDist, trailStep, atrTimeframe, atrTrigger, atrPeriod, atrMultiplier, atrShift, spread, accFilter, secret, comment)
Create a buy stop order message
Parameters:
licenseId (string) : License Id. This is a unique identifier found in the Pineconnector Licensing Dashboard.
symbol (string) : Symbol. Default is syminfo.ticker
pending (float) : Computing pending order entry price. EA Options: Pips, Specified Price, Percentage
risk (float) : Risk. Function depends on the “Volume Type” selected in the EA
sl (float) : StopLoss. Place stop-loss. Computation is based on the Target Type selected in the EA. Default is 0(inactive)
tp (float) : TakeProfit. Place take-profit. Computation is based on the Target Type selected in the EA. Default is 0(inactive)
beTrigger (float) : Breakeven will be activated after the position gains this number of pips. Ensure > 0
beOffset (float) : Offset from entry price. 0 means the SL will be placed exactly at entry price. 1 means 1 pip above the entry price for buy trades and 1 pip below for sell trades.
trailTrig (int) : Trailing stop-loss will be activated after a trade gains this number of pips. Default is 0(inactive)
trailDist (int) : SL will be opened at traildist after trailtrig is met, even if you do not have a SL placed.. Default is 0(inactive)
trailStep (int) : Moves trailing stop-loss once price moves to favourable by a specified number of pips. Default is 0(inactive)
atrTimeframe (string) : ATR Trailing Stop will be based on the specified timeframe in minutes and will only update once per bar close. Default is Timeframe.Period
atrTrigger (float) : Activate the trigger of ATR Trailing after market moves favourably by a number of pips. Default is 0(inactive)
atrPeriod (int) : ATR averaging period. Default is 0
atrMultiplier (float) : Multiple of ATR to utilise in the new SL computation. Default is 1
atrShift (float) : Relative shift of price information, 0 uses latest candle, 1 uses second last, etc. Default is 0
spread (float) : Enter the position only if the spread is equal or less than the specified value in pips. Default is 0(inactive)
accFilter (float) : Enter the position only if the account requirement is met. Default is 0(inactive)
secret (string)
comment (string) : Comment. Add a string into the order’s comment section. Default is "Symbol+Timeframe"
sellLimit(licenseId, symbol, pending, risk, sl, tp, beTrigger, beOffset, trailTrig, trailDist, trailStep, atrTimeframe, atrTrigger, atrPeriod, atrMultiplier, atrShift, spread, accFilter, secret, comment)
Create a sell limit order message
Parameters:
licenseId (string) : License Id. This is a unique identifier found in the Pineconnector Licensing Dashboard.
symbol (string) : Symbol. Default is syminfo.ticker
pending (float) : Computing pending order entry price. EA Options: Pips, Specified Price, Percentage
risk (float) : Risk. Function depends on the “Volume Type” selected in the EA
sl (float) : StopLoss. Place stop-loss. Computation is based on the Target Type selected in the EA. Default is 0(inactive)
tp (float) : TakeProfit. Place take-profit. Computation is based on the Target Type selected in the EA. Default is 0(inactive)
beTrigger (float) : Breakeven will be activated after the position gains this number of pips. Ensure > 0
beOffset (float) : Offset from entry price. 0 means the SL will be placed exactly at entry price. 1 means 1 pip above the entry price for buy trades and 1 pip below for sell trades.
trailTrig (int) : Trailing stop-loss will be activated after a trade gains this number of pips. Default is 0(inactive)
trailDist (int) : SL will be opened at traildist after trailtrig is met, even if you do not have a SL placed.. Default is 0(inactive)
trailStep (int) : Moves trailing stop-loss once price moves to favourable by a specified number of pips. Default is 0(inactive)
atrTimeframe (string) : ATR Trailing Stop will be based on the specified timeframe in minutes and will only update once per bar close. Default is Timeframe.Period
atrTrigger (float) : Activate the trigger of ATR Trailing after market moves favourably by a number of pips. Default is 0(inactive)
atrPeriod (int) : ATR averaging period. Default is 0
atrMultiplier (float) : Multiple of ATR to utilise in the new SL computation. Default is 1
atrShift (float) : Relative shift of price information, 0 uses latest candle, 1 uses second last, etc. Default is 0
spread (float) : Enter the position only if the spread is equal or less than the specified value in pips. Default is 0(inactive)
accFilter (float) : Enter the position only if the account requirement is met. Default is 0(inactive)
secret (string)
comment (string) : Comment. Add a string into the order’s comment section. Default is "Symbol+Timeframe"
sellStop(licenseId, symbol, pending, risk, sl, tp, beTrigger, beOffset, trailTrig, trailDist, trailStep, atrTimeframe, atrTrigger, atrPeriod, atrMultiplier, atrShift, spread, accFilter, secret, comment)
Create a sell stop order message
Parameters:
licenseId (string) : License Id. This is a unique identifier found in the Pineconnector Licensing Dashboard.
symbol (string) : Symbol. Default is syminfo.ticker
pending (float) : Computing pending order entry price. EA Options: Pips, Specified Price, Percentage
risk (float) : Risk. Function depends on the “Volume Type” selected in the EA
sl (float) : StopLoss. Place stop-loss. Computation is based on the Target Type selected in the EA. Default is 0(inactive)
tp (float) : TakeProfit. Place take-profit. Computation is based on the Target Type selected in the EA. Default is 0(inactive)
beTrigger (float) : Breakeven will be activated after the position gains this number of pips. Ensure > 0
beOffset (float) : Offset from entry price. 0 means the SL will be placed exactly at entry price. 1 means 1 pip above the entry price for buy trades and 1 pip below for sell trades.
trailTrig (int) : Trailing stop-loss will be activated after a trade gains this number of pips. Default is 0(inactive)
trailDist (int) : SL will be opened at traildist after trailtrig is met, even if you do not have a SL placed.. Default is 0(inactive)
trailStep (int) : Moves trailing stop-loss once price moves to favourable by a specified number of pips. Default is 0(inactive)
atrTimeframe (string) : ATR Trailing Stop will be based on the specified timeframe in minutes and will only update once per bar close. Default is Timeframe.Period
atrTrigger (float) : Activate the trigger of ATR Trailing after market moves favourably by a number of pips. Default is 0(inactive)
atrPeriod (int) : ATR averaging period. Default is 0
atrMultiplier (float) : Multiple of ATR to utilise in the new SL computation. Default is 1
atrShift (float) : Relative shift of price information, 0 uses latest candle, 1 uses second last, etc. Default is 0
spread (float) : Enter the position only if the spread is equal or less than the specified value in pips. Default is 0(inactive)
accFilter (float) : Enter the position only if the account requirement is met. Default is 0(inactive)
secret (string)
comment (string) : Comment. Add a string into the order’s comment section. Default is "Symbol+Timeframe"
Fibonacci ATR Fusion - Strategy [presentTrading]Open-script again! This time is also an ATR-related strategy. Enjoy! :)
If you have any questions, let me know, and I'll help make this as effective as possible.
█ Introduction and How It Is Different
The Fibonacci ATR Fusion Strategy is an advanced trading approach that uniquely integrates Fibonacci-based weighted averages with the Average True Range (ATR) to identify and capitalize on significant market trends.
Unlike traditional strategies that rely on single indicators or static parameters, this method combines multiple timeframes and dynamic volatility measurements to enhance precision and adaptability. Additionally, it features a 4-step Take Profit (TP) mechanism, allowing for systematic profit-taking at various levels, which optimizes both risk management and return potential in long and short market positions.
BTCUSD 6hr Performance
█ Strategy, How It Works: Detailed Explanation
The Fibonacci ATR Fusion Strategy utilizes a combination of technical indicators and weighted averages to determine optimal entry and exit points. Below is a breakdown of its key components and operational logic.
🔶 1. Enhanced True Range Calculation
The strategy begins by calculating the True Range (TR) to measure market volatility accurately.
TR = max(High - Low, abs(High - Previous Close), abs(Low - Previous Close))
High and Low: Highest and lowest prices of the current trading period.
Previous Close: Closing price of the preceding trading period.
max: Selects the largest value among the three calculations to account for gaps and limit movements.
🔶 2. Buying Pressure (BP) Calculation
Buying Pressure (BP) quantifies the extent to which buyers are driving the price upwards within a period.
BP = Close - True Low
Close: Current period's closing price.
True Low: The lower boundary determined in the True Range calculation.
🔶 3. Ratio Calculation for Different Periods
To assess the strength of buying pressure relative to volatility, the strategy calculates a ratio over various Fibonacci-based timeframes.
Ratio = 100 * (Sum of BP over n periods) / (Sum of TR over n periods)
n: Length of the period (e.g., 8, 13, 21, 34, 55).
Sum of BP: Cumulative Buying Pressure over n periods.
Sum of TR: Cumulative True Range over n periods.
This ratio normalizes buying pressure, making it comparable across different timeframes.
🔶 4. Weighted Average Calculation
The strategy employs a weighted average of ratios from multiple Fibonacci-based periods to smooth out signals and enhance trend detection.
Weighted Avg = (w1 * Ratio_p1 + w2 * Ratio_p2 + w3 * Ratio_p3 + w4 * Ratio_p4 + Ratio_p5) / (w1 + w2 + w3 + w4 + 1)
w1, w2, w3, w4: Weights assigned to each ratio period.
Ratio_p1 to Ratio_p5: Ratios calculated for periods p1 to p5 (e.g., 8, 13, 21, 34, 55).
This weighted approach emphasizes shorter periods more heavily, capturing recent market dynamics while still considering longer-term trends.
🔶 5. Simple Moving Average (SMA) of Weighted Average
To further smooth the weighted average and reduce noise, a Simple Moving Average (SMA) is applied.
Weighted Avg SMA = SMA(Weighted Avg, m)
- m: SMA period (e.g., 3).
This smoothed line serves as the primary signal generator for trade entries and exits.
🔶 6. Trading Condition Thresholds
The strategy defines specific threshold values to determine optimal entry and exit points based on crossovers and crossunders of the SMA.
Long Condition = Crossover(Weighted Avg SMA, Long Entry Threshold)
Short Condition = Crossunder(Weighted Avg SMA, Short Entry Threshold)
Long Exit = Crossunder(Weighted Avg SMA, Long Exit Threshold)
Short Exit = Crossover(Weighted Avg SMA, Short Exit Threshold)
Long Entry Threshold (T_LE): Level at which a long position is triggered.
Short Entry Threshold (T_SE): Level at which a short position is triggered.
Long Exit Threshold (T_LX): Level at which a long position is exited.
Short Exit Threshold (T_SX): Level at which a short position is exited.
These conditions ensure that trades are only executed when clear trends are identified, enhancing the strategy's reliability.
Previous local performance
🔶 7. ATR-Based Take Profit Mechanism
When enabled, the strategy employs a 4-step Take Profit system to systematically secure profits as the trade moves in the desired direction.
TP Price_1 Long = Entry Price + (TP1ATR * ATR Value)
TP Price_2 Long = Entry Price + (TP2ATR * ATR Value)
TP Price_3 Long = Entry Price + (TP3ATR * ATR Value)
TP Price_1 Short = Entry Price - (TP1ATR * ATR Value)
TP Price_2 Short = Entry Price - (TP2ATR * ATR Value)
TP Price_3 Short = Entry Price - (TP3ATR * ATR Value)
- ATR Value: Calculated using ATR over a specified period (e.g., 14).
- TPxATR: User-defined multipliers for each take profit level.
- TPx_percent: Percentage of the position to exit at each TP level.
This multi-tiered exit strategy allows for partial position closures, optimizing profit capture while maintaining exposure to potential further gains.
█ Trade Direction
The Fibonacci ATR Fusion Strategy is designed to operate in both long and short market conditions, providing flexibility to traders in varying market environments.
Long Trades: Initiated when the SMA of the weighted average crosses above the Long Entry Threshold (T_LE), indicating strong upward momentum.
Short Trades: Initiated when the SMA of the weighted average crosses below the Short Entry Threshold (T_SE), signaling robust downward momentum.
Additionally, the strategy can be configured to trade exclusively in one direction—Long, Short, or Both—based on the trader’s preference and market analysis.
█ Usage
Implementing the Fibonacci ATR Fusion Strategy involves several steps to ensure it aligns with your trading objectives and market conditions.
1. Configure Strategy Parameters:
- Trading Direction: Choose between Long, Short, or Both based on your market outlook.
- Trading Condition Thresholds: Set the Long Entry, Short Entry, Long Exit, and Short Exit thresholds to define when to enter and exit trades.
2. Set Take Profit Levels (if enabled):
- ATR Multipliers: Define how many ATRs away from the entry price each take profit level is set.
- Take Profit Percentages: Allocate what percentage of the position to close at each TP level.
3. Apply to Desired Chart:
- Add the strategy to the chart of the asset you wish to trade.
- Observe the plotted Fibonacci ATR and SMA Fibonacci ATR indicators for visual confirmation.
4. Monitor and Adjust:
- Regularly review the strategy’s performance through backtesting.
- Adjust the input parameters based on historical performance and changing market dynamics.
5. Risk Management:
- Ensure that the sum of take profit percentages does not exceed 100% to avoid over-closing positions.
- Utilize the ATR-based TP levels to adapt to varying market volatilities, maintaining a balanced risk-reward ratio.
█ Default Settings
Understanding the default settings is crucial for optimizing the Fibonacci ATR Fusion Strategy's performance. Here's a precise and simple overview of the key parameters and their effects:
🔶 Key Parameters and Their Effects
1. Trading Direction (`tradingDirection`)
- Default: Both
- Effect: Determines whether the strategy takes both long and short positions or restricts to one direction. Selecting Both allows maximum flexibility, while Long or Short can be used for directional bias.
2. Trading Condition Thresholds
Long Entry (long_entry_threshold = 58.0): Higher values reduce false positives but may miss trades.
Short Entry (short_entry_threshold = 42.0): Lower values capture early short trends but may increase false signals.
Long Exit (long_exit_threshold = 42.0): Exits long positions early, securing profits but potentially cutting trends short.
Short Exit (short_exit_threshold = 58.0): Delays short exits to capture favorable movements, avoiding premature exits.
3. Take Profit Configuration (`useTakeProfit` = false)
- Effect: When enabled, the strategy employs a 4-step TP mechanism to secure profits at multiple levels. By default, it is disabled to allow users to opt-in based on their trading style.
4. ATR-Based Take Profit Multipliers
TP1 (tp1ATR = 3.0): Sets the first TP at 3 ATRs for initial profit capture.
TP2 (tp2ATR = 8.0): Targets larger trends, though less likely to be reached.
TP3 (tp3ATR = 14.0): Optimizes for extreme price moves, seldom triggered.
5. Take Profit Percentages
TP Level 1 (tp1_percent = 12%): Secures 12% at the first TP.
TP Level 2 (tp2_percent = 12%): Exits another 12% at the second TP.
TP Level 3 (tp3_percent = 12%): Closes an additional 12% at the third TP.
6. Weighted Average Parameters
Ratio Periods: Fibonacci-based intervals (8, 13, 21, 34, 55) balance responsiveness.
Weights: Emphasizes recent data for timely responses to market trends.
SMA Period (weighted_avg_sma_period = 3): Smoothens data with minimal lag, balancing noise reduction and responsiveness.
7. ATR Period (`atrPeriod` = 14)
Effect: Sets the ATR calculation length, impacting TP sensitivity to volatility.
🔶 Impact on Performance
- Sensitivity and Responsiveness:
- Shorter Ratio Periods and Higher Weights: Make the weighted average more responsive to recent price changes, allowing quicker trade entries and exits but increasing the likelihood of false signals.
- Longer Ratio Periods and Lower Weights: Provide smoother signals with fewer false positives but may delay trade entries, potentially missing out on significant price moves.
- Profit Taking:
- ATR Multipliers: Higher multipliers set take profit levels further away, targeting larger price movements but reducing the probability of reaching these levels.
- Fixed Percentages: Allocating equal percentages at each TP level ensures consistent profit realization and risk management, preventing overexposure.
- Trade Direction Control:
- Selecting Specific Directions: Restricting trades to Long or Short can align the strategy with market trends or personal biases, potentially enhancing performance in trending markets.
- Risk Management:
- Take Profit Percentages: Dividing the position into smaller percentages at multiple TP levels helps lock in profits progressively, reducing risk and allowing the remaining position to ride further trends.
- Market Adaptability:
- Weighted Averages and ATR: By combining multiple timeframes and adjusting to volatility, the strategy adapts to different market conditions, maintaining effectiveness across various asset classes and timeframes.
---
If you want to know more about ATR, can also check "SuperATR 7-Step Profit".
Enjoy trading.
Trading IQ - ICT LibraryLibrary "ICTlibrary"
Used to calculate various ICT related price levels and strategies. An ongoing project.
Hello Coders!
This library is meant for sourcing ICT related concepts. While some functions might generate more output than you require, you can specify "Lite Mode" as "true" in applicable functions to slim down necessary inputs.
isLastBar(userTF)
Identifies the last bar on the chart before a timeframe change
Parameters:
userTF (simple int) : the timeframe you wish to calculate the last bar for, must be converted to integer using 'timeframe.in_seconds()'
Returns: bool true if bar on chart is last bar of higher TF, dalse if bar on chart is not last bar of higher TF
necessaryData(atrTF)
returns necessaryData UDT for historical data access
Parameters:
atrTF (float) : user-selected timeframe ATR value.
Returns: logZ. log return Z score, used for calculating order blocks.
method gradBoxes(gradientBoxes, idColor, timeStart, bottom, top, rightCoordinate)
creates neon like effect for box drawings
Namespace types: array
Parameters:
gradientBoxes (array) : an array.new() to store the gradient boxes
idColor (color)
timeStart (int) : left point of box
bottom (float) : bottom of box price point
top (float) : top of box price point
rightCoordinate (int) : right point of box
Returns: void
checkIfTraded(tradeName)
checks if recent trade is of specific name
Parameters:
tradeName (string)
Returns: bool true if recent trade id matches target name, false otherwise
checkIfClosed(tradeName)
checks if recent closed trade is of specific name
Parameters:
tradeName (string)
Returns: bool true if recent closed trade id matches target name, false otherwise
IQZZ(atrMult, finalTF)
custom ZZ to quickly determine market direction.
Parameters:
atrMult (float) : an atr multiplier used to determine the required price move for a ZZ direction change
finalTF (string) : the timeframe used for the atr calcuation
Returns: dir market direction. Up => 1, down => -1
method drawBos(id, startPoint, getKeyPointTime, getKeyPointPrice, col, showBOS, isUp)
calculates and draws Break Of Structure
Namespace types: array
Parameters:
id (array)
startPoint (chart.point)
getKeyPointTime (int) : the actual time of startPoint, simplystartPoint.time
getKeyPointPrice (float) : the actual time of startPoint, simplystartPoint.price
col (color) : color of the BoS line / label
showBOS (bool) : whether to show label/line. This function still calculates internally for other ICT related concepts even if not drawn.
isUp (bool) : whether BoS happened during price increase or price decrease.
Returns: void
method drawMSS(id, startPoint, getKeyPointTime, getKeyPointPrice, col, showMSS, isUp, upRejections, dnRejections, highArr, lowArr, timeArr, closeArr, openArr, atrTFarr, upRejectionsPrices, dnRejectionsPrices)
calculates and draws Market Structure Shift. This data is also used to calculate Rejection Blocks.
Namespace types: array
Parameters:
id (array)
startPoint (chart.point)
getKeyPointTime (int) : the actual time of startPoint, simplystartPoint.time
getKeyPointPrice (float) : the actual time of startPoint, simplystartPoint.price
col (color) : color of the MSS line / label
showMSS (bool) : whether to show label/line. This function still calculates internally for other ICT related concepts even if not drawn.
isUp (bool) : whether MSS happened during price increase or price decrease.
upRejections (array)
dnRejections (array)
highArr (array) : array containing historical highs, should be taken from the UDT "necessaryData" defined above
lowArr (array) : array containing historical lows, should be taken from the UDT "necessaryData" defined above
timeArr (array) : array containing historical times, should be taken from the UDT "necessaryData" defined above
closeArr (array) : array containing historical closes, should be taken from the UDT "necessaryData" defined above
openArr (array) : array containing historical opens, should be taken from the UDT "necessaryData" defined above
atrTFarr (array) : array containing historical atr values (of user-selected TF), should be taken from the UDT "necessaryData" defined above
upRejectionsPrices (array) : array containing up rejections prices. Is sorted and used to determine selective looping for invalidations.
dnRejectionsPrices (array) : array containing down rejections prices. Is sorted and used to determine selective looping for invalidations.
Returns: void
method getTime(id, compare, timeArr)
gets time of inputted price (compare) in an array of data
this is useful when the user-selected timeframe for ICT concepts is greater than the chart's timeframe
Namespace types: array
Parameters:
id (array) : the array of data to search through, to find which index has the same value as "compare"
compare (float) : the target data point to find in the array
timeArr (array) : array of historical times
Returns: the time that the data point in the array was recorded
method OB(id, highArr, signArr, lowArr, timeArr, sign)
store bullish orderblock data
Namespace types: array
Parameters:
id (array)
highArr (array) : array of historical highs
signArr (array) : array of historical price direction "math.sign(close - open)"
lowArr (array) : array of historical lows
timeArr (array) : array of historical times
sign (int) : orderblock direction, -1 => bullish, 1 => bearish
Returns: void
OTEstrat(OTEstart, future, closeArr, highArr, lowArr, timeArr, longOTEPT, longOTESL, longOTElevel, shortOTEPT, shortOTESL, shortOTElevel, structureDirection, oteLongs, atrTF, oteShorts)
executes the OTE strategy
Parameters:
OTEstart (chart.point)
future (int) : future time point for drawings
closeArr (array) : array of historical closes
highArr (array) : array of historical highs
lowArr (array) : array of historical lows
timeArr (array) : array of historical times
longOTEPT (string) : user-selected long OTE profit target, please create an input.string() for this using the example below
longOTESL (int) : user-selected long OTE stop loss, please create an input.string() for this using the example below
longOTElevel (float) : long entry price of selected retracement ratio for OTE
shortOTEPT (string) : user-selected short OTE profit target, please create an input.string() for this using the example below
shortOTESL (int) : user-selected short OTE stop loss, please create an input.string() for this using the example below
shortOTElevel (float) : short entry price of selected retracement ratio for OTE
structureDirection (string) : current market structure direction, this should be "Up" or "Down". This is used to cancel pending orders if market structure changes
oteLongs (bool) : input.bool() for whether OTE longs can be executed
atrTF (float) : atr of the user-seleceted TF
oteShorts (bool) : input.bool() for whether OTE shorts can be executed
@exampleInputs
oteLongs = input.bool(defval = false, title = "OTE Longs", group = "Optimal Trade Entry")
longOTElevel = input.float(defval = 0.79, title = "Long Entry Retracement Level", options = , group = "Optimal Trade Entry")
longOTEPT = input.string(defval = "-0.5", title = "Long TP", options = , group = "Optimal Trade Entry")
longOTESL = input.int(defval = 0, title = "How Many Ticks Below Swing Low For Stop Loss", group = "Optimal Trade Entry")
oteShorts = input.bool(defval = false, title = "OTE Shorts", group = "Optimal Trade Entry")
shortOTElevel = input.float(defval = 0.79, title = "Short Entry Retracement Level", options = , group = "Optimal Trade Entry")
shortOTEPT = input.string(defval = "-0.5", title = "Short TP", options = , group = "Optimal Trade Entry")
shortOTESL = input.int(defval = 0, title = "How Many Ticks Above Swing Low For Stop Loss", group = "Optimal Trade Entry")
Returns: void (0)
displacement(logZ, atrTFreg, highArr, timeArr, lowArr, upDispShow, dnDispShow, masterCoords, labelLevels, dispUpcol, rightCoordinate, dispDncol, noBorders)
calculates and draws dispacements
Parameters:
logZ (float) : log return of current price, used to determine a "significant price move" for a displacement
atrTFreg (float) : atr of user-seleceted timeframe
highArr (array) : array of historical highs
timeArr (array) : array of historical times
lowArr (array) : array of historical lows
upDispShow (int) : amount of historical upside displacements to show
dnDispShow (int) : amount of historical downside displacements to show
masterCoords (map) : a map to push the most recent displacement prices into, useful for having key levels in one data structure
labelLevels (string) : used to determine label placement for the displacement, can be inside box, outside box, or none, example below
dispUpcol (color) : upside displacement color
rightCoordinate (int) : future time for displacement drawing, best is "last_bar_time"
dispDncol (color) : downside displacement color
noBorders (bool) : input.bool() to remove box borders, example below
@exampleInputs
labelLevels = input.string(defval = "Inside" , title = "Box Label Placement", options = )
noBorders = input.bool(defval = false, title = "No Borders On Levels")
Returns: void
method getStrongLow(id, startIndex, timeArr, lowArr, strongLowPoints)
unshift strong low data to array id
Namespace types: array
Parameters:
id (array)
startIndex (int) : the starting index for the timeArr array of the UDT "necessaryData".
this point should start from at least 1 pivot prior to find the low before an upside BoS
timeArr (array) : array of historical times
lowArr (array) : array of historical lows
strongLowPoints (array) : array of strong low prices. Used to retrieve highest strong low price and see if need for
removal of invalidated strong lows
Returns: void
method getStrongHigh(id, startIndex, timeArr, highArr, strongHighPoints)
unshift strong high data to array id
Namespace types: array
Parameters:
id (array)
startIndex (int) : the starting index for the timeArr array of the UDT "necessaryData".
this point should start from at least 1 pivot prior to find the high before a downside BoS
timeArr (array) : array of historical times
highArr (array) : array of historical highs
strongHighPoints (array)
Returns: void
equalLevels(highArr, lowArr, timeArr, rightCoordinate, equalHighsCol, equalLowsCol, liteMode)
used to calculate recent equal highs or equal lows
Parameters:
highArr (array) : array of historical highs
lowArr (array) : array of historical lows
timeArr (array) : array of historical times
rightCoordinate (int) : a future time (right for boxes, x2 for lines)
equalHighsCol (color) : user-selected color for equal highs drawings
equalLowsCol (color) : user-selected color for equal lows drawings
liteMode (bool) : optional for a lite mode version of an ICT strategy. For more control over drawings leave as "True", "False" will apply neon effects
Returns: void
quickTime(timeString)
used to quickly determine if a user-inputted time range is currently active in NYT time
Parameters:
timeString (string) : a time range
Returns: true if session is active, false if session is inactive
macros(showMacros, noBorders)
used to calculate and draw session macros
Parameters:
showMacros (bool) : an input.bool() or simple bool to determine whether to activate the function
noBorders (bool) : an input.bool() to determine whether the box anchored to the session should have borders
Returns: void
po3(tf, left, right, show)
use to calculate HTF po3 candle
@tip only call this function on "barstate.islast"
Parameters:
tf (simple string)
left (int) : the left point of the candle, calculated as bar_index + left,
right (int) : :the right point of the candle, calculated as bar_index + right,
show (bool) : input.bool() whether to show the po3 candle or not
Returns: void
silverBullet(silverBulletStratLong, silverBulletStratShort, future, userTF, H, L, H2, L2, noBorders, silverBulletLongTP, historicalPoints, historicalData, silverBulletLongSL, silverBulletShortTP, silverBulletShortSL)
used to execute the Silver Bullet Strategy
Parameters:
silverBulletStratLong (simple bool)
silverBulletStratShort (simple bool)
future (int) : a future time, used for drawings, example "last_bar_time"
userTF (simple int)
H (float) : the high price of the user-selected TF
L (float) : the low price of the user-selected TF
H2 (float) : the high price of the user-selected TF
L2 (float) : the low price of the user-selected TF
noBorders (bool) : an input.bool() used to remove the borders from box drawings
silverBulletLongTP (series silverBulletLevels)
historicalPoints (array)
historicalData (necessaryData)
silverBulletLongSL (series silverBulletLevels)
silverBulletShortTP (series silverBulletLevels)
silverBulletShortSL (series silverBulletLevels)
Returns: void
method invalidFVGcheck(FVGarr, upFVGpricesSorted, dnFVGpricesSorted)
check if existing FVGs are still valid
Namespace types: array
Parameters:
FVGarr (array)
upFVGpricesSorted (array) : an array of bullish FVG prices, used to selective search through FVG array to remove invalidated levels
dnFVGpricesSorted (array) : an array of bearish FVG prices, used to selective search through FVG array to remove invalidated levels
Returns: void (0)
method drawFVG(counter, FVGshow, FVGname, FVGcol, data, masterCoords, labelLevels, borderTransp, liteMode, rightCoordinate)
draws FVGs on last bar
Namespace types: map
Parameters:
counter (map) : a counter, as map, keeping count of the number of FVGs drawn, makes sure that there aren't more FVGs drawn
than int FVGshow
FVGshow (int) : the number of FVGs to show. There should be a bullish FVG show and bearish FVG show. This function "drawFVG" is used separately
for bearish FVG and bullish FVG.
FVGname (string) : the name of the FVG, "FVG Up" or "FVG Down"
FVGcol (color) : desired FVG color
data (FVG)
masterCoords (map) : a map containing the names and price points of key levels. Used to define price ranges.
labelLevels (string) : an input.string with options "Inside", "Outside", "Remove". Determines whether FVG labels should be inside box, outside,
or na.
borderTransp (int)
liteMode (bool)
rightCoordinate (int) : the right coordinate of any drawings. Must be a time point.
Returns: void
invalidBlockCheck(bullishOBbox, bearishOBbox, userTF)
check if existing order blocks are still valid
Parameters:
bullishOBbox (array) : an array declared using the UDT orderBlock that contains bullish order block related data
bearishOBbox (array) : an array declared using the UDT orderBlock that contains bearish order block related data
userTF (simple int)
Returns: void (0)
method lastBarRejections(id, rejectionColor, idShow, rejectionString, labelLevels, borderTransp, liteMode, rightCoordinate, masterCoords)
draws rejectionBlocks on last bar
Namespace types: array
Parameters:
id (array) : the array, an array of rejection block data declared using the UDT rejection block
rejectionColor (color) : the desired color of the rejection box
idShow (int)
rejectionString (string) : the desired name of the rejection blocks
labelLevels (string) : an input.string() to determine if labels for the block should be inside the box, outside, or none.
borderTransp (int)
liteMode (bool) : an input.bool(). True = neon effect, false = no neon.
rightCoordinate (int) : atime for the right coordinate of the box
masterCoords (map) : a map that stores the price of key levels and assigns them a name, used to determine price ranges
Returns: void
method OBdraw(id, OBshow, BBshow, OBcol, BBcol, bullishString, bearishString, isBullish, labelLevels, borderTransp, liteMode, rightCoordinate, masterCoords)
draws orderblocks and breaker blocks for data stored in UDT array()
Namespace types: array
Parameters:
id (array) : the array, an array of order block data declared using the UDT orderblock
OBshow (int) : the number of order blocks to show
BBshow (int) : the number of breaker blocks to show
OBcol (color) : color of order blocks
BBcol (color) : color of breaker blocks
bullishString (string) : the title of bullish blocks, which is a regular bullish orderblock or a bearish orderblock that's converted to breakerblock
bearishString (string) : the title of bearish blocks, which is a regular bearish orderblock or a bullish orderblock that's converted to breakerblock
isBullish (bool) : whether the array contains bullish orderblocks or bearish orderblocks. If bullish orderblocks,
the array will naturally contain bearish BB, and if bearish OB, the array will naturally contain bullish BB
labelLevels (string) : an input.string() to determine if labels for the block should be inside the box, outside, or none.
borderTransp (int)
liteMode (bool) : an input.bool(). True = neon effect, false = no neon.
rightCoordinate (int) : atime for the right coordinate of the box
masterCoords (map) : a map that stores the price of key levels and assigns them a name, used to determine price ranges
Returns: void
FVG
UDT for FVG calcualtions
Fields:
H (series float) : high price of user-selected timeframe
L (series float) : low price of user-selected timeframe
direction (series string) : FVG direction => "Up" or "Down"
T (series int) : => time of bar on user-selected timeframe where FVG was created
fvgLabel (series label) : optional label for FVG
fvgLineTop (series line) : optional line for top of FVG
fvgLineBot (series line) : optional line for bottom of FVG
fvgBox (series box) : optional box for FVG
labelLine
quickly pair a line and label together as UDT
Fields:
lin (series line) : Line you wish to pair with label
lab (series label) : Label you wish to pair with line
orderBlock
UDT for order block calculations
Fields:
orderBlockData (array) : array containing order block x and y points
orderBlockBox (series box) : optional order block box
vioCount (series int) : = 0 violation count of the order block. 0 = Order Block, 1 = Breaker Block
traded (series bool)
status (series string) : = "OB" status == "OB" => Level is order block. status == "BB" => Level is breaker block.
orderBlockLab (series label) : options label for the order block / breaker block.
strongPoints
UDT for strong highs and strong lows
Fields:
price (series float) : price of the strong high or strong low
timeAtprice (series int) : time of the strong high or strong low
strongPointLabel (series label) : optional label for strong point
strongPointLine (series line) : optional line for strong point
overlayLine (series line) : optional lines for strong point to enhance visibility
overlayLine2 (series line) : optional lines for strong point to enhance visibility
displacement
UDT for dispacements
Fields:
highPrice (series float) : high price of displacement
lowPrice (series float) : low price of displacement
timeAtPrice (series int) : time of bar where displacement occurred
displacementBox (series box) : optional box to draw displacement
displacementLab (series label) : optional label for displacement
po3data
UDT for po3 calculations
Fields:
dHigh (series float) : higher timeframe high price
dLow (series float) : higher timeframe low price
dOpen (series float) : higher timeframe open price
dClose (series float) : higher timeframe close price
po3box (series box) : box to draw po3 candle body
po3line (array) : line array to draw po3 wicks
po3Labels (array) : label array to label price points of po3 candle
macros
UDT for session macros
Fields:
sessions (array) : Array of sessions, you can populate this array using the "quickTime" function located above "export macros".
prices (matrix) : Matrix of session data -> open, high, low, close, time
sessionTimes (array) : Array of session names. Pairs with array sessions.
sessionLines (matrix) : Optional array for sesion drawings.
OTEtimes
UDT for data storage and drawings associated with OTE strategy
Fields:
upTimes (array) : time of highest point before trade is taken
dnTimes (array) : time of lowest point before trade is taken
tpLineLong (series line) : line to mark tp level long
tpLabelLong (series label) : label to mark tp level long
slLineLong (series line) : line to mark sl level long
slLabelLong (series label) : label to mark sl level long
tpLineShort (series line) : line to mark tp level short
tpLabelShort (series label) : label to mark tp level short
slLineShort (series line) : line to mark sl level short
slLabelShort (series label) : label to mark sl level short
sweeps
UDT for data storage and drawings associated with liquidity sweeps
Fields:
upSweeps (matrix) : matrix containing liquidity sweep price points and time points for up sweeps
dnSweeps (matrix) : matrix containing liquidity sweep price points and time points for down sweeps
upSweepDrawings (array) : optional up sweep box array. Pair the size of this array with the rows or columns,
dnSweepDrawings (array) : optional up sweep box array. Pair the size of this array with the rows or columns,
raidExitDrawings
UDT for drawings associated with the Liquidity Raid Strategy
Fields:
tpLine (series line) : tp line for the liquidity raid entry
tpLabel (series label) : tp label for the liquidity raid entry
slLine (series line) : sl line for the liquidity raid entry
slLabel (series label) : sl label for the liquidity raid entry
m2022
UDT for data storage and drawings associated with the Model 2022 Strategy
Fields:
mTime (series int) : time of the FVG where entry limit order is placed
mIndex (series int) : array index of FVG where entry limit order is placed. This requires an array of FVG data, which is defined above.
mEntryDistance (series float) : the distance of the FVG to the 50% range. M2022 looks for the fvg closest to 50% mark of range.
mEntry (series float) : the entry price for the most eligible fvg
fvgHigh (series float) : the high point of the eligible fvg
fvgLow (series float) : the low point of the eligible fvg
longFVGentryBox (series box) : long FVG box, used to draw the eligible FVG
shortFVGentryBox (series box) : short FVG box, used to draw the eligible FVG
line50P (series line) : line used to mark 50% of the range
line100P (series line) : line used to mark 100% (top) of the range
line0P (series line) : line used to mark 0% (bottom) of the range
label50P (series label) : label used to mark 50% of the range
label100P (series label) : label used to mark 100% (top) of the range
label0P (series label) : label used to mark 0% (bottom) of the range
sweepData (array)
silverBullet
UDT for data storage and drawings associated with the Silver Bullet Strategy
Fields:
session (series bool)
sessionStr (series string) : name of the session for silver bullet
sessionBias (series string)
sessionHigh (series float) : = high high of session // use math.max(silverBullet.sessionHigh, high)
sessionLow (series float) : = low low of session // use math.min(silverBullet.sessionLow, low)
sessionFVG (series float) : if applicable, the FVG created during the session
sessionFVGdraw (series box) : if applicable, draw the FVG created during the session
traded (series bool)
tp (series float) : tp of trade entered at the session FVG
sl (series float) : sl of trade entered at the session FVG
sessionDraw (series box) : optional draw session with box
sessionDrawLabel (series label) : optional label session with label
silverBulletDrawings
UDT for trade exit drawings associated with the Silver Bullet Strategy
Fields:
tpLine (series line) : tp line drawing for strategy
tpLabel (series label) : tp label drawing for strategy
slLine (series line) : sl line drawing for strategy
slLabel (series label) : sl label drawing for strategy
unicornModel
UDT for data storage and drawings associated with the Unicorn Model Strategy
Fields:
hPoint (chart.point)
hPoint2 (chart.point)
hPoint3 (chart.point)
breakerBlock (series box) : used to draw the breaker block required for the Unicorn Model
FVG (series box) : used to draw the FVG required for the Unicorn model
topBlock (series float) : price of top of breaker block, can be used to detail trade entry
botBlock (series float) : price of bottom of breaker block, can be used to detail trade entry
startBlock (series int) : start time of the breaker block, used to set the "left = " param for the box
includes (array) : used to store the time of the breaker block, or FVG, or the chart point sequence that setup the Unicorn Model.
entry (series float) : // eligible entry price, for longs"math.max(topBlock, FVG.get_top())",
tpLine (series line) : optional line to mark PT
tpLabel (series label) : optional label to mark PT
slLine (series line) : optional line to mark SL
slLabel (series label) : optional label to mark SL
rejectionBlocks
UDT for data storage and drawings associated with rejection blocks
Fields:
rejectionPoint (chart.point)
bodyPrice (series float) : candle body price closest to the rejection point, for "Up" rejections => math.max(open, close),
rejectionBox (series box) : optional box drawing of the rejection block
rejectionLabel (series label) : optional label for the rejection block
equalLevelsDraw
UDT for data storage and drawings associated with equal highs / equal lows
Fields:
connector (series line) : single line placed at the first high or low, y = avgerage of distinguished equal highs/lows
connectorLab (series label) : optional label to be placed at the highs or lows
levels (array) : array containing the equal highs or lows prices
times (array) : array containing the equal highs or lows individual times
startTime (series int) : the time of the first high or low that forms a sequence of equal highs or lows
radiate (array) : options label to "radiate" the label in connector lab. Can be used for anything
necessaryData
UDT for data storage of historical price points.
Fields:
highArr (array) : array containing historical high points
lowArr (array) : array containing historical low points
timeArr (array) : array containing historical time points
logArr (array) : array containing historical log returns
signArr (array) : array containing historical price directions
closeArr (array) : array containing historical close points
binaryTimeArr (array) : array containing historical time points, uses "push" instead of "unshift" to allow for binary search
binaryCloseArr (array) : array containing historical close points, uses "push" instead of "unshift" to allow the correct
binaryOpenArr (array) : array containing historical optn points, uses "push" instead of "unshift" to allow the correct
atrTFarr (array) : array containing historical user-selected TF atr points
openArr (array) : array containing historical open points
strategy_helpersThis library is designed to aid traders and developers in calculating risk metrics efficiently across different asset types like equities, futures, and forex. It includes comprehensive functions that calculate the number of units or contracts to trade, the value at risk, and the total value of the position based on provided entry prices, stop levels, and risk percentages. Whether you're managing a portfolio or developing trading strategies, this library provides essential tools for risk management. Functions also automatically select the appropriate risk calculation method based on asset type, calculate leverage levels, and determine potential liquidation points for leveraged positions. Perfect for enhancing the precision and effectiveness of your trading strategies.
Library "strategy_helpers"
Provides tools for calculating risk metrics across different types of trading strategies including equities, futures, and forex. Functions allow for precise control over risk management by calculating the number of units or contracts to trade, the value at risk, and the total position value based on entry prices, stop levels, and desired risk percentage. Additional utilities include automatic risk calculation based on asset type, leverage level calculations, and determination of liquidation levels for leveraged trades.
calculate_risk(entry, stop_level, stop_range, capital, risk_percent, trade_direction, whole_number_buy)
Calculates risk metrics for equity trades based on entry, stop level, and risk percent
Parameters:
entry (float) : The price at which the position is entered. Use close if you arent adding to a position. Use the original entry price if you are adding to a position.
stop_level (float) : The price level where the stop loss is placed
stop_range (float) : The price range from entry to stop level
capital (float) : The total capital available for trading
risk_percent (float) : The percentage of capital risked on the trade. 100% is represented by 100.
trade_direction (bool) : True for long trades, false for short trades
whole_number_buy (bool) : True to adjust the quantity to whole numbers
Returns: A tuple containing the number of units to trade, the value at risk, and the total value of the position:
calculate_risk_futures(risk_capital, stop_range)
Calculates risk metrics for futures trades based on the risk capital and stop range
Parameters:
risk_capital (float) : The capital allocated for the trade
stop_range (float) : The price range from entry to stop level
Returns: A tuple containing the number of contracts to trade, the value at risk, and the total value of the position:
calculate_risk_forex(entry, stop_level, stop_range, capital, risk_percent, trade_direction)
Calculates risk metrics for forex trades based on entry, stop level, and risk percent
Parameters:
entry (float) : The price at which the position is entered. Use close if you arent adding to a position. Use the original entry price if you are adding to a position.
stop_level (float) : The price level where the stop loss is placed
stop_range (float) : The price range from entry to stop level
capital (float) : The total capital available for trading
risk_percent (float) : The percentage of capital risked on the trade. 100% is represented by 100.
trade_direction (bool) : True for long trades, false for short trades
Returns: A tuple containing the number of lots to trade, the value at risk, and the total value of the position:
calculate_risk_auto(entry, stop_level, stop_range, capital, risk_percent, trade_direction, whole_number_buy)
Automatically selects the risk calculation method based on the asset type and calculates risk metrics
Parameters:
entry (float) : The price at which the position is entered. Use close if you arent adding to a position. Use the original entry price if you are adding to a position.
stop_level (float) : The price level where the stop loss is placed
stop_range (float) : The price range from entry to stop level
capital (float) : The total capital available for trading
risk_percent (float) : The percentage of capital risked on the trade. 100% is represented by 100.
trade_direction (bool) : True for long trades, false for short trades
whole_number_buy (bool) : True to adjust the quantity to whole numbers, applicable only for non-futures and non-forex trades
Returns: A tuple containing the number of units or contracts to trade, the value at risk, and the total value of the position:
leverage_level(account_equity, position_value)
Calculates the leverage level used based on account equity and position value
Parameters:
account_equity (float) : Total equity in the trading account
position_value (float) : Total value of the position taken
Returns: The leverage level used in the trade
calculate_liquidation_level(entry, leverage, trade_direction, maintenance_margine)
Calculates the liquidation price level for a leveraged trade
Parameters:
entry (float) : The price at which the position is entered
leverage (float) : The leverage level used in the trade
trade_direction (bool) : True for long trades, false for short trades
maintenance_margine (float) : The maintenance margin requirement, expressed as a percentage
Returns: The price level at which the position would be liquidated, or na if leverage is zero
Backtesting & Trading Engine [PineCoders]The PineCoders Backtesting and Trading Engine is a sophisticated framework with hybrid code that can run as a study to generate alerts for automated or discretionary trading while simultaneously providing backtest results. It can also easily be converted to a TradingView strategy in order to run TV backtesting. The Engine comes with many built-in strats for entries, filters, stops and exits, but you can also add you own.
If, like any self-respecting strategy modeler should, you spend a reasonable amount of time constantly researching new strategies and tinkering, our hope is that the Engine will become your inseparable go-to tool to test the validity of your creations, as once your tests are conclusive, you will be able to run this code as a study to generate the alerts required to put it in real-world use, whether for discretionary trading or to interface with an execution bot/app. You may also find the backtesting results the Engine produces in study mode enough for your needs and spend most of your time there, only occasionally converting to strategy mode in order to backtest using TV backtesting.
As you will quickly grasp when you bring up this script’s Settings, this is a complex tool. While you will be able to see results very quickly by just putting it on a chart and using its built-in strategies, in order to reap the full benefits of the PineCoders Engine, you will need to invest the time required to understand the subtleties involved in putting all its potential into play.
Disclaimer: use the Engine at your own risk.
Before we delve in more detail, here’s a bird’s eye view of the Engine’s features:
More than 40 built-in strategies,
Customizable components,
Coupling with your own external indicator,
Simple conversion from Study to Strategy modes,
Post-Exit analysis to search for alternate trade outcomes,
Use of the Data Window to show detailed bar by bar trade information and global statistics, including some not provided by TV backtesting,
Plotting of reminders and generation of alerts on in-trade events.
By combining your own strats to the built-in strats supplied with the Engine, and then tuning the numerous options and parameters in the Inputs dialog box, you will be able to play what-if scenarios from an infinite number of permutations.
USE CASES
You have written an indicator that provides an entry strat but it’s missing other components like a filter and a stop strategy. You add a plot in your indicator that respects the Engine’s External Signal Protocol, connect it to the Engine by simply selecting your indicator’s plot name in the Engine’s Settings/Inputs and then run tests on different combinations of entry stops, in-trade stops and profit taking strats to find out which one produces the best results with your entry strat.
You are building a complex strategy that you will want to run as an indicator generating alerts to be sent to a third-party execution bot. You insert your code in the Engine’s modules and leverage its trade management code to quickly move your strategy into production.
You have many different filters and want to explore results using them separately or in combination. Integrate the filter code in the Engine and run through different permutations or hook up your filtering through the external input and control your filter combos from your indicator.
You are tweaking the parameters of your entry, filter or stop strat. You integrate it in the Engine and evaluate its performance using the Engine’s statistics.
You always wondered what results a random entry strat would yield on your markets. You use the Engine’s built-in random entry strat and test it using different combinations of filters, stop and exit strats.
You want to evaluate the impact of fees and slippage on your strategy. You use the Engine’s inputs to play with different values and get immediate feedback in the detailed numbers provided in the Data Window.
You just want to inspect the individual trades your strategy generates. You include it in the Engine and then inspect trades visually on your charts, looking at the numbers in the Data Window as you move your cursor around.
You have never written a production-grade strategy and you want to learn how. Inspect the code in the Engine; you will find essential components typical of what is being used in actual trading systems.
You have run your system for a while and have compiled actual slippage information and your broker/exchange has updated his fees schedule. You enter the information in the Engine and run it on your markets to see the impact this has on your results.
FEATURES
Before going into the detail of the Inputs and the Data Window numbers, here’s a more detailed overview of the Engine’s features.
Built-in strats
The engine comes with more than 40 pre-coded strategies for the following standard system components:
Entries,
Filters,
Entry stops,
2 stage in-trade stops with kick-in rules,
Pyramiding rules,
Hard exits.
While some of the filter and stop strats provided may be useful in production-quality systems, you will not devise crazy profit-generating systems using only the entry strats supplied; that part is still up to you, as will be finding the elusive combination of components that makes winning systems. The Engine will, however, provide you with a solid foundation where all the trade management nitty-gritty is handled for you. By binding your custom strats to the Engine, you will be able to build reliable systems of the best quality currently allowed on the TV platform.
On-chart trade information
As you move over the bars in a trade, you will see trade numbers in the Data Window change at each bar. The engine calculates the P&L at every bar, including slippage and fees that would be incurred were the trade exited at that bar’s close. If the trade includes pyramided entries, those will be taken into account as well, although for those, final fees and slippage are only calculated at the trade’s exit.
You can also see on-chart markers for the entry level, stop positions, in-trade special events and entries/exits (you will want to disable these when using the Engine in strategy mode to see TV backtesting results).
Customization
You can couple your own strats to the Engine in two ways:
1. By inserting your own code in the Engine’s different modules. The modular design should enable you to do so with minimal effort by following the instructions in the code.
2. By linking an external indicator to the engine. After making the proper selections in the engine’s Settings and providing values respecting the engine’s protocol, your external indicator can, when the Engine is used in Indicator mode only:
Tell the engine when to enter long or short trades, but let the engine’s in-trade stop and exit strats manage the exits,
Signal both entries and exits,
Provide an entry stop along with your entry signal,
Filter other entry signals generated by any of the engine’s entry strats.
Conversion from strategy to study
TradingView strategies are required to backtest using the TradingView backtesting feature, but if you want to generate alerts with your script, whether for automated trading or just to trigger alerts that you will use in discretionary trading, your code has to run as a study since, for the time being, strategies can’t generate alerts. From hereon we will use indicator as a synonym for study.
Unless you want to maintain two code bases, you will need hybrid code that easily flips between strategy and indicator modes, and your code will need to restrict its use of strategy() calls and their arguments if it’s going to be able to run both as an indicator and a strategy using the same trade logic. That’s one of the benefits of using this Engine. Once you will have entered your own strats in the Engine, it will be a matter of commenting/uncommenting only four lines of code to flip between indicator and strategy modes in a matter of seconds.
Additionally, even when running in Indicator mode, the Engine will still provide you with precious numbers on your individual trades and global results, some of which are not available with normal TradingView backtesting.
Post-Exit Analysis for alternate outcomes (PEA)
While typical backtesting shows results of trade outcomes, PEA focuses on what could have happened after the exit. The intention is to help traders get an idea of the opportunity/risk in the bars following the trade in order to evaluate if their exit strategies are too aggressive or conservative.
After a trade is exited, the Engine’s PEA module continues analyzing outcomes for a user-defined quantity of bars. It identifies the maximum opportunity and risk available in that space, and calculates the drawdown required to reach the highest opportunity level post-exit, while recording the number of bars to that point.
Typically, if you can’t find opportunity greater than 1X past your trade using a few different reasonable lengths of PEA, your strategy is doing pretty good at capturing opportunity. Remember that 100% of opportunity is never capturable. If, however, PEA was finding post-trade maximum opportunity of 3 or 4X with average drawdowns of 0.3 to those areas, this could be a clue revealing your system is exiting trades prematurely. To analyze PEA numbers, you can uncomment complete sets of plots in the Plot module to reveal detailed global and individual PEA numbers.
Statistics
The Engine provides stats on your trades that TV backtesting does not provide, such as:
Average Profitability Per Trade (APPT), aka statistical expectancy, a crucial value.
APPT per bar,
Average stop size,
Traded volume .
It also shows you on a trade-by-trade basis, on-going individual trade results and data.
In-trade events
In-trade events can plot reminders and trigger alerts when they occur. The built-in events are:
Price approaching stop,
Possible tops/bottoms,
Large stop movement (for discretionary trading where stop is moved manually),
Large price movements.
Slippage and Fees
Even when running in indicator mode, the Engine allows for slippage and fees to be included in the logic and test results.
Alerts
The alert creation mechanism allows you to configure alerts on any combination of the normal or pyramided entries, exits and in-trade events.
Backtesting results
A few words on the numbers calculated in the Engine. Priority is given to numbers not shown in TV backtesting, as you can readily convert the script to a strategy if you need them.
We have chosen to focus on numbers expressing results relative to X (the trade’s risk) rather than in absolute currency numbers or in other more conventional but less useful ways. For example, most of the individual trade results are not shown in percentages, as this unit of measure is often less meaningful than those expressed in units of risk (X). A trade that closes with a +25% result, for example, is a poor outcome if it was entered with a -50% stop. Expressed in X, this trade’s P&L becomes 0.5, which provides much better insight into the trade’s outcome. A trade that closes with a P&L of +2X has earned twice the risk incurred upon entry, which would represent a pre-trade risk:reward ratio of 2.
The way to go about it when you think in X’s and that you adopt the sound risk management policy to risk a fixed percentage of your account on each trade is to equate a currency value to a unit of X. E.g. your account is 10K USD and you decide you will risk a maximum of 1% of it on each trade. That means your unit of X for each trade is worth 100 USD. If your APPT is 2X, this means every time you risk 100 USD in a trade, you can expect to make, on average, 200 USD.
By presenting results this way, we hope that the Engine’s statistics will appeal to those cognisant of sound risk management strategies, while gently leading traders who aren’t, towards them.
We trade to turn in tangible profits of course, so at some point currency must come into play. Accordingly, some values such as equity, P&L, slippage and fees are expressed in currency.
Many of the usual numbers shown in TV backtests are nonetheless available, but they have been commented out in the Engine’s Plot module.
Position sizing and risk management
All good system designers understand that optimal risk management is at the very heart of all winning strategies. The risk in a trade is defined by the fraction of current equity represented by the amplitude of the stop, so in order to manage risk optimally on each trade, position size should adjust to the stop’s amplitude. Systems that enter trades with a fixed stop amplitude can get away with calculating position size as a fixed percentage of current equity. In the context of a test run where equity varies, what represents a fixed amount of risk translates into different currency values.
Dynamically adjusting position size throughout a system’s life is optimal in many ways. First, as position sizing will vary with current equity, it reproduces a behavioral pattern common to experienced traders, who will dial down risk when confronted to poor performance and increase it when performance improves. Second, limiting risk confers more predictability to statistical test results. Third, position sizing isn’t just about managing risk, it’s also about maximizing opportunity. By using the maximum leverage (no reference to trading on margin here) into the trade that your risk management strategy allows, a dynamic position size allows you to capture maximal opportunity.
To calculate position sizes using the fixed risk method, we use the following formula: Position = Account * MaxRisk% / Stop% [, which calculates a position size taking into account the trade’s entry stop so that if the trade is stopped out, 100 USD will be lost. For someone who manages risk this way, common instructions to invest a certain percentage of your account in a position are simply worthless, as they do not take into account the risk incurred in the trade.
The Engine lets you select either the fixed risk or fixed percentage of equity position sizing methods. The closest thing to dynamic position sizing that can currently be done with alerts is to use a bot that allows syntax to specify position size as a percentage of equity which, while being dynamic in the sense that it will adapt to current equity when the trade is entered, does not allow us to modulate position size using the stop’s amplitude. Changes to alerts are on the way which should solve this problem.
In order for you to simulate performance with the constraint of fixed position sizing, the Engine also offers a third, less preferable option, where position size is defined as a fixed percentage of initial capital so that it is constant throughout the test and will thus represent a varying proportion of current equity.
Let’s recap. The three position sizing methods the Engine offers are:
1. By specifying the maximum percentage of risk to incur on your remaining equity, so the Engine will dynamically adjust position size for each trade so that, combining the stop’s amplitude with position size will yield a fixed percentage of risk incurred on current equity,
2. By specifying a fixed percentage of remaining equity. Note that unless your system has a fixed stop at entry, this method will not provide maximal risk control, as risk will vary with the amplitude of the stop for every trade. This method, as the first, does however have the advantage of automatically adjusting position size to equity. It is the Engine’s default method because it has an equivalent in TV backtesting, so when flipping between indicator and strategy mode, test results will more or less correspond.
3. By specifying a fixed percentage of the Initial Capital. While this is the least preferable method, it nonetheless reflects the reality confronted by most system designers on TradingView today. In this case, risk varies both because the fixed position size in initial capital currency represents a varying percentage of remaining equity, and because the trade’s stop amplitude may vary, adding another variability vector to risk.
Note that the Engine cannot display equity results for strategies entering trades for a fixed amount of shares/contracts at a variable price.
SETTINGS/INPUTS
Because the initial text first published with a script cannot be edited later and because there are just too many options, the Engine’s Inputs will not be covered in minute detail, as they will most certainly evolve. We will go over them with broad strokes; you should be able to figure the rest out. If you have questions, just ask them here or in the PineCoders Telegram group.
Display
The display header’s checkbox does nothing.
For the moment, only one exit strategy uses a take profit level, so only that one will show information when checking “Show Take Profit Level”.
Entries
You can activate two simultaneous entry strats, each selected from the same set of strats contained in the Engine. If you select two and they fire simultaneously, the main strat’s signal will be used.
The random strat in each list uses a different seed, so you will get different results from each.
The “Filter transitions” and “Filter states” strats delegate signal generation to the selected filter(s). “Filter transitions” signals will only fire when the filter transitions into bull/bear state, so after a trade is stopped out, the next entry may take some time to trigger if the filter’s state does not change quickly. When you choose “Filter states”, then a new trade will be entered immediately after an exit in the direction the filter allows.
If you select “External Indicator”, your indicator will need to generate a +2/-2 (or a positive/negative stop value) to enter a long/short position, providing the selected filters allow for it. If you wish to use the Engine’s capacity to also derive the entry stop level from your indicator’s signal, then you must explicitly choose this option in the Entry Stops section.
Filters
You can activate as many filters as you wish; they are additive. The “Maximum stop allowed on entry” is an important component of proper risk management. If your system has an average 3% stop size and you need to trade using fixed position sizes because of alert/execution bot limitations, you must use this filter because if your system was to enter a trade with a 15% stop, that trade would incur 5 times the normal risk, and its result would account for an abnormally high proportion in your system’s performance.
Remember that any filter can also be used as an entry signal, either when it changes states, or whenever no trade is active and the filter is in a bull or bear mode.
Entry Stops
An entry stop must be selected in the Engine, as it requires a stop level before the in-trade stop is calculated. Until the selected in-trade stop strat generates a stop that comes closer to price than the entry stop (or respects another one of the in-trade stops kick in strats), the entry stop level is used.
It is here that you must select “External Indicator” if your indicator supplies a +price/-price value to be used as the entry stop. A +price is expected for a long entry and a -price value will enter a short with a stop at price. Note that the price is the absolute price, not an offset to the current price level.
In-Trade Stops
The Engine comes with many built-in in-trade stop strats. Note that some of them share the “Length” and “Multiple” field, so when you swap between them, be sure that the length and multiple in use correspond to what you want for that stop strat. Suggested defaults appear with the name of each strat in the dropdown.
In addition to the strat you wish to use, you must also determine when it kicks in to replace the initial entry’s stop, which is determined using different strats. For strats where you can define a positive or negative multiple of X, percentage or fixed value for a kick-in strat, a positive value is above the trade’s entry fill and a negative one below. A value of zero represents breakeven.
Pyramiding
What you specify in this section are the rules that allow pyramiding to happen. By themselves, these rules will not generate pyramiding entries. For those to happen, entry signals must be issued by one of the active entry strats, and conform to the pyramiding rules which act as a filter for them. The “Filter must allow entry” selection must be chosen if you want the usual system’s filters to act as additional filtering criteria for your pyramided entries.
Hard Exits
You can choose from a variety of hard exit strats. Hard exits are exit strategies which signal trade exits on specific events, as opposed to price breaching a stop level in In-Trade Stops strategies. They are self-explanatory. The last one labelled When Take Profit Level (multiple of X) is reached is the only one that uses a level, but contrary to stops, it is above price and while it is relative because it is expressed as a multiple of X, it does not move during the trade. This is the level called Take Profit that is show when the “Show Take Profit Level” checkbox is checked in the Display section.
While stops focus on managing risk, hard exit strategies try to put the emphasis on capturing opportunity.
Slippage
You can define it as a percentage or a fixed value, with different settings for entries and exits. The entry and exit markers on the chart show the impact of slippage on the entry price (the fill).
Fees
Fees, whether expressed as a percentage of position size in and out of the trade or as a fixed value per in and out, are in the same units of currency as the capital defined in the Position Sizing section. Fees being deducted from your Capital, they do not have an impact on the chart marker positions.
In-Trade Events
These events will only trigger during trades. They can be helpful to act as reminders for traders using the Engine as assistance to discretionary trading.
Post-Exit Analysis
It is normally on. Some of its results will show in the Global Numbers section of the Data Window. Only a few of the statistics generated are shown; many more are available, but commented out in the Plot module.
Date Range Filtering
Note that you don’t have to change the dates to enable/diable filtering. When you are done with a specific date range, just uncheck “Date Range Filtering” to disable date filtering.
Alert Triggers
Each selection corresponds to one condition. Conditions can be combined into a single alert as you please. Just be sure you have selected the ones you want to trigger the alert before you create the alert. For example, if you trade in both directions and you want a single alert to trigger on both types of exits, you must select both “Long Exit” and “Short Exit” before creating your alert.
Once the alert is triggered, these settings no longer have relevance as they have been saved with the alert.
When viewing charts where an alert has just triggered, if your alert triggers on more than one condition, you will need the appropriate markers active on your chart to figure out which condition triggered the alert, since plotting of markers is independent of alert management.
Position sizing
You have 3 options to determine position size:
1. Proportional to Stop -> Variable, with a cap on size.
2. Percentage of equity -> Variable.
3. Percentage of Initial Capital -> Fixed.
External Indicator
This is where you connect your indicator’s plot that will generate the signals the Engine will act upon. Remember this only works in Indicator mode.
DATA WINDOW INFORMATION
The top part of the window contains global numbers while the individual trade information appears in the bottom part. The different types of units used to express values are:
curr: denotes the currency used in the Position Sizing section of Inputs for the Initial Capital value.
quote: denotes quote currency, i.e. the value the instrument is expressed in, or the right side of the market pair (USD in EURUSD ).
X: the stop’s amplitude, itself expressed in quote currency, which we use to express a trade’s P&L, so that a trade with P&L=2X has made twice the stop’s amplitude in profit. This is sometimes referred to as R, since it represents one unit of risk. It is also the unit of measure used in the APPT, which denotes expected reward per unit of risk.
X%: is also the stop’s amplitude, but expressed as a percentage of the Entry Fill.
The numbers appearing in the Data Window are all prefixed:
“ALL:” the number is the average for all first entries and pyramided entries.
”1ST:” the number is for first entries only.
”PYR:” the number is for pyramided entries only.
”PEA:” the number is for Post-Exit Analyses
Global Numbers
Numbers in this section represent the results of all trades up to the cursor on the chart.
Average Profitability Per Trade (X): This value is the most important gauge of your strat’s worthiness. It represents the returns that can be expected from your strat for each unit of risk incurred. E.g.: your APPT is 2.0, thus for every unit of currency you invest in a trade, you can on average expect to obtain 2 after the trade. APPT is also referred to as “statistical expectancy”. If it is negative, your strategy is losing, even if your win rate is very good (it means your winning trades aren’t winning enough, or your losing trades lose too much, or both). Its counterpart in currency is also shown, as is the APPT/bar, which can be a useful gauge in deciding between rivalling systems.
Profit Factor: Gross of winning trades/Gross of losing trades. Strategy is profitable when >1. Not as useful as the APPT because it doesn’t take into account the win rate and the average win/loss per trade. It is calculated from the total winning/losing results of this particular backtest and has less predictive value than the APPT. A good profit factor together with a poor APPT means you just found a chart where your system outperformed. Relying too much on the profit factor is a bit like a poker player who would think going all in with two’s against aces is optimal because he just won a hand that way.
Win Rate: Percentage of winning trades out of all trades. Taken alone, it doesn’t have much to do with strategy profitability. You can have a win rate of 99% but if that one trade in 100 ruins you because of poor risk management, 99% doesn’t look so good anymore. This number speaks more of the system’s profile than its worthiness. Still, it can be useful to gauge if the system fits your personality. It can also be useful to traders intending to sell their systems, as low win rate systems are more difficult to sell and require more handholding of worried customers.
Equity (curr): This the sum of initial capital and the P&L of your system’s trades, including fees and slippage.
Return on Capital is the equivalent of TV’s Net Profit figure, i.e. the variation on your initial capital.
Maximum drawdown is the maximal drawdown from the highest equity point until the drop . There is also a close to close (meaning it doesn’t take into account in-trade variations) maximum drawdown value commented out in the code.
The next values are self-explanatory, until:
PYR: Avg Profitability Per Entry (X): this is the APPT for all pyramided entries.
PEA: Avg Max Opp . Available (X): the average maximal opportunity found in the Post-Exit Analyses.
PEA: Avg Drawdown to Max Opp . (X): this represents the maximum drawdown (incurred from the close at the beginning of the PEA analysis) required to reach the maximal opportunity point.
Trade Information
Numbers in this section concern only the current trade under the cursor. Most of them are self-explanatory. Use the description’s prefix to determine what the values applies to.
PYR: Avg Profitability Per Entry (X): While this value includes the impact of all current pyramided entries (and only those) and updates when you move your cursor around, P&L only reflects fees at the trade’s last bar.
PEA: Max Opp . Available (X): It’s the most profitable close reached post-trade, measured from the trade’s Exit Fill, expressed in the X value of the trade the PEA follows.
PEA: Drawdown to Max Opp . (X): This is the maximum drawdown from the trade’s Exit Fill that needs to be sustained in order to reach the maximum opportunity point, also expressed in X. Note that PEA numbers do not include slippage and fees.
EXTERNAL SIGNAL PROTOCOL
Only one external indicator can be connected to a script; in order to leverage its use to the fullest, the engine provides options to use it as either an entry signal, an entry/exit signal or a filter. When used as an entry signal, you can also use the signal to provide the entry’s stop. Here’s how this works:
For filter state: supply +1 for bull (long entries allowed), -1 for bear (short entries allowed).
For entry signals: supply +2 for long, -2 for short.
For exit signals: supply +3 for exit from long, -3 for exit from short.
To send an entry stop level with an entry signal: Send positive stop level for long entry (e.g. 103.33 to enter a long with a stop at 103.33), negative stop level for short entry (e.g. -103.33 to enter a short with a stop at 103.33). If you use this feature, your indicator will have to check for exact stop levels of 1.0, 2.0 or 3.0 and their negative counterparts, and fudge them with a tick in order to avoid confusion with other signals in the protocol.
Remember that mere generation of the values by your indicator will have no effect until you explicitly allow their use in the appropriate sections of the Engine’s Settings/Inputs.
An example of a script issuing a signal for the Engine is published by PineCoders.
RECOMMENDATIONS TO ASPIRING SYSTEM DESIGNERS
Stick to higher timeframes. On progressively lower timeframes, margins decrease and fees and slippage take a proportionally larger portion of profits, to the point where they can very easily turn a profitable strategy into a losing one. Additionally, your margin for error shrinks as the equilibrium of your system’s profitability becomes more fragile with the tight numbers involved in the shorter time frames. Avoid <1H time frames.
Know and calculate fees and slippage. To avoid market shock, backtest using conservative fees and slippage parameters. Systems rarely show unexpectedly good returns when they are confronted to the markets, so put all chances on your side by being outrageously conservative—or a the very least, realistic. Test results that do not include fees and slippage are worthless. Slippage is there for a reason, and that’s because our interventions in the market change the market. It is easier to find alpha in illiquid markets such as cryptos because not many large players participate in them. If your backtesting results are based on moving large positions and you don’t also add the inevitable slippage that will occur when you enter/exit thin markets, your backtesting will produce unrealistic results. Even if you do include large slippage in your settings, the Engine can only do so much as it will not let slippage push fills past the high or low of the entry bar, but the gap may be much larger in illiquid markets.
Never test and optimize your system on the same dataset , as that is the perfect recipe for overfitting or data dredging, which is trying to find one precise set of rules/parameters that works only on one dataset. These setups are the most fragile and often get destroyed when they meet the real world.
Try to find datasets yielding more than 100 trades. Less than that and results are not as reliable.
Consider all backtesting results with suspicion. If you never entertained sceptic tendencies, now is the time to begin. If your backtest results look really good, assume they are flawed, either because of your methodology, the data you’re using or the software doing the testing. Always assume the worse and learn proper backtesting techniques such as monte carlo simulations and walk forward analysis to avoid the traps and biases that unchecked greed will set for you. If you are not familiar with concepts such as survivor bias, lookahead bias and confirmation bias, learn about them.
Stick to simple bars or candles when designing systems. Other types of bars often do not yield reliable results, whether by design (Heikin Ashi) or because of the way they are implemented on TV (Renko bars).
Know that you don’t know and use that knowledge to learn more about systems and how to properly test them, about your biases, and about yourself.
Manage risk first , then capture opportunity.
Respect the inherent uncertainty of the future. Cleanse yourself of the sad arrogance and unchecked greed common to newcomers to trading. Strive for rationality. Respect the fact that while backtest results may look promising, there is no guarantee they will repeat in the future (there is actually a high probability they won’t!), because the future is fundamentally unknowable. If you develop a system that looks promising, don’t oversell it to others whose greed may lead them to entertain unreasonable expectations.
Have a plan. Understand what king of trading system you are trying to build. Have a clear picture or where entries, exits and other important levels will be in the sort of trade you are trying to create with your system. This stated direction will help you discard more efficiently many of the inevitably useless ideas that will pop up during system design.
Be wary of complexity. Experienced systems engineers understand how rapidly complexity builds when you assemble components together—however simple each one may be. The more complex your system, the more difficult it will be to manage.
Play! . Allow yourself time to play around when you design your systems. While much comes about from working with a purpose, great ideas sometimes come out of just trying things with no set goal, when you are stuck and don’t know how to move ahead. Have fun!
@LucF
NOTES
While the engine’s code can supply multiple consecutive entries of longs or shorts in order to scale positions (pyramid), all exits currently assume the execution bot will exit the totality of the position. No partial exits are currently possible with the Engine.
Because the Engine is literally crippled by the limitations on the number of plots a script can output on TV; it can only show a fraction of all the information it calculates in the Data Window. You will find in the Plot Module vast amounts of commented out lines that you can activate if you also disable an equivalent number of other plots. This may be useful to explore certain characteristics of your system in more detail.
When backtesting using the TV backtesting feature, you will need to provide the strategy parameters you wish to use through either Settings/Properties or by changing the default values in the code’s header. These values are defined in variables and used not only in the strategy() statement, but also as defaults in the Engine’s relevant Inputs.
If you want to test using pyramiding, then both the strategy’s Setting/Properties and the Engine’s Settings/Inputs need to allow pyramiding.
If you find any bugs in the Engine, please let us know.
THANKS
To @glaz for allowing the use of his unpublished MA Squize in the filters.
To @everget for his Chandelier stop code, which is also used as a filter in the Engine.
To @RicardoSantos for his pseudo-random generator, and because it’s from him that I first read in the Pine chat about the idea of using an external indicator as input into another. In the PineCoders group, @theheirophant then mentioned the idea of using it as a buy/sell signal and @simpelyfe showed a piece of code implementing the idea. That’s the tortuous story behind the use of the external indicator in the Engine.
To @admin for the Volatility stop’s original code and for the donchian function lifted from Ichimoku .
To @BobHoward21 for the v3 version of Volatility Stop .
To @scarf and @midtownsk8rguy for the color tuning.
To many other scripters who provided encouragement and suggestions for improvement during the long process of writing and testing this piece of code.
To J. Welles Wilder Jr. for ATR, used extensively throughout the Engine.
To TradingView for graciously making an account available to PineCoders.
And finally, to all fellow PineCoders for the constant intellectual stimulation; it is a privilege to share ideas with you all. The Engine is for all TradingView PineCoders, of course—but especially for you.
Look first. Then leap.
Great Expectations [LucF]Great Expectations helps traders answer the question: What is possible? It is a powerful question, yet exploration of the unknown always entails risk. A more complete set of questions better suited to traders could be:
What opportunity exists from any given point on a chart?
What portion of this opportunity can be realistically captured?
What risk will be incurred in trying to do so, and how long will it take?
Great Expectations is the result of an exploration of these questions. It is a trade simulator that generates visual and quantitative information to help strategy modelers visually identify and analyse areas of optimal expectation on charts, whether they are designing automated or discretionary strategies.
WARNING: Great Expectations is NOT an indicator that helps determine the current state of a market. It works by looking at points in the past from which the future is already known. It uses one definition of repainting extensively (i.e. it goes back in the past to print information that could not have been know at the time). Repainting understood that way is in fact almost all the indicator does! —albeit for what I hope is a noble cause. The indicator is of no use whatsoever in analyzing markets in real-time. If you do not understand what it does, please stay away!
This is an indicator—not a strategy that uses TradingView’s backtesting engine. It works by simulating trades, not unlike a backtest, but with the crucial difference that it assumes a trade (either long or short) is entered on all bars in the historic sample. It walks forward from each bar and determines possible outcomes, gathering individual trade statistics that in turn generate precious global statistics from all outcomes tested on the chart.
Great Expectations provides numbers summarizing trade results on all simulations run from the chart. Those numbers cannot be compared to backtest-produced numbers since all non-filtered bars are examined, even if an entry was taken on the bar immediately preceding the current one, which never happens in a backtest. This peculiarity does NOT invalidate Great Expectations calculations; it just entails that results be considered under a different light. Provided they are evaluated within the indicator’s context, they can be useful—sometimes even more than backtesting results, e.g. in evaluating the impact of parameter-fitting or variations in entry, exit or filtering strats.
Traders and strategy modelers are creatures of hope often suffering from blurred vision; my hope is that Great Expectations will help them appraise the validity of their setup and strat intuitions in a realistic fashion, preventing confirmation bias from obstructing perspective—and great expectations from turning into financial great deceptions.
USE CASES
You’ve identified what looks like a promising setup on other indicators. You load Great Expectations on the chart and evaluate if its high-expectation areas match locations where your setup’s conditions occur. Unless today is your lucky day, chances are the indicator will help you realize your setup is not as promising as you had hoped.
You want to get a rough estimate of the optimal trade duration for a chart and you don’t mind using the entry and exit strategies provided with the indicator. You use the trade length readouts of the indicator.
You’re experimenting with a new stop strategy and want to know how long it will keep you in trades, on average. You integrate your stop strategy in the indicator’s code and look at the average trade length it produces and the TST ratio to evaluate its performance.
You have put together your own entry and exit criteria and are looking for a filter that will help you improve backtesting results. You visually ascertain the suitability of your filter by looking at its results on the charts with great Expectations, to see if your filter is choosing its areas correctly.
You have a strategy that shows backtested trades on your chart. Great Expectations can help you evaluate how well your strategy is benefitting from high-opportunity areas while avoiding poor expectation spots.
You want more complete statistics on your set of strategies than what backtesting will provide. You use Great Expectations, knowing that it tests all bars in the sample that correspond to your criteria, as opposed to backtesting results which are limited to a subset of all possible entries.
You want to fool your friends into thinking you’ve designed the holy grail of indicators, something that identifies optimal opportunities on any chart; you show them the P&L cloud.
FEATURES
For one trade
At any given point on the chart, assuming a trade is entered there, Great Expectations shows you information specific to that trade simulation both on the chart and in the Data Window.
The chart can display:
the P & L Cloud which shows whether the trade ended profitably or not, and by how much,
the Opportunity & Risk Cloud which the maximum opportunity and risk the simulation encountered. When superimposed over the P & L cloud, you will see what I call the managed opportunity and risk, i.e the portion of maximum opportunity that was captured and the portion of the maximum risk that was incurred,
the target and if it was reached,
a background that uses a gradient to show different levels of trade length, P&L or how frequently the target was reached during simulation.
The Data Window displays more than 40 values on individual trades and global results. For any given trade you will know:
Entry/Exit levels, including slippage impact,
It’s outcome and duration,
P/L achieved,
The fraction of the maximum opportunity/risk managed by the trade.
For all trades
After going through all the possible trades on the chart, the indicator will provide you with a rare view of all outcomes expressed with the P&L cloud, which allows us to instantly see the most/least profitable areas of a chart using trade data as support, while also showing its relationship with the opportunity/risk encountered during the simulation. The difference between the two clouds is the managed opportunity and risk.
The Data Window will present you with numbers which we will go through later. Some of them are: average stop size, P/L, win rate, % opportunity managed, trade lengths for different types of trade outcomes and the TST (Target:Stop Travel) ratio.
Let’s see Great Expectations in action… and remember to open your Data Window!
INPUTS
Trade direction : You must first choose if you wish to look at long or short trades. Because of the way the indicator works and the amount of visual information on the chart, it is only practical to look at one type of trades at a time. The default is Longs.
Maximum trade Length (MaxL) : This is the maximum walk forward distance the simulator will go in analyzing outcomes from any given point in the past. It also determines the size of the dead zone among the chart’s last bars. A red background line identifies the beginning of the dead zone for which not enough bars have elapsed to analyze outcomes for the maximum trade length defined. If an ATR-based entry stop is used, that length is added to the wait time before beginning simulations, so that the first entry starts with a clean ATR value. On a sample of around 16000 bars, my tests show that the indicator runs into server errors at lengths of around 290, i.e. having completed ~4,6M simulation loop iterations. That is way too high a length anyways; 100 will usually be amply enough to ring out all the possibilities out of a simulation, and on shorter time frames, 30 can be enough. While making it unduly small will prevent simulations of expressing the market’s potential, the less you use, the faster the indicator will run. The default is 40.
Unrealized P&L base at End of Trade (EOT) : When a simulation ends and the trade is still open, we calculate unrealized P&L from an exit order executed from either the last in-trade stop on the previous bar, or the close of the last bar. You can readily see the impact of this selection on the chart, with the P&L cloud. The default is on the close.
Display : The check box besides the title does nothing.
Show target : Shows a green line displaying the trade’s target expressed as a multiple of X, i.e. the amplitude of the entry stop. I call this value “X” and use it as a unit to express profit and loss on a trade (some call it “R”). The line is highlighted for trades where the close reached the target during the trade, whether the trade ended in profit or loss. This is also where you specify the multiple of X you wish to use in calculating targets. The multiple is used even if targets are not displayed.
Show P&L Cloud : The cloud allows traders to see right away the profitable areas of the chart. The only line printed with the cloud is the “end of trade line” (EOT). The EOT line is the only way one can see the level where a trade ended on the chart (in the Data Window you can see it as the “Exit Fill” value). The EOT level for the trade determines if the trade ended in a profit or a loss. Its value represents one of the following:
- fill from order executed at close of bar where stop is breached during trade (which produces “Realized P/L”),
- simulation of a fill pseudo-fill at the user-defined EOT level (last close or stop level) if the trade runs its course through MaxL bars without getting stopped (producing Unrealized P/L).
The EOT line and the cloud fill print in green when the trade’s outcome is profitable and in red when it is not. If the trade was closed after breaching the stop, the line appears brighter.
Show Opportunity&Risk Cloud : Displays the maximum opportunity/risk that was present during the trade, i.e. the maximum and minimum prices reached.
Background Color Scheme : Allows you to choose between 3 different color schemes for the background gradients, to accommodate different types of chart background/candles. Select “None” if you don’t want a background.
Background source : Determines what value will be used to generate the different intensities of the gradient. You can choose trade length (brighter is shorter), Trade P&L (brighter is higher) or the number of times the target was reached during simulation (brighter is higher). The default is Trade Length.
Entry strat : The check box besides the title does nothing. The default strat is All bars, meaning a trade will be simulated from all bars not excluded by the filters where a MaxL bars future exists. For fun, I’ve included a pseudo-random entry strat (an indirect way of changing the seed is to vary the starting date of the simulation).
Show Filter State : Displays areas where the combination of filters you have selected are allowing entries. Filtering occurs as per your selection(s), whether the state is displayed or not. The effect of multiple selections is additive. The filters are:
1. Bar direction: Longs will only be entered if close>open and vice versa.
2. Rising Volume: Applies to both long and shorts.
3. Rising/falling MA of the length you choose over the number of bars you choose.
4. Custom indicator: You can feed your own filtering signal through this from another indicator. It must produce a signal of 1 to allow long entries and 0 to allow shorts.
Show Entry Stops :
1. Multiple of user-defined length ATR.
2. Fixed percentage.
3. Fixed value.
All entry stops are calculated using the entry fill price as a reference. The fill price is calculated from the current bar’s open, to which slippage is added if configured. This simulates the case where the strategy issued the entry signal on the previous bar for it to be executed at the next bar’s open.
The entry stop remains active until the in-trade stop becomes the more aggressive of the two stops. From then on, the entry stop will be ignored, unless a bar close breaches the in-trade stop, in which case the stop will be reset with a new entry stop and the process repeats.
Show In-trade stops : Displays in bright red the selected in-trade stop (be sure to read the note in this section about them).
1. ATR multiple: added/subtracted from the average of the two previous bars minimum/maximum of open/close.
2. A trailing stop with a deviation expressed as a multiple of entry stop (X).
3. A fixed percentage trailing stop.
Trailing stops deviations are measured from the highest/lowest high/low reached during the trade.
Note: There is a twist with the in-trade stops. It’s that for any given bar, its in-trade stop can hold multiple values, as each successive pass of the advancing simulation loops goes over it from a different entry points. What is printed is the stop from the loop that ended on that bar, which may have nothing to do with other instances of the trade’s in-trade stop for the same bar when visited from other starting points in previous simulations. There is just no practical way to print all stop values that were used for any given bar. While the printed entry stops are the actual ones used on each bar, the in-trade stops shown are merely the last instance used among many.
Include Slippage : if checked, slippage will be added/subtracted from order price to yield the fill price. Slippage is in percentage. If you choose to include slippage in the simulations, remember to adjust it by considering the liquidity of the markets and the time frame you’ll be analyzing.
Include Fees : if checked, fees will be subtracted/added to both realized an unrealized trade profits/losses. Fees are in percentage. The default fees work well for crypto markets but will need adjusting for others—especially in Forex. Remember to modify them accordingly as they can have a major impact on results. Both fees and slippage are included to remind us of their importance, even if the global numbers produced by the indicator are not representative of a real trading scenario composed of sequential trades.
Date Range filtering : the usual. Just note that the checkbox has to be selected for date filtering to activate.
DATA WINDOW
Most of the information produced by this indicator is made available in the Data Window, which you bring up by using the icon below the Watchlist and Alerts buttons at the right of the TV UI. Here’s what’s there.
Some of the information presented in the Data Window is standard trade data; other values are not so standard; e. g. the notions of managed opportunity and risk and Target:Stop Travel ratio. The interplay between all the values provided by Great Expectations is inherently complex, even for a static set of entry/filter/exit strats. During the constant updating which the habitual process of progressive refinement in building strategies that is the lot of strategy modelers entails, another level of complexity is no doubt added to the analysis of this indicator’s values. While I don’t want to sound like Wolfram presenting A New Kind of Science , I do believe that if you are a serious strategy modeler and spend the time required to get used to using all the information this indicator makes available, you may find it useful.
Trade Information
Entry Order : This is the open of the bar where simulation starts. We suppose that an entry signal was generated at the previous bar.
Entry Fill (including slip.) : The actual entry price, including slippage. This is the base price from which other values will be calculated.
Exit Order : When a stop is breached, an exit order is executed from the close of the bar that breached the stop. While there is no “In-trade stop” value included in the Data Window (other than the End of trade Stop previously discussed), this “Exit Order” value is how we can know the level where the trade was stopped during the simulation. The “Trade Length” value will then show the bar where the stop was breached.
Exit Fill (including slip.) : When the exit order is simulated, slippage is added to the order level to create the fill.
Chart: Target : This is the target calculated at the beginning of the simulation. This value also appear on the chart in teal. It is controlled by the multiple of X defined under the “Show Target” checkbox in the Inputs.
Chart: Entry Stop : This value also appears on the chart (the red dots under points where a trade was simulated). Its value is controlled by the Entry Strat chosen in the Inputs.
X (% Fill, including Fees) and X (currency) : This is the stop’s amplitude (Entry Fill – Entry Stop) + Fees. It represents the risk incurred upon entry and will be used to express P&L. We will show R expressed in both a percentage of the Entry Fill level (this value), and currency (the next value). This value represents the risk in the risk:reward ratio and is considered to be a unit of 1 so that RR can be expressed as a single value (i.e. “2” actually meaning “1:2”).
Trade Length : If trade was stopped, it’s the number of bars elapsed until then. The trade is then considered “Closed”. If the trade ends without being stopped (there is no profit-taking strat implemented, so the stop is the only exit strat), then the trade is “Open”, the length is MaxL and it will show in orange. Otherwise the value will print in green/red to reflect if the trade is winning/losing.
P&L (X) : The P&L of the trade, expressed as a multiple of X, which takes into account fees paid at entry and exit. Given our default target setting at 2 units of “X”, a trade that closes at its target will have produced a P&L of +2.0, i.e. twice the value of X (not counting fees paid at exit ). A trade that gets stopped late 50% further that the entry stop’s level will produce a P&L of -1.5X.
P&L (currency, including Fees) : same value as above, but expressed in currency.
Target first reached at bar : If price closed above the target during the trade (even if it occurs after the trade was stopped), this will show when. This value will be used in calculating our TST ratio.
Times Stop/Target reached in sim. : Includes all occurrences during the complete simulation loop.
Opportunity (X) : The highest/lowest price reached during a simulation, i.e. the maximum opportunity encountered, whether the trade was previously stopped or not, expressed as a multiple of X.
Risk (X) : The lowest/highest price reached during a simulation, i.e. the maximum risk encountered, whether the trade was previously stopped or not, expressed as a multiple of X.
Risk:Opportunity : The greater this ratio, the greater Opportunity is, compared to Risk.
Managed Opportunity (%) : The portion of Opportunity that was captured by the highest/low stop position, even if it occurred after a previous stop closed the trade.
Managed Risk (%) : The portion of risk that was protected by the lowest/highest stop position, even if it occurred after a previous stop closed the trade. When this value is greater than 100%, it means the trade’s stop is protecting more than the maximum risk, which is frequent. You will, however, never see close to those values for the Managed Opportunity value, since the stop would have to be higher than the Maximum opportunity. It is much easier to alleviate the risk than it is to lock in profits.
Managed Risk:Opportunity : The ratio of the two preceding values.
Managed Opp. vs. Risk : The Managed Opportunity minus the Managed Risk. When it is negative, which is most often is, it means your strat is protecting a greater portion of the risk than it captures opportunity.
Global Numbers
Win Rate(%) : Percentage of winning trades over all entries. Open trades are considered winning if their last stop/close (as per user selection) locks in profits.
Avg X%, Avg X (currency) : Averages of previously described values:.
Avg Profitability/Trade (APPT) : This measures expectation using: Average Profitability Per Trade = (Probability of Win × Average Win) − (Probability of Loss × Average Loss) . It quantifies the average expectation/trade, which RR alone can’t do, as the probabilities of each outcome (win/lose) must also be used to calculate expectancy. The APPT combine the RR with the win rate to yield the true expectancy of a strategy. In my usual way of expressing risk with X, APPT is the equivalent of the average P&L per trade expressed in X. An APPT of -1.5 means that we lose on average 1.5X/trade.
Equity (X), Equity (currency) : The cumulative result of all trade outcomes, expressed as a multiple of X. Multiplied by the Average X in currency, this yields the Equity in currency.
Risk:Opportunity, Managed Risk:Opportunity, Managed Opp. vs. Risk : The global values of the ones previously described.
Avg Trade Length (TL) : One of the most important values derived by going through all the simulations. Again, it is composed of either the length of stopped trades, or MaxL when the trade isn’t stopped (open). This value can help systems modelers shape the characteristics of the components they use to build their strategies.
Avg Closed Win TL and Avg Closed Lose TL : The average lengths of winning/losing trades that were stopped.
Target reached? Avg bars to Stop and Target reached? Avg bars to Target : For the trades where the target was reached at some point in the simulation, the number of bars to the first point where the stop was breached and where the target was reached, respectively. These two values are used to calculate the next value.
TST (Target:Stop Travel Ratio) : This tracks the ratio between the two preceding values (Bars to first stop/Bars to first target), but only for trades where the target was reached somewhere in the loop. A ratio of 2 means targets are reached twice as fast as stops.
The next values of this section are counts or percentages and are self-explanatory.
Chart Plots
Contains chart plots of values already describes.
NOTES
Optimization/Overfitting: There is a fine line between optimizing and overfitting. Tools like this indicator can lead unsuspecting modelers down a path of overfitting that often turns strategies into over-specialized beasts that do not perform elegantly when confronted to the real-world. Proven testing strategies like walk forward analysis will go a long way in helping modelers alleviate this risk.
Input tuning: Because the results generated by the indicator will vary with the parameters used in the active entry, filtering and exit strats, it’s important to realize that although it may be fun at first, just slapping the default settings on a chart and time frame will not yield optimal nor reliable results. While using ATR as often as possible (as I do in this indicator) is a good way to make strat parametrization adaptable, it is not a foolproof solution.
There is no data for the last MaxL bars of the chart, since not enough trade future has elapsed to run a simulation from MaxL bars back.
Modifying the code: I have tried to structure the code modularly, even if that entails a larger code base, so that you can adapt it to your needs. I’ve included a few token components in each of the placeholders designed for entry strategies, filters, entry stops and in-trade stops. This will hopefully make it easier to add your own. In the same spirit, I have also commented liberally.
You will find in the code many instances of standard trade management tasks that can be lifted to code TV strategies where, as I do in mine, you manage everything yourself and don’t rely on built-in Pine strategy functions to act on your trades.
Enjoy!
THANKS
To @scarf who showed me how plotchar() could be used to plot values without ruining scale.
To @glaz for the suggestion to include a Chandelier stop strat; I will.
To @simpelyfe for the idea of using an indicator input for the filters (if some day TV lets us use more than one, it will be useful in other modules of the indicator).
To @RicardoSantos for the random generator used in the random entry strat.
To all scripters publishing open source on TradingView; their code is the best way to learn.
To my trading buddies Irving and Bruno; who showed me way back how pro traders get it done.
Enhanced Volume + Trend StrategyThis strategy combines trend-following using an Exponential Moving Average (EMA) with volume confirmation to identify high-probability trading opportunities. Here’s how it works:
1. Trend Detection Using EMA (Exponential Moving Average):
The strategy uses the EMA(20) to detect the market trend. The EMA is a popular tool for identifying the direction of the trend because it gives more weight to recent price data, making it more responsive to changes in price direction.
Long Condition (Buy Signal): A long trade is triggered when the price is above the EMA(20), indicating a bullish trend.
Short Condition (Sell Signal): A short trade is triggered when the price is below the EMA(20), indicating a bearish trend.
2. Volume Confirmation:
Volume is used as a filter to confirm the strength of the price movement.
The Volume Moving Average (SMA) with a length of 20 bars is used to determine the average volume over the last 20 bars.
Volume Condition: A trade is only triggered if the current volume is greater than the Volume Moving Average. This ensures that the trend is supported by strong market participation, which is a sign of higher probability for the trade's success.
3. Stop Loss and Take Profit Based on ATR (Average True Range):
ATR(14) is used to measure market volatility and to determine dynamic stop loss and take profit levels. The ATR indicator calculates the range between the high and low prices over a given period, helping to measure how much the price fluctuates on average.
Stop Loss: The stop loss is set at 1.5x ATR below the entry price for long trades and above the entry price for short trades. This gives enough space for the trade to move, accounting for typical market fluctuations.
Take Profit: The take profit is set at 2x ATR above the entry price for long trades and below the entry price for short trades. This aims to capture a larger price move while still managing risk.
4. Signal Visualization:
Buy Signals: When a long condition is met (price above EMA and volume above the moving average), a green Buy Signal is displayed below the bar on the chart.
Sell Signals: When a short condition is met (price below EMA and volume above the moving average), a red Sell Signal is displayed above the bar on the chart.
Summary:
This strategy looks for bullish trends when the price is above the EMA(20) and bearish trends when the price is below the EMA(20). However, it doesn’t enter a trade unless the current volume is above the average, ensuring that there is enough market participation to back up the price move. ATR is used to dynamically calculate stop loss and take profit levels, providing a flexible approach based on the volatility of the market.
By combining these elements, the strategy aims to capture strong price moves that are supported by volume and trend, while protecting the trades with sensible stop loss and take profit levels based on market volatility.
This strategy is simple but effective in markets where trends and volume are strong indicators of price movement. It’s suitable for active trading on various timeframes, such as the 4-hour chart, to capture medium-term price moves.
RSI-MA Synergy (Синергія RSI і MA)Ця торгова стратегія розроблена для виявлення потенційних точок входу на ринок шляхом аналізу комбінації ковзних середніх (MA) та індексу відносної сили (RSI), з додатковими фільтрами за об'ємом і волатильністю. Назва "RSI-MA Synergy" підкреслює ключову роль взаємодії цих двох індикаторів у стратегії.
Сигнали Входу: Стратегія використовує перетин швидкої ковзної середньої (fastMA) та повільної ковзної середньої (slowMA) для визначення тренду.
Довга позиція (Long): Відкривається коли fastMA перетинає slowMA знизу вгору, а RSI нижче 50.
Коротка позиція (Short): Відкривається коли fastMA перетинає slowMA зверху вниз, а RSI вище 50.
Фільтри:
Об'єм: Вхід у позицію можливий лише тоді, коли об'єм торгівлі перевищує заданий мінімальний рівень.
Волатильність: Вхід у позицію можливий, лише коли поточна волатильність (виміряна за допомогою Average True Range, ATR) перевищує заданий мінімальний поріг.
Стоп-лос і Тейк-профіт:
Можливість встановити стоп-лос і тейк-профіт у відсотках від ціни входу для керування ризиками.
Вихід з Позиції: Позиція може закриватися за досягненням стоп-лосу або тейк-профіту, або при виникненні зворотного сигналу від перетину ковзних середніх та/або RSI.
Мета: Ця стратегія намагається збалансувати виявлення сильних трендів з фільтрацією хибних сигналів, використовуючи синергетичну взаємодію RSI та MA, а також додаткові фільтри для об'єму та волатильності.
English:
Name: "RSI-MA Synergy"
This trading strategy is designed to identify potential market entry points by analyzing a combination of Moving Averages (MA) and the Relative Strength Index (RSI), with additional filters for volume and volatility. The name "RSI-MA Synergy" highlights the key role of the interaction between these two indicators in the strategy.
Entry Signals: The strategy uses the crossover of a fast-moving average (fastMA) and a slow-moving average (slowMA) to determine the trend.
Long Position: Opened when fastMA crosses above slowMA, and the RSI is below 50.
Short Position: Opened when fastMA crosses below slowMA, and the RSI is above 50.
Filters:
Volume: Entry into a position is only possible when the trading volume exceeds a specified minimum level.
Volatility: Entry into a position is only possible when the current volatility (measured using Average True Range, ATR) exceeds a specified minimum threshold.
Stop-Loss and Take-Profit:
The ability to set stop-loss and take-profit levels as percentages of the entry price for risk management.
Position Exit: Positions can be closed upon reaching the stop-loss or take-profit, or when a reverse signal occurs from the moving average crossover and/or RSI.
Purpose: This strategy aims to balance the identification of strong trends with the filtering of false signals, using the synergistic interaction of RSI and MA, as well as additional filters for volume and volatility.
Висновок:
Назва "RSI-MA Synergy" чудово підходить для цієї стратегії. Оновлений опис також підкреслює роль взаємодії індикаторів і фільтрів у її роботі.
Якщо у вас є ще якісь питання або побажання, дайте мені знати!
OKX:TRBUSDT.P
Enhanced Divergence Indicator / Strategy (many oscillators)Hi, Guys!
So, I am publishing a divergence script, with the ability to choose from many indicators, which is equipped to serve either as a strategy or an indicator (or both).
In my opinion, trading with indicators is not something that can consistently bring you profit. But one of the most effective ways to use an indicator is precisely divergence, since it also contains information about imbalance in the price action. This is still one of the main tasks of technical analysis of price movements.
That is why I decided to make a script public, which I myself use with some additional functions, and here I am publishing the main ones. Most of its elements can be found in other community scripts, but not quite collected in one, and not all. The main difference is that here I provide an opportunity to refine the divergences, by using a filter for the minimum price difference in the two extremes, the minimum difference in the extremes of the indicator and something else that you will not find anywhere in free code. As far as I can, I have also made a filter for the minimum reverse movement of the indicator between its two extremes, which make up the divergence. In the settings, I have called it "Minimum Oscillator Pullback".
I'm not a programmer, so my script is crude and inelegant, but overall it does the job.
I added the ability to use a few more widespread filters, but with some small additional options. For example, you can display a fast and slow moving average, but the good thing is that among them there is also T3 - one of the best MAs for showing a trend. You should keep in mind, however, that this way of using a trend is not very good when using divergences.
I also added an underestimated indicator as a filter, which could be quite effective here. It is the Stochastic Momentum Index. I have given the option to use a different timeframe for it. Usually, in oscillators, overbought and oversold zones are searched for, but here its more effective use is rather the opposite. It actually shows the strength of the trend. That's why I made an option for its reversed use, and in addition, its limit levels are also variable.
There is also a filter for eliminating trading days and/or trading hours.
To make the code more informative, I have provided an opportunity to test the strategy with leverage.
There is an option to use TP and SL.
Regarding closing a position, there are also several options. I have not seen anyone else use it, but with a lot of testing, I have found that the SMI mentioned and used as a filter is a very good indicator for exiting a position. This is one thing. But something even better that I have found and put in the code is the use of standard deviation. Most algo-traders use Average True Range for exit. Well, I have personally found with a lot of historical data that Standard Deviation is actually much more effective for this.
For variety, and also because such trading systems exist, I have added the option to close after a certain number of candles. Here I have also added an additional functionality - closing on a candle in the opposite direction of the open position, after the specified number of candles have passed.
Apart from this, there is also an option to use VWAP for exit.
You will see that there are more than a dozen indicators to choose from for divergence. I have tested dozens, maybe hundreds of others, which at first glance seem very suitable for this. But in practice I have found that they do not really add anything.
Keep in mind that in different timeframes, in different market conditions, and different assets behave differently. For some, some indicators are better, but in another timeframe they are weak.
In addition, the filters for improving divergence sometimes behave strangely (for example, for an oscillator it may be good to accept a negative and very large value for the minimum movement between its extremes). This is because they are not standardized and have different scales. But if you play around with the options enough, you will understand what works for you.
Now I can't think of anything more to say, inside the options things should be relatively clear. If there are adequate questions that I am able to answer (I remind you that I am an amateur), I will write in the comments. I am sure that this code will be useful for many, but do not rely too much on it and do not take risks without testing - both with historical data and paper trading. As you know, in any case, nothing is guaranteed in the future.
I think I missed something important.
When you use the script as an indicator, a line will always appear when there is a divergence. It may seem strange to you on the price movement, but keep in mind that it shows exactly where the extremes of the oscillator, which is not visible on the chart, are. A sign will appear on this line when the divergence meets your other conditions - the filters and enhancements included.
In addition, there are options to limit the divergence indication to a number of candles. In practice, this is necessary and improves the results. It is very important to understand that in order for the script to indicate the last extreme, which we will use to open a position, it must first have determined that we have already gone in the opposite direction. Therefore, the options specify candles to the left, but also candles to the right after the peak, to verify that this is really a peak (or bottom). Many believe that this makes divergences bad for trading, since the signal is actually received later. Well, this is not entirely true and you can check it yourself. You can safely set the right candles to 0 and you will see that there are many false signals. Usually it is best to use 2 candles on the right for a signal and if the divergence is good, they still give a good entry. In certain conditions it is good with just one candle.