ٹرپل انڈیکیٹر مومنٹم انورسر حکمت عملی

مصنف:چاؤ ژانگ، تاریخ: 2023-10-26 16:12:33
ٹیگز:

img

جائزہ

اس حکمت عملی میں مارکیٹ میں انتہائی نقل و حرکت کا پتہ لگانے کے لئے تین اوپن سورس پبلک اشارے - ٹرینڈ جادو ، سکس مومنٹم ، اور مجموعی ڈیلٹا حجم کو یکجا کیا گیا ہے۔ یہ تین اشارے ایک دوسرے کی تصدیق کرتے ہیں اور مارکیٹ میں الٹ پوائنٹس کی مؤثر طریقے سے نشاندہی کرسکتے ہیں۔ یہ حکمت عملی پوزیشنوں کو کھولنے کی کوشش کرتی ہے جب تینوں اشارے بیک وقت خرید / فروخت کے سگنل دیتے ہیں ، تاکہ کم خطرہ والی رفتار الٹ ٹریڈنگ کو نافذ کیا جاسکے۔

حکمت عملی منطق

یہ حکمت عملی 1 منٹ یا 3 منٹ کے موم بتی چارٹ کا استعمال کرتی ہے، بندش کی قیمت سے 1.5 گنا ATR کے سٹاپ نقصان کے ساتھ.

سب سے پہلے ، ٹرینڈ میجک اشارے ، اے ٹی آر اشارے کے ساتھ مل کر ، مارکیٹ کے رجحان اور اتار چڑھاؤ کا جائزہ لیتا ہے۔ جب سی سی آئی اشارے 0 سے اوپر ہوتا ہے تو ، اس سے یہ ظاہر ہوتا ہے کہ اتار چڑھاؤ ہو رہا ہے۔ اس وقت ، اگر اے ٹی آر اشارے کی پوزیشن قیمت سے زیادہ ہے تو ، اس سے یہ ظاہر ہوتا ہے کہ یہ ایک بڑھتی ہوئی رجحان ہے ، دوسری صورت میں یہ ایک نیچے کی رجحان کی نشاندہی کرتا ہے۔

دوسری بات ، کمپریس مومنٹم اشارے کا فیصلہ کرتا ہے کہ جب اتار چڑھاؤ بڑھتا ہے اور کم ہوتا ہے۔ جب بولنگر بینڈ کو کیلٹنر چینلز کے اندر سکیڑ دیا جاتا ہے تو ، اس سے یہ ظاہر ہوتا ہے کہ مارکیٹ کی اتار چڑھاؤ کم ہو رہی ہے۔ اس کمپریشن کی حالت کے بعد کچھ عرصے تک جاری رہتا ہے ، بولنگر بینڈ ناگزیر طور پر کیلٹنر چینلز کو توڑ دیں گے ، جس سے قیمتوں میں انتہائی اضافہ یا کمی واقع ہوگی۔

آخر میں ، مجموعی ڈیلٹا حجم اشارے خرید اور فروخت کے تجارتی حجم کے درمیان فرق کا حساب لگاتے ہوئے مارکیٹ فورسز کا نتیجہ اخذ کرتا ہے۔ جب تجارتی حجم میں خریدار کی طرف سے غلبہ حاصل ہوتا ہے تو ، اس سے یہ ظاہر ہوتا ہے کہ تیزی کی قوتیں مضبوط ہورہی ہیں۔

جب تینوں اشارے ایک ہی وقت میں سگنل دیتے ہیں تو ، اس کی تصدیق ہوتی ہے کہ مارکیٹ ایک الٹ نقطہ کے قریب ہے۔ اس وقت ، موجودہ سمت کے خلاف تجارت کے لئے پوزیشن کھولیں۔

