0% found this document useful (0 votes)
25 views19 pages

Ultimate Strategy Template (Advanced Edition)

This document is a Pine Script code for a trading strategy that implements a Moving Average Cross indicator. It includes various customizable parameters for trade management, risk management, and alerts, allowing users to define entry and exit conditions, stop losses, and take profits. The script also features options for limiting daily and weekly trades, as well as tracking performance metrics like drawdown and losing streaks.

Uploaded by

tewaf88486
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views19 pages

Ultimate Strategy Template (Advanced Edition)

This document is a Pine Script code for a trading strategy that implements a Moving Average Cross indicator. It includes various customizable parameters for trade management, risk management, and alerts, allowing users to define entry and exit conditions, stop losses, and take profits. The script also features options for limiting daily and weekly trades, as well as tracking performance metrics like drawdown and losing streaks.

Uploaded by

tewaf88486
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 19

//@version=5

// This source code is subject to the terms of the Mozilla Public License 2.0 at
https://mozilla.org/MPL/2.0/
// © 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 = input.string(title='MA1 type', defval='SMA', options=['RMA', 'SMA',


'EMA'])
// length_ma1 = input(10, title='[ALL but VWAP] MA1 length')

// type_ma2 = input.string(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 = ta.rma(src, length)
// sma_1 = ta.sma(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 = ta.crossover(MA1, MA2)
// sell = ta.crossunder(MA1, MA2)

// plot(MA1, color=color.new(color.green, 0), title='Plot MA1', linewidth=3)


// plot(MA2, color=color.new(color.red, 0), title='Plot MA2', linewidth=3)

// plotshape(buy, title='LONG SIGNAL', style=shape.circle,


location=location.belowbar, color=color.new(color.green, 0), size=size.normal)
// plotshape(sell, title='SHORT SIGNAL', style=shape.circle,
location=location.abovebar, color=color.new(color.red, 0), size=size.normal)

// /////////////////////////// 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=strategy.commission.percent,
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_ = input.source(close, title='Data source', group = "General")

// Custom close signal


custom_close = input.bool(false, title='Use Custom Close?', group = "General")

// Last trades data displayed in a table


