//@version=5
// This source code is subject to the terms of the Mozilla Public License 2.0 at
[Link]
// © Daveatt
// # ========================================================================= #
// # | SAMPLE INDICATOR |
// # ========================================================================= #
// Sample script to plug to the strategy template
// //@version=5
//indicator(title='Moving Average Cross', shorttitle='Moving Average Cross',
overlay=true, precision=6, max_labels_count=500, max_lines_count=500)
// type_ma1 = [Link](title='MA1 type', defval='SMA', options=['RMA', 'SMA',
'EMA'])
// length_ma1 = input(10, title='[ALL but VWAP] MA1 length')
// type_ma2 = [Link](title='MA2 type', defval='SMA', options=['RMA', 'SMA',
'EMA'])
// length_ma2 = input(100, title='[ALL but VWAP] MA2 length')
// // MA
// f_ma(smoothing, src, length) =>
// rma_1 = [Link](src, length)
// sma_1 = [Link](src, length)
// ema_1 = ta.]ema(src, length)
// iff_1 = smoothing == 'EMA' ? ema_1 : src
// iff_2 = smoothing == 'SMA' ? sma_1 : iff_1
// smoothing == 'RMA' ? rma_1 : iff_2
// MA1 = f_ma(type_ma1, close, length_ma1)
// MA2 = f_ma(type_ma2, close, length_ma2)
// // buy and sell conditions
// buy = [Link](MA1, MA2)
// sell = [Link](MA1, MA2)
// plot(MA1, color=[Link]([Link], 0), title='Plot MA1', linewidth=3)
// plot(MA2, color=[Link]([Link], 0), title='Plot MA2', linewidth=3)
// plotshape(buy, title='LONG SIGNAL', style=[Link],
location=[Link], color=[Link]([Link], 0), size=[Link])
// plotshape(sell, title='SHORT SIGNAL', style=[Link],
location=[Link], color=[Link]([Link], 0), size=[Link])
// /////////////////////////// SIGNAL FOR STRATEGY /////////////////////////
// Signal = buy ? 1 : sell ? -1 : 0
// plot(Signal, title='🔌Connector🔌', display = display.data_window)
// # ========================================================================= #
// # | SAMPLE INDICATOR |
// # ========================================================================= #
VERSION = "V7"
SCRIPT_NAME = "BEST Strategy Template " + VERSION
// # ========================================================================= #
// # | STRATEGY |
// # ========================================================================= #
// These values are used both in the strategy() header and in the script's relevant
inputs as default values so they match.
// Unless these values match in the script's Inputs and the TV backtesting
Properties, results between them cannot be compared.
InitCapital = 10000000
InitPosition = 2.0
InitCommission = 0.075
InitPyramidMax = 1
CalcOnorderFills = false
ProcessOrdersOnClose = true
CalcOnEveryTick = false
CloseEntriesRule = "FIFO"
strategy(title=SCRIPT_NAME, shorttitle=SCRIPT_NAME,
overlay=true, pyramiding=InitPyramidMax, initial_capital=InitCapital,
default_qty_type=strategy.percent_of_equity,
process_orders_on_close=ProcessOrdersOnClose,
default_qty_value=InitPosition, commission_type=[Link],
commission_value=InitCommission, calc_on_order_fills=CalcOnorderFills,
calc_on_every_tick=CalcOnEveryTick,
precision=9, max_lines_count=500, max_labels_count=500)
// # ========================================================================= #
// # ========================================================================= #
// # || Alerts ||
// # ========================================================================= #
// # ========================================================================= #
i_alert_txt_entry_long = input.text_area(defval = "", title = "Long Entry Message",
group = "Alerts")
i_alert_txt_entry_short = input.text_area(defval = "", title = "Short Entry
Message", group = "Alerts")
i_alert_txt_exit_SL_long = input.text_area(defval = "", title = "Long Exit SL
Message", group = "Alerts")
i_alert_txt_exit_TP1_long = input.text_area(defval = "", title = "Long Exit TP1
Message", group = "Alerts")
i_alert_txt_exit_custom_long = input.text_area(defval = "", title = "Long Custom
Exit Message", group = "Alerts")
i_alert_txt_exit_SL_short = input.text_area(defval = "", title = "Short Exit SL
Message", group = "Alerts")
i_alert_txt_exit_TP1_short = input.text_area(defval = "", title = "Short Exit TP1
Message", group = "Alerts")
i_alert_txt_exit_custom_short = input.text_area(defval = "", title = "Short Custom
Exit Message", group = "Alerts")
// ————— You capture the Source of your indicator here
ext_source_ = [Link](close, title='Data source', group = "General")
// Custom close signal
custom_close = [Link](false, title='Use Custom Close?', group = "General")
// Last trades data displayed in a table
display_last_trade_data = [Link](true, title = "Display the current opened
trades data", group = "Table")
_table_location = [Link](title="Table Location", defval="TOP RIGHT",
options=["TOP LEFT", "TOP CENTER", "TOP RIGHT", "BOTTOM LEFT", "BOTTOM CENTER",
"BOTTOM RIGHT"], group = "Table")
_table_txt_size = [Link]("Normal", title = "Txt Size", options=["Tiny",
"Small", "Normal", "Large", "Huge"], group = "Table")
table_cell_bg_color = [Link]([Link], title = "Cells Background Color",
group = "Table", inline = "table_cells")
table_cell_txt_color = [Link]([Link], title = "Cells Text Color", group =
"Table", inline = "table_cells")
table_frame_color = [Link]([Link], title = "Frame Color", group =
"Table", inline = "table_frame")
table_frame_width = [Link](1, title = "Frame Width", minval = 0, group =
"Table", inline = "table_frame")
table_border_color = [Link]([Link], title = "Border Color", group =
"Table", inline = "table_borders")
table_border_width = [Link](1, title = "Border Width", minval = 0, group =
"Table", inline = "table_borders")
table_header_bg_color = [Link](#0b3880, title = "Header Background Color",
group = "Table Header", inline = "header_color")
table_header_txt_color = [Link]([Link], title = "Header Text Color",
group = "Table Header", inline = "header_color")
// Pie Chart Winners/Losers
display_pie_chart = false//[Link](true, title = "Display Pie Chart
Winners/Losers", group = "Pie Chart")
// ————— Bar Coloring
clrBars = [Link](true, title='Colour Candles to Trade Order state',
group='Coloring')
CloseSession = [Link](false, title='Close positions at market at the end of
each session ?', group='Session')
Session = [Link](title='Trading Session', defval='0000-2345',
group='Session')
OpenDirection = [Link](defval='ALL', title='Open Trading Direction',
options=['ALL', 'LONG', 'SHORT'], group='Direction')
CloseDirection = [Link](defval='ALL', title='Close Trading Direction',
options=['ALL', 'LONG', 'SHORT'], group='Direction')
closeOnOpposite = [Link](true, title='Close on Opposite Signal',
group='Strategy')
// ————— Date range filtering
DateFilter = [Link](false, 'Date Range Filtering', group='Date')
// ————— Syntax coming from [Link]
date-input-added-to-pine-21812/
i_startTime = [Link](defval=timestamp('01 Jan 2019 13:30 +0000'), title='Start
Time', group='Date')
i_endTime = [Link](defval=timestamp('30 Dec 2021 23:30 +0000'), title='End
Time', group='Date')
TradeDateIsAllowed() =>
DateFilter ? time >= i_startTime and time <= i_endTime : true
// ————— Set the max losing streak length with an input
setmaxLosingStreak = [Link](title='Set Max number of consecutive loss trades',
defval=false, group='Risk Management')
maxLosingStreak = [Link](title='Max of consecutive loss trades', defval=15,
minval=1, group='Risk Management')
setmaxWinStreak = [Link](title='Set Max number of consecutive won trades',
defval=false, group='Risk Management')
maxWinStreak = [Link](title='Max Winning Streak Length', defval=15, minval=1,
group='Risk Management')
// ————— Set the max consecutive days with a loss
setmaxLosingDaysStreak = [Link](title='Set MAX consecutive days with a loss in
a row', defval=false, group='Risk Management')
maxLosingDaysStreak = [Link](title='Max of consecutive days with a loss in a
row', defval=3, minval=1, group='Risk Management')
setMaxDrawdown = [Link](title='Set Max Total DrawDown', defval=false,
group='Risk Management')
// ————— Input for the strategy's maximum drawdown (in % of strategy equity)
maxPercDd = [Link](title='Max Drawdown (%)', defval=10, minval=1, maxval=100,
group='Risk Management')
setMaxIntradayLoss = [Link](title='Set Max Intraday Loss', defval=false,
group='Risk Management')
// ————— Input for the strategy's maximum intraday loss (in % of strategy equity)
maxIntradayLoss = [Link](title='Max Intraday Loss (%)', defval=3, minval=1,
maxval=100, group='Risk Management')
setNumberDailyTrades = [Link](title='Limit the number of trades per day',
defval=false, group='Risk Management')
maxDailyTrades = [Link](title='Number MAX of daily trades', defval=10, minval=1,
maxval=100, group='Risk Management')
setNumberWeeklyTrades = [Link](title='Limit the number of trades per week',
defval=false, group='Risk Management')
maxWeeklyTrades = [Link](title='Number MAX of weekly trades', defval=50,
minval=1, maxval=100, group='Risk Management')
// Hard Exit
// # ========================================================================= #
// # | Stop Loss |
// # ========================================================================= #
StopType = [Link](title='Stop Type Selection', defval='Percent',
options=['None', 'Percent', 'Trailing', 'ATR'], group='Stop Loss')
// ————— Percent
LossPerc = [Link](title='Stop Loss (%)', minval=0.0, step=0.5, defval=10,
group='Percent Stop Loss') * 0.01
TrailPerc = [Link](title='Trail Stop Loss (%)', minval=0.0, step=0.5,
defval=3, group='Trailing Stop Loss', tooltip = "Activated when the selected Stop
Loss = Trailing") * 0.01
// ————— ATR
atrStopLength = [Link](title='Stop Length', defval=14, group='ATR Stop Loss')
riskRatioATR = [Link](defval=1, title='Risk Ratio', step=0.10, group='ATR Stop
Loss')
// # ========================================================================= #
// # | Take Profit |
// # ========================================================================= #
TakeProfitType = [Link](title='Take Profit Type Selection', defval='Percent',
options=['None', 'Percent', 'ATR'], group='Take Profit')
TP1_ratio = 100//[Link](defval=50, title='Closing X% at TP1', group='Take
Profit', tooltip='Example: 50 closing 50% of the position once TP1 is reached.\nFor
1 TP only, set 100 to close 100% of the trade')
// ————— TP1 —————
// ————— Percent
ProfitPerc1 = [Link](title='Take Profit (%)', minval=0.0, step=0.5, defval=5,
group='Take Profit 1') * 0.01
// ————— ATR
atrTakeProfitLength1 = [Link](title='Take Profit Length', defval=14, group='ATR
Take Profit 1', inline='ATR TP1')
rewardRatioATR1 = [Link](defval=2, title='Reward Ratio', step=0.10, group='ATR
Take Profit 1', inline='ATR TP1')
// # ========================================================================= #
// # | Stop Loss to Breakeven |
// # ========================================================================= #
use_sl_be = [Link](false, title = "Use Stop Loss to Breakeven Mode?",
group = "Stop Loss Breakeven")
sl_be_mode = [Link]("$", title = "Mode", options=["pips", "%", "$"],
group = "Stop Loss Breakeven")
sl_be_value = [Link](1, step = 0.1, minval = 0, title = "Stop Loss to
Breakeven +/- X", group = "Stop Loss Breakeven")
// # ========================================================================= #
// # | Custom Exit |
// # ========================================================================= #
custom_exit_mode = [Link](title='Custom Exit Type Selection',
defval='None', options=['None', 'Number of bars'], group='Custom Exit')
i_custom_exit_nb_bars = [Link](5, title = "Nb bars to exit", group = "Custom
Exit", tooltip = "Exit the trade(s) after X bars have closed since the trade open")
BIG_NUMBER_COUNT = 1000
// variables initialisation
ext_source = nz(ext_source_)
// 1 is bull signal
bull = ext_source == 1
// -1 is bear signal
bear = ext_source == -1
plotshape(
series = bull and not bull[1],
title = "Buy",
style = [Link],
location = [Link],
color = [Link](color = [Link], transp = 0),
size = [Link]
)
plotshape(
series = bear and not bear[1],
title = "Sell",
style = [Link],
location = [Link],
color = [Link](color = [Link], transp = 0),
size = [Link]
)
// 2 exit custom close long
exit_bull = custom_close and ext_source == 2
// -2 exit custom close short
exit_bear = custom_close and ext_source == -2
// Entry Price
entry_price = [Link](condition=(bear[1] and strategy.position_size[1] >= 0)
or (bull[1] and strategy.position_size[1] <= 0), source=close, occurrence=0)
entry_price_long = [Link](condition=(bull and strategy.position_size <= 0),
source=close, occurrence=0)
entry_price_short = [Link](condition=(bear and strategy.position_size >= 0),
source=close, occurrence=0)
// ————— RISK MANAGEMENT
condintradayloss = setMaxIntradayLoss ? maxIntradayLoss : 100
[Link].max_intraday_loss(value=condintradayloss,
type=strategy.percent_of_equity)
condmaxdrawdown = setMaxDrawdown ? maxPercDd : 100
[Link].max_drawdown(value=condmaxdrawdown, type=strategy.percent_of_equity)
// daily trades calculation
oktoTradeDaily = true
tradesIntradayCount = setNumberDailyTrades ? maxDailyTrades : BIG_NUMBER_COUNT
[Link].max_intraday_filled_orders(count=tradesIntradayCount)
// weekly trades calculation
tradesLastWeek = 0
tradesLastWeek := if dayofweek == [Link] and dayofweek != dayofweek[1]
[Link][1] + [Link][1]
else
tradesLastWeek[1]
// Calculate number of trades this week
weeklyTrades = [Link] + [Link] - tradesLastWeek
okToTradeWeekly = setNumberWeeklyTrades ? weeklyTrades < maxWeeklyTrades : true
// consecutive loss days in a row
countConsLossDays = setmaxLosingDaysStreak ? maxLosingDaysStreak : BIG_NUMBER_COUNT
[Link].max_cons_loss_days(countConsLossDays)
// Calculate the total losing streaks
// Check if there's a new losing trade that increased the streak
newLoss = [Link] > [Link][1] and [Link] ==
[Link][1] and [Link] == [Link][1]
// Determine current losing streak length
streakLossLen = 0
streakLossLen := if newLoss
nz(streakLossLen[1]) + 1
else
if [Link] > [Link][1] or [Link] >
[Link][1]
0
else
nz(streakLossLen[1])
// Check if losing streak is under max allowed
okToTradeLossStreak = setmaxLosingStreak ? streakLossLen < maxLosingStreak : true
// Calculate the total winning streaks
// See if there's a new winner that increased the streak
newWin = [Link] > [Link][1] and [Link] ==
[Link][1] and [Link] == [Link][1]
// Figure out current winning streak length
streakWinLen = 0
streakWinLen := if newWin
nz(streakWinLen[1]) + 1
else
if [Link] > [Link][1] or [Link] >
[Link][1]
0
else
nz(streakWinLen[1])
// Check if winning streak is under max allowed
okToTradeWinStreak = setmaxWinStreak ? streakWinLen < maxWinStreak : true
var float longPercStopPrice = 0.
var float shortPercStopPrice = 0.
// Stop loss management
if strategy.position_size > 0
longPercStopPrice := entry_price_long * (1 - LossPerc)
else if strategy.position_size < 0
shortPercStopPrice := entry_price_short * (1 + LossPerc)
// trailing
// Determine trail stop loss prices
var float longTrailStopPrice = 0.0
var float shortTrailStopPrice = 0.0
var float final_SL_Long = 0.0
var float final_SL_Short = 0.0
var MaxReached = 0.0 // Max high/low reached since beginning of trade.
signal_candle = (bull and strategy.position_size <= 0)
or (bear and strategy.position_size >= 0)
if signal_candle[1]
MaxReached := strategy.position_size > 0 ? high : low
// Update Max point reached during trade (used both for trailing stop reference
point and in-trade max drawdown calcs).
// start trailing only when beyong the breakeven point
MaxReached := strategy.position_size > 0
? [Link](nz(MaxReached, high), high)
: strategy.position_size < 0 ? [Link](nz(MaxReached,low), low) : na
//if strategy.position_size > 0
// stopValue = close * (1 - TrailPerc)
// longTrailStopPrice := [Link](stopValue, longTrailStopPrice)
//else
// longTrailStopPrice := 0
//if strategy.position_size < 0
// stopValue = close * (1 + TrailPerc)
// shortTrailStopPrice := [Link](stopValue, shortTrailStopPrice)
//else
// shortTrailStopPrice := 999999
if strategy.position_size > 0
longTrailStopPrice := MaxReached * (1 - TrailPerc)
else if strategy.position_size < 0
shortTrailStopPrice := MaxReached * (1 + TrailPerc)
useSL = StopType != 'None'
use_SL_Percent = StopType == 'Percent'
use_SL_Trail = StopType == 'Trailing'
use_SL_ATR = StopType == 'ATR'
// Use this function to return the correct pip value for pips on Forex symbols
pip() => [Link]
// ATR
// Function atr (average true range) returns the RMA of true range.
// True range is max(high - low, abs(high - close[1]), abs(low - close[1]))
atr_stop = [Link](atrStopLength)
atr_tp1 = [Link](atrTakeProfitLength1)
// ATR used for Risk:Reward
var float RR_STOP_ATR = 0.0
//RR_STOP_ATR := nz(RR_STOP_ATR[1])
var float RR_TP1_ATR = 0.0
//RR_TP1_ATR := nz(RR_TP1_ATR[1])
// Capturig the atr value at signal time only
if (bull and strategy.position_size <= 0) or (bear and strategy.position_size >= 0)
RR_STOP_ATR := atr_stop
RR_TP1_ATR := atr_tp1
if (strategy.position_size <= 0 and bull)
if use_SL_Percent
final_SL_Long := longPercStopPrice
else if use_SL_ATR
final_SL_Long := entry_price_long - RR_STOP_ATR * riskRatioATR
else if (strategy.position_size >= 0 and bear)
if use_SL_Percent
final_SL_Short := shortPercStopPrice
else if use_SL_ATR
final_SL_Short := entry_price_short + RR_STOP_ATR * riskRatioATR
if use_SL_Trail
if strategy.position_size > 0
final_SL_Long := longTrailStopPrice
else if strategy.position_size < 0
final_SL_Short := shortTrailStopPrice
// Take Profit Manangement
useTakeProfit = TakeProfitType != 'None'
use_TP_Percent = TakeProfitType == 'Percent'
use_TP_ATR = TakeProfitType == 'ATR'
var float TP1longPrice = 0.
var float TP1shortPrice = 0.
var bool is_TP1_REACHED = false
if (strategy.position_size <= 0 and bull)
TP1longPrice := use_TP_Percent ? entry_price_long * (1 + ProfitPerc1) :
entry_price_long + RR_TP1_ATR * rewardRatioATR1
else if (strategy.position_size >= 0 and bear)
TP1shortPrice := use_TP_Percent ? entry_price_short * (1 - ProfitPerc1) :
entry_price_short - RR_TP1_ATR * rewardRatioATR1
if strategy.position_size[1] > 0 and high >= TP1longPrice
is_TP1_REACHED := true
else if strategy.position_size[1] < 0 and low <= TP1shortPrice
is_TP1_REACHED := true
// Plot take profit values for confirmation
plot(series=strategy.position_size > 0 and useTakeProfit ? TP1longPrice : na,
color=[Link]([Link], 0), style=plot.style_circles, linewidth=3, title='Long
Take Profit 1')
plot(series=strategy.position_size < 0 and useTakeProfit ? TP1shortPrice : na,
color=[Link]([Link], 0), style=plot.style_circles, linewidth=3, title='Short
Take Profit 1')
// Used for debug and check the ATR TP value
plot(use_TP_ATR and strategy.position_size != 0 ? RR_TP1_ATR * rewardRatioATR1 :
na, color=[Link]([Link], 100), title='ATR TP1 Value')
// # ========================================================================= #
// # | Stop Loss To Breakeven |
// # ========================================================================= #
var bool SL_BE_REACHED = false
var bool is_SL_REACHED = false
if use_sl_be and useSL
current_profit = [Link]([Link] - 1)
if strategy.position_size[1] > 0
if not SL_BE_REACHED
if sl_be_mode == "pips" and current_profit * pip() >= sl_be_value *
pip()
final_SL_Long := entry_price_long //+ (sl_be_value * pip())
SL_BE_REACHED := true
else if sl_be_mode == "$" and current_profit >= sl_be_value
final_SL_Long := entry_price_long //+ (sl_be_value)
SL_BE_REACHED := true
else if sl_be_mode == "%" and [Link](((high - entry_price_long) /
entry_price_long)) * 100 >= sl_be_value
final_SL_Long := entry_price_long //* (1 + (sl_be_value/100))
SL_BE_REACHED := true
else if strategy.position_size[1] < 0
if not SL_BE_REACHED
if sl_be_mode == "pips" and current_profit * pip() >= sl_be_value *
pip()
final_SL_Short := entry_price_short //- (sl_be_value * pip())
SL_BE_REACHED := true
else if sl_be_mode == "$" and current_profit >= sl_be_value
final_SL_Short := entry_price_short// - (sl_be_value)
SL_BE_REACHED := true
else if sl_be_mode == "%" and [Link](((entry_price_short - low) /
low)) * 100 >= sl_be_value
final_SL_Short := entry_price_short// * (1 - (sl_be_value/100))
SL_BE_REACHED := true
// Plot stop loss values for confirmation
plot(series=strategy.position_size > 0 and useSL ? final_SL_Long : na,
color=[Link]([Link], 0), style=plot.style_cross, linewidth=2, title='Long
Stop Loss')
plot(series=strategy.position_size < 0 and useSL ? final_SL_Short : na,
color=[Link]([Link], 0), style=plot.style_cross, linewidth=2, title='Short
Stop Loss')
// Used for debug and check the ATR SL value
plot(use_SL_ATR and strategy.position_size != 0 ? RR_STOP_ATR * riskRatioATR : na,
color=[Link]([Link], 100), title='ATR Stop Value')
// Session calculations
// The BarInSession function returns true when
// the current bar is inside the session parameter
BarInSession(sess) =>
time([Link], sess) != 0
in_session = BarInSession(Session)
okToTradeInSession = CloseSession ? in_session : true
new_session = in_session and not in_session[1]
bgcolor(color=CloseSession and BarInSession(Session)[1] ? [Link]([Link],
85) : na, title='Trading Session')
// consolidation of the conditions
okToTrade = okToTradeWeekly and okToTradeLossStreak and okToTradeWinStreak and
TradeDateIsAllowed() and okToTradeInSession // and TradeHourlyIsAllowed()
// Orders part
longs_opened = strategy.position_size > 0
shorts_opened = strategy.position_size < 0
trades_opened = strategy.position_size != 0
longs_opened_in_session = CloseSession and longs_opened
shorts_opened_in_session = CloseSession and shorts_opened
// trades_opened_in_session = CloseSession and trades_opened
open_all = OpenDirection == 'ALL'
open_all_longs = OpenDirection != 'SHORT'
open_all_shorts = OpenDirection != 'LONG'
close_all = CloseDirection == 'ALL'
close_all_longs = CloseDirection != 'SHORT'
close_all_shorts = CloseDirection != 'LONG'
// Go long
longCondition = bull
if longCondition and okToTrade and okToTradeInSession and open_all_longs
alert_message_long_txt = "entry: " + [Link](close) + " sl: " +
[Link](final_SL_Long) + " tp: " + [Link](TP1longPrice)
[Link]('Long', [Link], alert_message=alert_message_long_txt,
comment = alert_message_long_txt)
// Go Short
shortCondition = bear
if shortCondition and okToTrade and okToTradeInSession and open_all_shorts
alert_message_short_txt = "entry: " + [Link](close) + " sl: " +
[Link](final_SL_Short) + " tp: " + [Link](TP1shortPrice)
[Link]('Short', [Link], alert_message=alert_message_short_txt,
comment = alert_message_short_txt)
// Execute Exits
if closeOnOpposite and strategy.position_size > 0 and shortCondition // and
open_all_shorts
[Link](id='Long', comment='Short Signal\nClose Long')
if closeOnOpposite and strategy.position_size < 0 and longCondition // and
open_all_longs
[Link](id='Short', comment='Long Signal\nClose Short')
// # ========================================================================= #
// # | Custom User-Defined close |
// # ========================================================================= #
if strategy.position_size > 0 and exit_bull and close_all_longs
[Link](id='Long', alert_message=i_alert_txt_exit_custom_long,
comment='Custom User-Defined\nClose Long Signal')
alert(i_alert_txt_exit_custom_long, alert.freq_once_per_bar_close)
if strategy.position_size < 0 and exit_bear and close_all_shorts
[Link](id='Short', alert_message=i_alert_txt_exit_custom_short,
comment='Custom User-Defined\nClose Short Signal')
alert(i_alert_txt_exit_custom_short, alert.freq_once_per_bar_close)
// # ========================================================================= #
// # | Custom template close |
// # ========================================================================= #
custom_exit_bull = custom_exit_mode == "Number of bars" and [Link](bull and
strategy.position_size <= 0) >= i_custom_exit_nb_bars
custom_exit_bear = custom_exit_mode == "Number of bars" and [Link](bear and
strategy.position_size >= 0) >= i_custom_exit_nb_bars
//plot([Link](bull and strategy.position_size <= 0), title = "test", display
= display.data_window)
if strategy.position_size > 0 and custom_exit_bull and close_all_longs
[Link](id='Long', alert_message=i_alert_txt_exit_custom_long,
comment='Custom Close Signal\nClose Long')
alert(i_alert_txt_exit_custom_long, alert.freq_once_per_bar_close)
if strategy.position_size < 0 and custom_exit_bear and close_all_shorts
[Link](id='Short', alert_message=i_alert_txt_exit_custom_short,
comment='Custom Close Signal\nClose Short')
alert(i_alert_txt_exit_custom_short, alert.freq_once_per_bar_close)
// # ========================================================================= #
// # | SL/TP1/TP2 exits |
// # ========================================================================= #
if strategy.position_size > 0 and close_all_longs
[Link](id='Exit Long SL/TP', from_entry='Long', stop=useSL ?
final_SL_Long : na, limit = useTakeProfit ? TP1longPrice : na, comment_loss = "Exit
SL Long", alert_loss = i_alert_txt_exit_SL_long, comment_profit = "Exit TP Long",
alert_profit = i_alert_txt_exit_TP1_long)
if strategy.position_size < 0 and close_all_shorts
[Link](id='Exit Short SL/TP', from_entry='Short', stop=useSL ?
final_SL_Short : na, limit = useTakeProfit ? TP1shortPrice : na, comment_loss =
"Exit SL Short", alert_loss = i_alert_txt_exit_SL_short, comment_profit = "Exit TP
Short", alert_profit = i_alert_txt_exit_TP1_short)
// // Close all Longs only
// if not okToTradeInSession and close_all_longs and longs_opened_in_session
// [Link](id="Long")
// // Close all Shorts only
// if not okToTradeInSession and close_all_shorts and shorts_opened_in_session
// [Link](id="Short")
// Close all positions at the end of each session regardeless of their profit/loss
if not okToTradeInSession and close_all and trades_opened
strategy.close_all()
// Flatten strategy when max losing streak is reached
close_strat = not okToTradeWeekly or not okToTradeLossStreak or not
okToTradeWinStreak or not TradeDateIsAllowed()
if close_strat
// close all existing orders
strategy.close_all()
// Colour code the candles
bclr = not clrBars ? na : strategy.position_size == 0 ? [Link] : longs_opened ?
[Link] : shorts_opened ? [Link] : [Link]
barcolor(bclr, title='Trade State Bar Colouring')
// # ========================================================================= #
// # | Entry Price |
// # ========================================================================= #
plot(strategy.position_size != 0 ? strategy.position_avg_price : na, title = "Entry
Price", style = plot.style_circles, linewidth = 2)
// # ========================================================================= #
// # | Table |
// # ========================================================================= #
f_location() =>
_loc = ""
if _table_location == "TOP LEFT"
_loc := position.top_left
else if _table_location == "TOP CENTER"
_loc := position.top_center
else if _table_location == "TOP RIGHT"
_loc := position.top_right
else if _table_location == "BOTTOM LEFT"
_loc := position.bottom_left
else if _table_location == "BOTTOM CENTER"
_loc := position.bottom_center
else if _table_location == "BOTTOM RIGHT"
_loc := position.bottom_right
_loc
var table_location = f_location()
var current_trades_table = [Link](position = table_location,
columns = 8,
rows = 10,
bgcolor = table_header_bg_color,
frame_color = table_frame_color,
frame_width = table_frame_width,
border_color = table_border_color,
border_width = table_border_width
)
table_txt_size = switch _table_txt_size
"Tiny" => [Link]
"Small" => [Link]
"Normal" => [Link]
"Large" => [Link]
"Huge" => [Link]
tradeDirection(_size) =>
_size < 0 ? "Short" : "Long"
var int nb_row = 0
// Functions from the refman V5
// Get the biggest max trade run up value from all of the open trades.
maxOpenTradeRunUp() =>
maxRunup = 0.0
for tradeNo = 0 to [Link] - 1
maxRunup := [Link](maxRunup, [Link].max_runup(tradeNo))
result = maxRunup
// Get the biggest max trade drawdown value from all of the open trades.
maxTradeDrawDown() =>
maxDrawdown = 0.0
for tradeNo = 0 to [Link] - 1
maxDrawdown := [Link](maxDrawdown,
[Link].max_drawdown(tradeNo))
result = maxDrawdown
// Calculate open profit or loss for the open positions.
tradeOpenPL() =>
sumProfit = 0.0
for tradeNo = 0 to [Link] - 1
sumProfit += [Link](tradeNo)
result = sumProfit
// Calculate avg entry price for the open positions.
tradeAvgEntryPrice() =>
avgProfit = 0.0
for tradeNo = 0 to [Link] - 1
avgProfit += [Link].entry_price(tradeNo)
result = nz(avgProfit / [Link])
// Return the number of opened longs and shorts
tradeOpenNbLongsShorts() =>
nbLongs = 0
nbShorts = 0
for tradeNo = 0 to [Link] - 1
size = [Link](tradeNo)
if size > 0
nbLongs += 1
else
nbShorts += 1
[nbLongs, nbShorts]
if [Link] and [Link] > 0 and
display_last_trade_data
[Link](table_id = current_trades_table, column = 0, row = 0, text = "Trade
No", text_color = table_header_txt_color, text_halign = text.align_center,
text_valign = text.align_center, text_size = table_txt_size, bgcolor =
table_header_bg_color)
[Link](table_id = current_trades_table, column = 1, row = 0, text =
"Direction", text_color = table_header_txt_color, text_halign = text.align_center,
text_valign = text.align_center, text_size = table_txt_size, bgcolor =
table_header_bg_color)
[Link](table_id = current_trades_table, column = 2, row = 0, text = "Entry
Price", text_color = table_header_txt_color, text_halign = text.align_center,
text_valign = text.align_center, text_size = table_txt_size, bgcolor =
table_header_bg_color)
[Link](table_id = current_trades_table, column = 3, row = 0, text = "Entry
Time", text_color = table_header_txt_color, text_halign = text.align_center,
text_valign = text.align_center, text_size = table_txt_size, bgcolor =
table_header_bg_color)
[Link](table_id = current_trades_table, column = 4, row = 0, text =
"Profit/Loss", text_color = table_header_txt_color, text_halign =
text.align_center, text_valign = text.align_center, text_size = table_txt_size,
bgcolor = table_header_bg_color)
[Link](table_id = current_trades_table, column = 5, row = 0, text = "Max
Drawdown", text_color = table_header_txt_color, text_halign = text.align_center,
text_valign = text.align_center, text_size = table_txt_size, bgcolor =
table_header_bg_color)
[Link](table_id = current_trades_table, column = 6, row = 0, text = "Max
RunUp", text_color = table_header_txt_color, text_halign = text.align_center,
text_valign = text.align_center, text_size = table_txt_size, bgcolor =
table_header_bg_color)
[Link](table_id = current_trades_table, column = 7, row = 0, text =
"Equity", text_color = table_header_txt_color, text_halign = text.align_center,
text_valign = text.align_center, text_size = table_txt_size, bgcolor =
table_header_bg_color)
for tradeNo = 0 to [Link] - 1
nb_row := tradeNo + 1
str_tradeNo = [Link](nb_row)
str_direction = tradeDirection([Link](tradeNo))
str_entry_Price = [Link]([Link].entry_price(tradeNo),
[Link])
str_entry_Time = str.format_time([Link].entry_time(tradeNo),
"yyyy-MM-dd HH:mm", [Link])
str_profit_loss = [Link]([Link](tradeNo), "#.##")
str_max_DD = [Link]([Link].max_drawdown(tradeNo),
"#.##")
str_max_runUP = [Link]([Link].max_runup(tradeNo),
"#.##")
str_equity = [Link]([Link], "#.##") + " " +
strategy.account_currency
[Link](table_id = current_trades_table, column = 0, row = nb_row, text
= str_tradeNo, text_color = table_cell_txt_color, text_halign = text.align_center,
text_valign = text.align_center, text_size = table_txt_size, bgcolor =
table_cell_bg_color)
[Link](table_id = current_trades_table, column = 1, row = nb_row, text
= str_direction, text_color = table_cell_txt_color, text_halign =
text.align_center, text_valign = text.align_center, text_size = table_txt_size,
bgcolor = table_cell_bg_color)
[Link](table_id = current_trades_table, column = 2, row = nb_row, text
= str_entry_Price, text_color = table_cell_txt_color, text_halign =
text.align_center, text_valign = text.align_center, text_size = table_txt_size,
bgcolor = table_cell_bg_color)
[Link](table_id = current_trades_table, column = 3, row = nb_row, text
= str_entry_Time, text_color = table_cell_txt_color, text_halign =
text.align_center, text_valign = text.align_center, text_size = table_txt_size,
bgcolor = table_cell_bg_color)
[Link](table_id = current_trades_table, column = 4, row = nb_row, text
= str_profit_loss, text_color = table_cell_txt_color, text_halign =
text.align_center, text_valign = text.align_center, text_size = table_txt_size,
bgcolor = table_cell_bg_color)
[Link](table_id = current_trades_table, column = 5, row = nb_row, text
= str_max_DD, text_color = table_cell_txt_color, text_halign = text.align_center,
text_valign = text.align_center, text_size = table_txt_size, bgcolor =
table_cell_bg_color)
[Link](table_id = current_trades_table, column = 6, row = nb_row, text
= str_max_runUP, text_color = table_cell_txt_color, text_halign =
text.align_center, text_valign = text.align_center, text_size = table_txt_size,
bgcolor = table_cell_bg_color)
[Link](table_id = current_trades_table, column = 7, row = nb_row, text
= str_equity, text_color = table_cell_txt_color, text_halign = text.align_center,
text_valign = text.align_center, text_size = table_txt_size, bgcolor =
table_cell_bg_color)
// display Sum if there is more than 1 trade opened
if [Link] > 1 and nb_row == [Link]
// Creating the Total merged row
[Link](table_id = current_trades_table, column = 0, row =
[Link] + 1, text = "Total", text_color = table_header_txt_color,
text_halign = text.align_center, text_valign = text.align_center, text_size =
table_txt_size, bgcolor = table_header_bg_color)
table.merge_cells(current_trades_table, 0, [Link] + 1, 7,
[Link] + 1)
// Displaying the total
LastRow = [Link] + 2
str_nb_opened_trades = "Opened trades: " +
[Link]([Link])
[nbLongs, nbShorts] = tradeOpenNbLongsShorts()
str_nbLongsShorts = ""
if nbLongs > 0
str_nbLongsShorts := "Opened Longs: " + [Link](nbLongs)
if nbShorts > 0
str_nbLongsShorts := str_nbLongsShorts + "\n"
if nbShorts > 0
str_nbLongsShorts := str_nbLongsShorts + "Opened Shorts: " +
[Link](nbShorts)
str_avg_entry_price = [Link](tradeAvgEntryPrice(), "#.##")
str_last_entry_Time = "Last Opened Trade Time: " +
str.format_time([Link].entry_time([Link] - 1), "yyyy-MM-
dd HH:mm", [Link])
str_sum_profit_loss = [Link](tradeOpenPL(), "#.##")
str_max_DD = [Link](maxTradeDrawDown(), "#.##")
str_max_runUP = [Link](maxOpenTradeRunUp(), "#.##")
str_equity = [Link]([Link], "#.##") + " " +
strategy.account_currency
[Link](table_id = current_trades_table, column = 0, row = LastRow, text
= str_nb_opened_trades, text_color = table_cell_txt_color, text_halign =
text.align_center, text_valign = text.align_center, text_size = table_txt_size,
bgcolor = table_cell_bg_color)
[Link](table_id = current_trades_table, column = 1, row = LastRow, text
= str_nbLongsShorts, text_color = table_cell_txt_color, text_halign =
text.align_center, text_valign = text.align_center, text_size = table_txt_size,
bgcolor = table_cell_bg_color)
[Link](table_id = current_trades_table, column = 2, row = LastRow, text
= str_avg_entry_price, text_color = table_cell_txt_color, text_halign =
text.align_center, text_valign = text.align_center, text_size = table_txt_size,
bgcolor = table_cell_bg_color)
[Link](table_id = current_trades_table, column = 3, row = LastRow, text
= str_last_entry_Time, text_color = table_cell_txt_color, text_halign =
text.align_center, text_valign = text.align_center, text_size = table_txt_size,
bgcolor = table_cell_bg_color)
[Link](table_id = current_trades_table, column = 4, row = LastRow, text
= str_sum_profit_loss, text_color = table_cell_txt_color, text_halign =
text.align_center, text_valign = text.align_center, text_size = table_txt_size,
bgcolor = table_cell_bg_color)
[Link](table_id = current_trades_table, column = 5, row = LastRow, text
= str_max_DD, text_color = table_cell_txt_color, text_halign = text.align_center,
text_valign = text.align_center, text_size = table_txt_size, bgcolor =
table_cell_bg_color)
[Link](table_id = current_trades_table, column = 6, row = LastRow, text
= str_max_runUP, text_color = table_cell_txt_color, text_halign =
text.align_center, text_valign = text.align_center, text_size = table_txt_size,
bgcolor = table_cell_bg_color)
[Link](table_id = current_trades_table, column = 7, row = LastRow, text
= str_equity, text_color = table_cell_txt_color, text_halign = text.align_center,
text_valign = text.align_center, text_size = table_txt_size, bgcolor =
table_cell_bg_color)
//[Link](table_id = current_trades_table, column = 7, row = LastRow,
text = str_equity, text_color = table_cell_txt_color, text_halign =
text.align_center, text_valign = text.align_center, text_size = table_txt_size,
bgcolor = table_cell_bg_color)
// // # ========================================================================= #
// // # | PIE CHART |
// // # ========================================================================= #
// r = [Link] (0 ,"*Inside radius* ",minval=0,maxval=50,step=10
,inline="3")
// R = [Link] (120 ,"*Outside radius*",minval=80,maxval=200,step=10
,tooltip="🔘 Radius of insider and outer circle \nNOTE🔰\n*If this larger radius
exceeds the allowed limit,\nthe chart may disappear So, to solve this problem,
shift the graph to the leftside *👇" ,inline="3")
// w = [Link] (10 ,"|Overlap|",minval=0,maxval=10,step=2
,inline="4")
// p_x = [Link] (-50 ,"<<==Shift==>> " ,step=50
,tooltip="Overlap:Lines Thickness \n shift: (-)shift to leftside _OR_ rightside(+)
"
,inline="4")
// color CLR = na
// win_rate = [Link](([Link] / [Link]) * 100, 2)
// loss_rate = [Link](([Link] / [Link]) * 100, 2)
// C1 = int(win_rate * 360 / 100)
// C2 = C1 + int(loss_rate * 360 / 100)
// for i = 0 to 360 by 1
// x0 = int(r*[Link]([Link](i)))
// y0 = int(r*[Link]([Link](i)))
// x = int(R*[Link]([Link](i)))
// y = int(R*[Link]([Link](i)))
// CLR := i < C1 ? [Link] : i < C2 ? [Link] : [Link]
// if [Link] and display_pie_chart
// line = [Link](bar_index+p_x+R+x0 , close+y0 , bar_index+p_x+ x+R,
close + y , color= CLR ,style= w==0?
line.style_arrow_right:line.style_solid, extend = [Link], width=w)
// L1 =[Link](bar_index+p_x+R ,close ,"Winners/Losers \n🔎
Distribution🔍" , color=[Link]
,style=label.style_label_center,textcolor=[Link],textalign=text.align_c
enter,size=[Link])
// if display_pie_chart and [Link] > 0
// L2=[Link](bar_index+p_x+R+ int( (r+R)/2*[Link]([Link](C1/2)))
,close+ int( (r+R)/2*[Link]([Link](C1/2))) ,"Winners = "+
[Link](win_rate) + " %" ,style=
label.style_none,textcolor=[Link] ,textalign=text.align_center
,size=[Link] ,tooltip="Win Rate")
// [Link](L2[1])
// L3=[Link](bar_index+p_x+R+ int(
(r+R)/2*[Link]([Link]((C1+C2)/2))),close+ int(
(r+R)/2*[Link]([Link]((C1+C2)/2))) ,"ETH.D = "+ [Link](loss_rate)
+ " %" ,style=
label.style_none,textcolor=[Link] ,textalign=text.align_center
,size=[Link],tooltip="Loss Rate")
// [Link](L3[1])
if strategy.position_size == 0
or (strategy.position_size > 0 and strategy.position_size[1] < 0)
or (strategy.position_size < 0 and strategy.position_size[1] > 0)
is_TP1_REACHED := false
SL_BE_REACHED := false