فوائد کا تجزیہ

  • تصدیق کرنے کے لئے متعدد اشارے کا استعمال کرتے ہوئے مؤثر طریقے سے جھوٹے بریک آؤٹ سے بچ سکتے ہیں
  • توڑنے بولنگر بینڈ اور Keltner چینلز ایک نسبتا اعلی جیت کی شرح ہے
  • حجم کی تبدیلی قوتوں میں تبدیلی کی نشاندہی کرتی ہے ، جو الٹ سگنل کی حمایت کرتی ہے
  • ریورس ٹریڈنگ میں نسبتاً کم خطرات ہیں اور یہ قلیل مدتی کارروائیوں کے لیے موزوں ہے۔

خطرے کا تجزیہ

  • ایک ہی ٹائم فریم پر ٹریڈنگ میں پھنس جانے کے اہم خطرات ہیں
  • پہلی بریک آؤٹ پوائنٹ پر واپسی نہیں ہوسکتی ہے، زیادہ سے زیادہ اندراج کو یاد کرنے کا خطرہ
  • رجحان کے خلاف تجارت سے بچنے کے لئے طویل وقت کے فریموں کی بھی نگرانی کرنے کی ضرورت ہے
  • اہم رجحان کی سمت کی بنیاد پر صرف طویل یا مختصر جانے کا انتخاب کر سکتے ہیں
  • جب رجحان واضح نہیں ہوتا ہے تو تجارت سے بچنے کے لئے ADX شرائط مقرر کرسکتے ہیں

اصلاح کی ہدایات

  • ٹرینڈ کا تعین کرنے کے لئے طویل مدت کا استعمال کرتے ہوئے کراس ٹائم فریم کی توثیق شامل کریں
  • پروڈکٹ اسکریننگ شامل کریں، زیادہ اتار چڑھاؤ کے ساتھ مصنوعات کا انتخاب کریں
  • اشارے کے اثرات کو بہتر بنانے کے لئے اشارے کے پیرامیٹرز کو ایڈجسٹ کریں
  • جیت کی شرح کو بہتر بنانے کے لئے مشین لرننگ ماڈلز کو شامل کریں
  • جذبات کے اشارے کو یکجا کریں، مارکیٹ کے جذبات میں انتہا پسندی کے خلاف تجارت

نتیجہ

یہ حکمت عملی مارکیٹ کے رجحانات کا تعین کرنے کے لئے متعدد اشارے استعمال کرتی ہے ، اور جب متعدد اشارے مستقل سگنل دیتے ہیں تو پوزیشنیں کھولتی ہے۔ ایک اشارے کے مقابلے میں ، یہ زیادہ غلط سگنل کو فلٹر کرسکتا ہے۔ لیکن چونکہ یہ صرف ایک ہی ٹائم فریم پر کام کرتا ہے ، لہذا یہ اب بھی رجحان سازی کی منڈیوں میں پھنس جانے کا شکار ہے۔ اگلے اقدامات کارکردگی کو بہتر بنانے کے لئے مشین لرننگ جیسی زیادہ جدید تکنیکوں کو شامل کرنا ، یا طویل ٹائم فریم اشارے کو یکجا کرنا ہوسکتے ہیں تاکہ رجحان کے خلاف تجارت سے بچنے کے ل the ، حکمت عملی کو زیادہ مارکیٹ کے حالات میں قابل عمل بنایا جاسکے۔


/*backtest
start: 2023-09-25 00:00:00
end: 2023-10-25 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © myn

//@version=5
strategy('Strategy Myth-Busting #11 - TrendMagic+SqzMom+CDV - [MYN]', max_bars_back=5000, overlay=true, pyramiding=0, initial_capital=1000, currency='USD', default_qty_type=strategy.percent_of_equity, default_qty_value=1, commission_value=0.075, use_bar_magnifier = false)

// HA to Regular Candlestick resolover
useHA = input.bool(true, "Use Heiken Ashi")

CLOSE = close
OPEN = open
HIGH = high
LOW = low

CLOSE := useHA ? (OPEN + CLOSE + HIGH + LOW) / 4 : CLOSE
OPEN := useHA ? na(OPEN[1]) ? (OPEN + CLOSE) / 2: (OPEN[1] + CLOSE[1]) / 2 : OPEN
HIGH := useHA ? math.max(HIGH, math.max(OPEN, CLOSE)) : HIGH
LOW := useHA ? math.min(LOW, math.min(OPEN, CLOSE)) : LOW

isCrypto = input.bool(true, "Is Crypto?")

// Functions
f_priorBarsSatisfied(_objectToEval, _numOfBarsToLookBack) => 
    returnVal = false
    for i = 0 to _numOfBarsToLookBack
        if (_objectToEval[i] == true)
            returnVal = true



/////////////////////////////////////
//* Put your strategy logic below *//
/////////////////////////////////////