display_last_trade_data = input.bool(true, title = "Display the current opened
trades data", group = "Table")

_table_location = input.string(title="Table Location", defval="TOP RIGHT",


options=["TOP LEFT", "TOP CENTER", "TOP RIGHT", "BOTTOM LEFT", "BOTTOM CENTER",
"BOTTOM RIGHT"], group = "Table")
_table_txt_size = input.string("Normal", title = "Txt Size", options=["Tiny",
"Small", "Normal", "Large", "Huge"], group = "Table")
table_cell_bg_color = input.color(color.white, title = "Cells Background Color",
group = "Table", inline = "table_cells")
table_cell_txt_color = input.color(color.black, title = "Cells Text Color", group =
"Table", inline = "table_cells")
table_frame_color = input.color(color.black, title = "Frame Color", group =
"Table", inline = "table_frame")
table_frame_width = input.int(1, title = "Frame Width", minval = 0, group =
"Table", inline = "table_frame")
table_border_color = input.color(color.black, title = "Border Color", group =
"Table", inline = "table_borders")
table_border_width = input.int(1, title = "Border Width", minval = 0, group =
"Table", inline = "table_borders")

table_header_bg_color = input.color(#0b3880, title = "Header Background Color",


group = "Table Header", inline = "header_color")
table_header_txt_color = input.color(color.white, title = "Header Text Color",
group = "Table Header", inline = "header_color")

// Pie Chart Winners/Losers


display_pie_chart = false//input.bool(true, title = "Display Pie Chart
Winners/Losers", group = "Pie Chart")

// ————— Bar Coloring


clrBars = input.bool(true, title='Colour Candles to Trade Order state',
group='Coloring')

CloseSession = input.bool(false, title='Close positions at market at the end of


each session ?', group='Session')
Session = input.session(title='Trading Session', defval='0000-2345',
group='Session')

OpenDirection = input.string(defval='ALL', title='Open Trading Direction',


options=['ALL', 'LONG', 'SHORT'], group='Direction')
CloseDirection = input.string(defval='ALL', title='Close Trading Direction',
options=['ALL', 'LONG', 'SHORT'], group='Direction')

closeOnOpposite = input.bool(true, title='Close on Opposite Signal',


group='Strategy')

// ————— Date range filtering


DateFilter = input.bool(false, 'Date Range Filtering', group='Date')

// ————— Syntax coming from https://www.tradingview.com/blog/en/new-parameter-for-


date-input-added-to-pine-21812/
i_startTime = input.time(defval=timestamp('01 Jan 2019 13:30 +0000'), title='Start
Time', group='Date')
i_endTime = input.time(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 = input.bool(title='Set Max number of consecutive loss trades',
defval=false, group='Risk Management')
maxLosingStreak = input.int(title='Max of consecutive loss trades', defval=15,
minval=1, group='Risk Management')

setmaxWinStreak = input.bool(title='Set Max number of consecutive won trades',


defval=false, group='Risk Management')
maxWinStreak = input.int(title='Max Winning Streak Length', defval=15, minval=1,
group='Risk Management')

// ————— Set the max consecutive days with a loss


setmaxLosingDaysStreak = input.bool(title='Set MAX consecutive days with a loss in
a row', defval=false, group='Risk Management')
maxLosingDaysStreak = input.int(title='Max of consecutive days with a loss in a
row', defval=3, minval=1, group='Risk Management')

setMaxDrawdown = input.bool(title='Set Max Total DrawDown', defval=false,


group='Risk Management')
// ————— Input for the strategy's maximum drawdown (in % of strategy equity)
maxPercDd = input.int(title='Max Drawdown (%)', defval=10, minval=1, maxval=100,
group='Risk Management')

setMaxIntradayLoss = input.bool(title='Set Max Intraday Loss', defval=false,


group='Risk Management')
// ————— Input for the strategy's maximum intraday loss (in % of strategy equity)
maxIntradayLoss = input.int(title='Max Intraday Loss (%)', defval=3, minval=1,
maxval=100, group='Risk Management')

setNumberDailyTrades = input.bool(title='Limit the number of trades per day',


defval=false, group='Risk Management')
maxDailyTrades = input.int(title='Number MAX of daily trades', defval=10, minval=1,
maxval=100, group='Risk Management')

setNumberWeeklyTrades = input.bool(title='Limit the number of trades per week',


defval=false, group='Risk Management')
maxWeeklyTrades = input.int(title='Number MAX of weekly trades', defval=50,
minval=1, maxval=100, group='Risk Management')

// Hard Exit

// # ========================================================================= #
// # | Stop Loss |
// # ========================================================================= #

StopType = input.string(title='Stop Type Selection', defval='Percent',


options=['None', 'Percent', 'Trailing', 'ATR'], group='Stop Loss')
// ————— Percent
LossPerc = input.float(title='Stop Loss (%)', minval=0.0, step=0.5, defval=10,
group='Percent Stop Loss') * 0.01
TrailPerc = input.float(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 = input.int(title='Stop Length', defval=14, group='ATR Stop Loss')
riskRatioATR = input.float(defval=1, title='Risk Ratio', step=0.10, group='ATR Stop
Loss')

// # ========================================================================= #
// # | Take Profit |
// # ========================================================================= #

TakeProfitType = input.string(title='Take Profit Type Selection', defval='Percent',


options=['None', 'Percent', 'ATR'], group='Take Profit')
TP1_ratio = 100//input.float(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 = input.float(title='Take Profit (%)', minval=0.0, step=0.5, defval=5,
group='Take Profit 1') * 0.01
// ————— ATR
atrTakeProfitLength1 = input.int(title='Take Profit Length', defval=14, group='ATR
Take Profit 1', inline='ATR TP1')
rewardRatioATR1 = input.float(defval=2, title='Reward Ratio', step=0.10, group='ATR
Take Profit 1', inline='ATR TP1')

// # ========================================================================= #
// # | Stop Loss to Breakeven |
// # ========================================================================= #

use_sl_be = input.bool(false, title = "Use Stop Loss to Breakeven Mode?",


group = "Stop Loss Breakeven")
sl_be_mode = input.string("$", title = "Mode", options=["pips", "%", "$"],
group = "Stop Loss Breakeven")
sl_be_value = input.float(1, step = 0.1, minval = 0, title = "Stop Loss to
Breakeven +/- X", group = "Stop Loss Breakeven")

// # ========================================================================= #
// # | Custom Exit |
// # ========================================================================= #

custom_exit_mode = input.string(title='Custom Exit Type Selection',


defval='None', options=['None', 'Number of bars'], group='Custom Exit')
i_custom_exit_nb_bars = input.int(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 = shape.triangleup,
location = location.bottom,
color = color.new(color = color.green, transp = 0),
size = size.normal
)

plotshape(
series = bear and not bear[1],
title = "Sell",
style = shape.triangledown,
location = location.top,
color = color.new(color = color.red, transp = 0),
size = size.normal
)

// 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 = ta.valuewhen(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 = ta.valuewhen(condition=(bull and strategy.position_size <= 0),
source=close, occurrence=0)
entry_price_short = ta.valuewhen(condition=(bear and strategy.position_size >= 0),
source=close, occurrence=0)

// ————— RISK MANAGEMENT

condintradayloss = setMaxIntradayLoss ? maxIntradayLoss : 100


strategy.risk.max_intraday_loss(value=condintradayloss,
type=strategy.percent_of_equity)

condmaxdrawdown = setMaxDrawdown ? maxPercDd : 100


strategy.risk.max_drawdown(value=condmaxdrawdown, type=strategy.percent_of_equity)

// daily trades calculation

oktoTradeDaily = true

tradesIntradayCount = setNumberDailyTrades ? maxDailyTrades : BIG_NUMBER_COUNT


strategy.risk.max_intraday_filled_orders(count=tradesIntradayCount)

// weekly trades calculation


tradesLastWeek = 0

tradesLastWeek := if dayofweek == dayofweek.monday and dayofweek != dayofweek[1]


strategy.closedtrades[1] + strategy.opentrades[1]
else
tradesLastWeek[1]

// Calculate number of trades this week


weeklyTrades = strategy.closedtrades + strategy.opentrades - tradesLastWeek
okToTradeWeekly = setNumberWeeklyTrades ? weeklyTrades < maxWeeklyTrades : true

// consecutive loss days in a row


countConsLossDays = setmaxLosingDaysStreak ? maxLosingDaysStreak : BIG_NUMBER_COUNT
strategy.risk.max_cons_loss_days(countConsLossDays)

// Calculate the total losing streaks


// Check if there's a new losing trade that increased the streak
newLoss = strategy.losstrades > strategy.losstrades[1] and strategy.wintrades ==
strategy.wintrades[1] and strategy.eventrades == strategy.eventrades[1]
// Determine current losing streak length
streakLossLen = 0

streakLossLen := if newLoss
nz(streakLossLen[1]) + 1
else
if strategy.wintrades > strategy.wintrades[1] or strategy.eventrades >
strategy.eventrades[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 = strategy.wintrades > strategy.wintrades[1] and strategy.losstrades ==
strategy.losstrades[1] and strategy.eventrades == strategy.eventrades[1]

// Figure out current winning streak length


streakWinLen = 0

streakWinLen := if newWin
nz(streakWinLen[1]) + 1
else
if strategy.losstrades > strategy.losstrades[1] or strategy.eventrades >
strategy.eventrades[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


? math.max(nz(MaxReached, high), high)
: strategy.position_size < 0 ? math.min(nz(MaxReached,low), low) : na

//if strategy.position_size > 0


// stopValue = close * (1 - TrailPerc)
// longTrailStopPrice := math.max(stopValue, longTrailStopPrice)
//else
// longTrailStopPrice := 0

//if strategy.position_size < 0


// stopValue = close * (1 + TrailPerc)
// shortTrailStopPrice := math.min(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() => syminfo.mintick

// 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 = ta.atr(atrStopLength)
atr_tp1 = ta.atr(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=color.new(color.green, 0), style=plot.style_circles, linewidth=3, title='Long
Take Profit 1')

plot(series=strategy.position_size < 0 and useTakeProfit ? TP1shortPrice : na,


color=color.new(color.red, 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=color.new(color.green, 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 = strategy.opentrades.profit(strategy.opentrades - 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 math.abs(((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 math.abs(((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=color.new(color.red, 0), style=plot.style_cross, linewidth=2, title='Long
Stop Loss')

plot(series=strategy.position_size < 0 and useSL ? final_SL_Short : na,


color=color.new(color.red, 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=color.new(color.red, 100), title='ATR Stop Value')

// Session calculations
// The BarInSession function returns true when
// the current bar is inside the session parameter
BarInSession(sess) =>
time(timeframe.period, 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] ? color.new(color.green,


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: " + str.tostring(close) + " sl: " +
str.tostring(final_SL_Long) + " tp: " + str.tostring(TP1longPrice)
strategy.entry('Long', strategy.long, 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: " + str.tostring(close) + " sl: " +
str.tostring(final_SL_Short) + " tp: " + str.tostring(TP1shortPrice)
strategy.entry('Short', strategy.short, 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
strategy.close(id='Long', comment='Short Signal\nClose Long')

if closeOnOpposite and strategy.position_size < 0 and longCondition // and


open_all_longs
strategy.close(id='Short', comment='Long Signal\nClose Short')

// # ========================================================================= #
// # | Custom User-Defined close |
// # ========================================================================= #

if strategy.position_size > 0 and exit_bull and close_all_longs


strategy.close(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


strategy.close(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 ta.barssince(bull and


strategy.position_size <= 0) >= i_custom_exit_nb_bars
custom_exit_bear = custom_exit_mode == "Number of bars" and ta.barssince(bear and
strategy.position_size >= 0) >= i_custom_exit_nb_bars

//plot(ta.barssince(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


strategy.close(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


strategy.close(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

strategy.exit(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

strategy.exit(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
// strategy.close(id="Long")

// // Close all Shorts only


// if not okToTradeInSession and close_all_shorts and shorts_opened_in_session
// strategy.close(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 ? color.gray : longs_opened ?
color.lime : shorts_opened ? color.red : color.gray

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 = table.new(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" => size.tiny
"Small" => size.small
"Normal" => size.normal
"Large" => size.large
"Huge" => size.huge

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 strategy.opentrades - 1
maxRunup := math.max(maxRunup, strategy.opentrades.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 strategy.opentrades - 1
maxDrawdown := math.max(maxDrawdown,
strategy.opentrades.max_drawdown(tradeNo))
result = maxDrawdown

// Calculate open profit or loss for the open positions.


tradeOpenPL() =>
sumProfit = 0.0
for tradeNo = 0 to strategy.opentrades - 1
sumProfit += strategy.opentrades.profit(tradeNo)
result = sumProfit

// Calculate avg entry price for the open positions.


tradeAvgEntryPrice() =>

avgProfit = 0.0
for tradeNo = 0 to strategy.opentrades - 1
avgProfit += strategy.opentrades.entry_price(tradeNo)

result = nz(avgProfit / strategy.opentrades)

// Return the number of opened longs and shorts

tradeOpenNbLongsShorts() =>

nbLongs = 0
nbShorts = 0

for tradeNo = 0 to strategy.opentrades - 1

size = strategy.opentrades.size(tradeNo)
if size > 0
nbLongs += 1
else
nbShorts += 1

[nbLongs, nbShorts]

if barstate.islastconfirmedhistory and strategy.opentrades > 0 and


display_last_trade_data

table.cell(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)
table.cell(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)
table.cell(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)
table.cell(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)
table.cell(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)
table.cell(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)
table.cell(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)
table.cell(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 strategy.opentrades - 1

nb_row := tradeNo + 1

str_tradeNo = str.tostring(nb_row)
str_direction = tradeDirection(strategy.opentrades.size(tradeNo))
str_entry_Price = str.tostring(strategy.opentrades.entry_price(tradeNo),
format.mintick)
str_entry_Time = str.format_time(strategy.opentrades.entry_time(tradeNo),
"yyyy-MM-dd HH:mm", syminfo.timezone)
str_profit_loss = str.tostring(strategy.opentrades.profit(tradeNo), "#.##")
str_max_DD = str.tostring(strategy.opentrades.max_drawdown(tradeNo),
"#.##")
str_max_runUP = str.tostring(strategy.opentrades.max_runup(tradeNo),
"#.##")
str_equity = str.tostring(strategy.equity, "#.##") + " " +
strategy.account_currency

table.cell(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)
table.cell(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)
table.cell(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)
table.cell(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)
table.cell(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)
table.cell(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)
table.cell(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)
table.cell(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 strategy.opentrades > 1 and nb_row == strategy.opentrades

// Creating the Total merged row


table.cell(table_id = current_trades_table, column = 0, row =
strategy.opentrades + 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, strategy.opentrades + 1, 7,
strategy.opentrades + 1)

// Displaying the total

LastRow = strategy.opentrades + 2

str_nb_opened_trades = "Opened trades: " +


str.tostring(strategy.opentrades)

[nbLongs, nbShorts] = tradeOpenNbLongsShorts()


str_nbLongsShorts = ""

if nbLongs > 0
str_nbLongsShorts := "Opened Longs: " + str.tostring(nbLongs)
if nbShorts > 0
str_nbLongsShorts := str_nbLongsShorts + "\n"
if nbShorts > 0
str_nbLongsShorts := str_nbLongsShorts + "Opened Shorts: " +
str.tostring(nbShorts)

str_avg_entry_price = str.tostring(tradeAvgEntryPrice(), "#.##")


str_last_entry_Time = "Last Opened Trade Time: " +
str.format_time(strategy.opentrades.entry_time(strategy.opentrades - 1), "yyyy-MM-
dd HH:mm", syminfo.timezone)
str_sum_profit_loss = str.tostring(tradeOpenPL(), "#.##")
str_max_DD = str.tostring(maxTradeDrawDown(), "#.##")
str_max_runUP = str.tostring(maxOpenTradeRunUp(), "#.##")
str_equity = str.tostring(strategy.equity, "#.##") + " " +
strategy.account_currency

table.cell(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)
table.cell(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)
table.cell(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)
table.cell(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)
table.cell(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)
table.cell(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)
table.cell(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)
table.cell(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)
//table.cell(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 = input.int (0 ,"*Inside radius* ",minval=0,maxval=50,step=10


,inline="3")
// R = input.int (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 = input.int (10 ,"|Overlap|",minval=0,maxval=10,step=2
,inline="4")
// p_x = input.int (-50 ,"<<==Shift==>> " ,step=50
,tooltip="Overlap:Lines Thickness \n shift: (-)shift to leftside _OR_ rightside(+)
"
,inline="4")

// color CLR = na

// win_rate = math.round((strategy.wintrades / strategy.closedtrades) * 100, 2)


// loss_rate = math.round((strategy.losstrades / strategy.closedtrades) * 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*math.sin(math.toradians(i)))
// y0 = int(r*math.cos(math.toradians(i)))
// x = int(R*math.sin(math.toradians(i)))
// y = int(R*math.cos(math.toradians(i)))

// CLR := i < C1 ? color.lime : i < C2 ? color.red : color.fuchsia

// if barstate.islast and display_pie_chart

// line = line.new(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 = extend.none, width=w)

// L1 =label.new(bar_index+p_x+R ,close ,"Winners/Losers \n🔎


Distribution🔍" , color=color.black
,style=label.style_label_center,textcolor=color.yellow,textalign=text.align_c
enter,size=size.small)

// if display_pie_chart and strategy.closedtrades > 0

// L2=label.new(bar_index+p_x+R+ int( (r+R)/2*math.sin(math.toradians(C1/2)))


,close+ int( (r+R)/2*math.cos(math.toradians(C1/2))) ,"Winners = "+
str.tostring(win_rate) + " %" ,style=
label.style_none,textcolor=color.white ,textalign=text.align_center
,size=size.large ,tooltip="Win Rate")
// label.delete(L2[1])

// L3=label.new(bar_index+p_x+R+ int(
(r+R)/2*math.sin(math.toradians((C1+C2)/2))),close+ int(
(r+R)/2*math.cos(math.toradians((C1+C2)/2))) ,"ETH.D = "+ str.tostring(loss_rate)
+ " %" ,style=
label.style_none,textcolor=color.white ,textalign=text.align_center
,size=size.normal,tooltip="Loss Rate")
// label.delete(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

You might also like