// Trend Magic by KivancOzbilgic
//░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

period = input(20, 'CCI period')
coeff = input(2, 'ATR Multiplier')
AP = input(5, 'ATR Period')
ATR = ta.sma(ta.tr, AP)
src = CLOSE
upT = LOW - ATR * coeff
downT = HIGH + ATR * coeff
MagicTrend = 0.0
MagicTrend := ta.cci(src, period) >= 0 ? upT < nz(MagicTrend[1]) ? nz(MagicTrend[1]) : upT : downT > nz(MagicTrend[1]) ? nz(MagicTrend[1]) : downT
color1 = ta.cci(src, period) >= 0 ? #0022FC : #FC0400
plot(MagicTrend, color=color1, linewidth=3)
alertcondition(ta.cross(CLOSE, MagicTrend), title='Cross Alert', message='Price - MagicTrend Crossing!')
alertcondition(ta.crossover(LOW, MagicTrend), title='CrossOver Alarm', message='BUY SIGNAL!')
alertcondition(ta.crossunder(HIGH, MagicTrend), title='CrossUnder Alarm', message='SELL SIGNAL!')

i_numLookbackBarsTM = input(17,title="Number of bars to look back to validate Trend Magic trend")
//trendMagicEntryLong = trendMagicEntryConditionLong and f_priorBarsSatisfied(trendMagicEntryConditionLong,i_numLookbackBarsTM)
//trendMagicEntryShort = trendMagicEntryConditionShort and f_priorBarsSatisfied(trendMagicEntryConditionShort,i_numLookbackBarsTM)

trendMagicEntryConditionLong = ta.cci(src, period) >= 0 and src > MagicTrend + (isCrypto ? 5 : 0 )
trendMagicEntryConditionShort = ta.cci(src, period) < 0 and src < MagicTrend - (isCrypto ? 5 : 0) 

trendMagicEntryLong = trendMagicEntryConditionLong and ta.barssince(trendMagicEntryConditionShort) > i_numLookbackBarsTM 
trendMagicEntryShort = trendMagicEntryConditionShort and ta.barssince(trendMagicEntryConditionLong) > i_numLookbackBarsTM 


// Squeeze Momentum by LazyBear
//░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░


length = input(10, title='BB Length', group="Squeeze Momentum")
mult = input(2.0, title='BB MultFactor')
lengthKC = input(10, title='KC Length')
multKC = input(1.5, title='KC MultFactor')

useTrueRange = input(true, title='Use TrueRange (KC)')

// Calculate BB
source = CLOSE
basis = ta.sma(source, length)
dev = multKC * ta.stdev(source, length)
upperBB = basis + dev
lowerBB = basis - dev

// Calculate KC
ma = ta.sma(source, lengthKC)
range_1 = useTrueRange ? ta.tr : HIGH - LOW
rangema = ta.sma(range_1, lengthKC)
upperKC = ma + rangema * multKC
lowerKC = ma - rangema * multKC

sqzOn = lowerBB > lowerKC and upperBB < upperKC
sqzOff = lowerBB < lowerKC and upperBB > upperKC
noSqz = sqzOn == false and sqzOff == false

val = ta.linreg(source - math.avg(math.avg(ta.highest(HIGH, lengthKC), ta.lowest(LOW, lengthKC)), ta.sma(CLOSE, lengthKC)), lengthKC, 0)

iff_1 = val > nz(val[1]) ? color.lime : color.green
iff_2 = val < nz(val[1]) ? color.red : color.maroon
bcolor = val > 0 ? iff_1 : iff_2
scolor = noSqz ? color.blue : sqzOn ? color.black : color.gray
//plot(val, color=bcolor, style=plot.style_histogram, linewidth=4)
//plot(0, color=scolor, style=plot.style_cross, linewidth=2)

i_numLookbackBarsSM = input(14,title="Number of bars to look back to validate Sqz Mom trend")
//sqzmomEntryLong = val > 0 and f_priorBarsSatisfied(val > 0,i_numLookbackBarsSM)
//sqzmomEntryShort = val < 0 and f_priorBarsSatisfied(val < 0,i_numLookbackBarsSM)


sqzmomEntryConditionLong = val > 0 
sqzmomEntryConditionShort = val < 0
sqzmomEntryLong = sqzmomEntryConditionLong and ta.barssince(sqzmomEntryConditionShort) > i_numLookbackBarsSM 
sqzmomEntryShort = sqzmomEntryConditionShort and ta.barssince(sqzmomEntryConditionLong) > i_numLookbackBarsSM 




// Cumulative Delta Volume by LonesomeTheBlue
//░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

linestyle = input.string(defval='Candle', title='Style', options=['Candle', 'Line'], group="Cumlative Delta Volume")
hacandle = input(defval=true, title='Heikin Ashi Candles?')
showma1 = input.bool(defval=false, title='SMA 1', inline='ma1')
ma1len = input.int(defval=50, title='', minval=1, inline='ma1')
ma1col = input.color(defval=color.lime, title='', inline='ma1')
showma2 = input.bool(defval=false, title='SMA 2', inline='ma2')
ma2len = input.int(defval=200, title='', minval=1, inline='ma2')
ma2col = input.color(defval=color.red, title='', inline='ma2')
showema1 = input.bool(defval=false, title='EMA 1', inline='ema1')
ema1len = input.int(defval=50, title='', minval=1, inline='ema1')
ema1col = input.color(defval=color.lime, title='', inline='ema1')
showema2 = input.bool(defval=false, title='EMA 2', inline='ema2')
ema2len = input.int(defval=200, title='', minval=1, inline='ema2')
ema2col = input.color(defval=color.red, title='', inline='ema2')
colorup = input.color(defval=color.lime, title='Body', inline='bcol')
colordown = input.color(defval=color.red, title='', inline='bcol')
bcolup = input.color(defval=#74e05e, title='Border', inline='bocol')
bcoldown = input.color(defval=#ffad7d, title='', inline='bocol')
wcolup = input.color(defval=#b5b5b8, title='Wicks', inline='wcol')
wcoldown = input.color(defval=#b5b5b8, title='', inline='wcol')

tw = HIGH - math.max(OPEN, CLOSE)
bw = math.min(OPEN, CLOSE) - LOW
body = math.abs(CLOSE - OPEN)

_rate(cond) =>
    ret = 0.5 * (tw + bw + (cond ? 2 * body : 0)) / (tw + bw + body)
    ret := nz(ret) == 0 ? 0.5 : ret
    ret

deltaup = volume * _rate(OPEN <= CLOSE)
deltadown = volume * _rate(OPEN > CLOSE)
delta = CLOSE >= OPEN ? deltaup : -deltadown
cumdelta = ta.cum(delta)
float ctl = na
float o = na
float h = na
float l = na
float c = na
if linestyle == 'Candle'
    o := cumdelta[1]
    h := math.max(cumdelta, cumdelta[1])
    l := math.min(cumdelta, cumdelta[1])
    c := cumdelta
    ctl
else
    ctl := cumdelta
    ctl

plot(ctl, title='CDV Line', color=color.new(color.blue, 0), linewidth=2)

float haclose = na
float haopen = na
float hahigh = na
float halow = na
haclose := (o + h + l + c) / 4
haopen := na(haopen[1]) ? (o + c) / 2 : (haopen[1] + haclose[1]) / 2
hahigh := math.max(h, math.max(haopen, haclose))
halow := math.min(l, math.min(haopen, haclose))

c_ = hacandle ? haclose : c
o_ = hacandle ? haopen : o
h_ = hacandle ? hahigh : h
l_ = hacandle ? halow : l

//plotcandle(o_, h_, l_, c_, title='CDV Candles', color=o_ <= c_ ? colorup : colordown, bordercolor=o_ <= c_ ? bcolup : bcoldown, wickcolor=o_ <= c_ ? bcolup : bcoldown)

//plot(showma1 and linestyle == 'Candle' ? ta.sma(c_, ma1len) : na, title='SMA 1', color=ma1col)
//plot(showma2 and linestyle == 'Candle' ? ta.sma(c_, ma2len) : na, title='SMA 2', color=ma2col)
//plot(showema1 and linestyle == 'Candle' ? ta.ema(c_, ema1len) : na, title='EMA 1', color=ema1col)
//plot(showema2 and linestyle == 'Candle' ? ta.ema(c_, ema2len) : na, title='EMA 2', color=ema2col)

i_numLookbackBarsCDV = input(14,title="Number of bars to look back to validate CDV trend")
//cdvEntryLong = o_ < c_ and f_priorBarsSatisfied(o_ < c_,i_numLookbackBarsCDV)
//cdvEntryShort = o_ > c_ and f_priorBarsSatisfied(o_ > c_,i_numLookbackBarsCDV)

cdvEntryConditionLong = o_ <= c_
cdvEntryConditionShort = o_ > c_
cdvEntryLong = cdvEntryConditionLong and ta.barssince(cdvEntryConditionShort) > i_numLookbackBarsCDV 
cdvEntryShort = cdvEntryConditionShort and ta.barssince(cdvEntryConditionLong) > i_numLookbackBarsCDV 


//////////////////////////////////////
//* Put your strategy rules below *//
/////////////////////////////////////

longCondition = trendMagicEntryLong and sqzmomEntryLong and cdvEntryLong
shortCondition = trendMagicEntryShort and sqzmomEntryShort and cdvEntryShort

//define as 0 if do not want to use
closeLongCondition = 0
closeShortCondition = 0


// ADX
//░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

adxEnabled = input.bool(defval = false , title = "Average Directional Index (ADX)", tooltip = "", group ="ADX" ) 
adxlen = input(14, title="ADX Smoothing", group="ADX")
adxdilen = input(14, title="DI Length", group="ADX")
adxabove = input(25, title="ADX Threshold", group="ADX")

adxdirmov(len) =>
	adxup = ta.change(HIGH)
	adxdown = -ta.change(LOW)
	adxplusDM = na(adxup) ? na : (adxup > adxdown and adxup > 0 ? adxup : 0)
	adxminusDM = na(adxdown) ? na : (adxdown > adxup and adxdown > 0 ? adxdown : 0)
	adxtruerange = ta.rma(ta.tr, len)
	adxplus = fixnan(100 * ta.rma(adxplusDM, len) / adxtruerange)
	adxminus = fixnan(100 * ta.rma(adxminusDM, len) / adxtruerange)
	[adxplus, adxminus]
adx(adxdilen, adxlen) =>
	[adxplus, adxminus] = adxdirmov(adxdilen)
	adxsum = adxplus + adxminus
	adx = 100 * ta.rma(math.abs(adxplus - adxminus) / (adxsum == 0 ? 1 : adxsum), adxlen)

adxsig = adxEnabled ? adx(adxdilen, adxlen) : na
isADXEnabledAndAboveThreshold = adxEnabled ? (adxsig > adxabove) : true

//Backtesting Time Period (Input.time not working as expected as of 03/30/2021.  Giving odd start/end dates
//░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
useStartPeriodTime = input.bool(true, 'Start', group='Date Range', inline='Start Period')
startPeriodTime = input(timestamp('1 Jan 2019'), '', group='Date Range', inline='Start Period')
useEndPeriodTime = input.bool(true, 'End', group='Date Range', inline='End Period')
endPeriodTime = input(timestamp('31 Dec 2030'), '', group='Date Range', inline='End Period')

start = useStartPeriodTime ? startPeriodTime >= time : false
end = useEndPeriodTime ? endPeriodTime <= time : false
calcPeriod = true

// Trade Direction 
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
tradeDirection = input.string('Long and Short', title='Trade Direction', options=['Long and Short', 'Long Only', 'Short Only'], group='Trade Direction')

// Percent as Points
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
per(pcnt) =>
    strategy.position_size != 0 ? math.round(pcnt / 100 * strategy.position_avg_price / syminfo.mintick) : float(na)

// Take profit 1
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
tp1 = input.float(title='Take Profit 1 - Target %', defval=2, minval=0.0, step=0.5, group='Take Profit', inline='Take Profit 1')
q1 = input.int(title='% Of Position', defval=100, minval=0, group='Take Profit', inline='Take Profit 1')

// Take profit 2
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
tp2 = input.float(title='Take Profit 2 - Target %', defval=100, minval=0.0, step=0.5, group='Take Profit', inline='Take Profit 2')
q2 = input.int(title='% Of Position', defval=100, minval=0, group='Take Profit', inline='Take Profit 2')

// Take profit 3
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
tp3 = input.float(title='Take Profit 3 - Target %', defval=100, minval=0.0, step=0.5, group='Take Profit', inline='Take Profit 3')
q3 = input.int(title='% Of Position', defval=100, minval=0, group='Take Profit', inline='Take Profit 3')

// Take profit 4
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
tp4 = input.float(title='Take Profit 4 - Target %', defval=100, minval=0.0, step=0.5, group='Take Profit')

/// Stop Loss
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
stoplossPercent = input.float(title='Stop Loss (%)', defval=6, minval=0.01, group='Stop Loss') * 0.01
slLongClose = CLOSE < strategy.position_avg_price * (1 - stoplossPercent)
slShortClose = CLOSE > strategy.position_avg_price * (1 + stoplossPercent)

/// Leverage
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
leverage = input.float(1, 'Leverage', step=.5, group='Leverage')
contracts = math.min(math.max(.000001, strategy.equity / CLOSE * leverage), 1000000000)


/// Trade State Management
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

isInLongPosition = strategy.position_size > 0
isInShortPosition = strategy.position_size < 0

/// ProfitView Alert Syntax String Generation
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

alertSyntaxPrefix = input.string(defval='CRYPTANEX_99FTX_Strategy-Name-Here', title='Alert Syntax Prefix', group='ProfitView Alert Syntax')
alertSyntaxBase = alertSyntaxPrefix + '\n#' + str.tostring(OPEN) + ',' + str.tostring(HIGH) + ',' + str.tostring(LOW) + ',' + str.tostring(CLOSE) + ',' + str.tostring(volume) + ','


/// Trade Execution
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

longConditionCalc = (longCondition and isADXEnabledAndAboveThreshold)
shortConditionCalc = (shortCondition and isADXEnabledAndAboveThreshold)

if calcPeriod
    if longConditionCalc and tradeDirection != 'Short Only' and isInLongPosition == false
        strategy.entry('Long', strategy.long, qty=contracts)

        alert(message=alertSyntaxBase + 'side:long', freq=alert.freq_once_per_bar_close)

    if shortConditionCalc and tradeDirection != 'Long Only' and isInShortPosition == false
        strategy.entry('Short', strategy.short, qty=contracts)

        alert(message=alertSyntaxBase + 'side:short', freq=alert.freq_once_per_bar_close)
    
    //Inspired from Multiple %% profit exits example by adolgo https://www.tradingview.com/script/kHhCik9f-Multiple-profit-exits-example/
    strategy.exit('TP1', qty_percent=q1, profit=per(tp1))
    strategy.exit('TP2', qty_percent=q2, profit=per(tp2))
    strategy.exit('TP3', qty_percent=q3, profit=per(tp3))
    strategy.exit('TP4', profit=per(tp4))

    strategy.close('Long', qty_percent=100, comment='SL Long', when=slLongClose)
    strategy.close('Short', qty_percent=100, comment='SL Short', when=slShortClose)

    strategy.close_all(when=closeLongCondition or closeShortCondition, comment='Close Postion')

/// Dashboard
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
// Inspired by https://www.tradingview.com/script/uWqKX6A2/ - Thanks VertMT

showDashboard = input.bool(group="Dashboard", title="Show Dashboard", defval=false)

f_fillCell(_table, _column, _row, _title, _value, _bgcolor, _txtcolor) =>
    _cellText = _title + "\n" + _value
    table.cell(_table, _column, _row, _cellText, bgcolor=_bgcolor, text_color=_txtcolor, text_size=size.auto)

// Draw dashboard table
if showDashboard
    var bgcolor = color.new(color.black,0)
    
    // Keep track of Wins/Losses streaks
    newWin  = (strategy.wintrades  > strategy.wintrades[1]) and (strategy.losstrades == strategy.losstrades[1]) and (strategy.eventrades == strategy.eventrades[1])
    newLoss = (strategy.wintrades == strategy.wintrades[1]) and (strategy.losstrades  > strategy.losstrades[1]) and (strategy.eventrades == strategy.eventrades[1])

    varip int winRow     = 0
    varip int lossRow    = 0
    varip int maxWinRow  = 0
    varip int maxLossRow = 0

    if newWin
        lossRow := 0
        winRow := winRow + 1
    if winRow > maxWinRow
        maxWinRow := winRow
        
    if newLoss
        winRow := 0
        lossRow := lossRow + 1
    if lossRow > maxLossRow
        maxLossRow := lossRow


    // Prepare stats table
    var table dashTable = table.new(position.bottom_right, 1, 15, border_width=1)
    
   
    if barstate.islastconfirmedhistory
        // Update table
        dollarReturn = strategy.netprofit
        f_fillCell(dashTable, 0, 0, "Start:", str.format("{0,date,long}", strategy.closedtrades.entry_time(0)) , bgcolor, color.white) // + str.format(" {0,time,HH:mm}", strategy.closedtrades.entry_time(0)) 
        f_fillCell(dashTable, 0, 1, "End:", str.format("{0,date,long}", strategy.opentrades.entry_time(0)) , bgcolor, color.white) // + str.format(" {0,time,HH:mm}", strategy.opentrades.entry_time(0))
        _profit = (strategy.netprofit / strategy.initial_capital) * 100
        f_fillCell(dashTable, 0, 2, "Net Profit:", str.tostring(_profit, '##.##') + "%", _profit > 0 ? color.green : color.red, color.white)
        _numOfDaysInStrategy = (strategy.opentrades.entry_time(0) - strategy.closedtrades.entry_time(0)) / (1000 * 3600 * 24)
        f_fillCell(dashTable, 0, 3, "Percent Per Day", str.tostring(_profit / _numOfDaysInStrategy, '#########################.#####')+"%", _profit > 0 ? color.green : color.red, color.white)
        _winRate = ( strategy.wintrades / strategy.closedtrades ) * 100
        f_fillCell(dashTable, 0, 4, "Percent Profitable:", str.tostring(_winRate, '##.##') + "%", _winRate < 50 ? color.red : _winRate < 75 ? #999900 : color.green, color.white)
        f_fillCell(dashTable, 0, 5, "Profit Factor:", str.tostring(strategy.grossprofit / strategy.grossloss,  '##.###'), strategy.grossprofit > strategy.grossloss ? color.green : color.red, color.white)
        f_fillCell(dashTable, 0, 6, "Total Trades:", str.tostring(strategy.closedtrades), bgcolor, color.white)
        f_fillCell(dashTable, 0, 8, "Max Wins In A Row:", str.tostring(maxWinRow, '######') , bgcolor, color.white)
        f_fillCell(dashTable, 0, 9, "Max Losses In A Row:", str.tostring(maxLossRow, '######') , bgcolor, color.white)

مزید