PHP Code:
// @ Julien_Eche
//@version=6
indicator(title = 'Best SMA Finder', overlay = true, max_bars_back = 1100)
strategy_type = input.string(defval = 'Long Only', title = 'Strategy Type', options = ['Buy & Sell', 'Long Only'])
min_trades = input.int(defval = 100, title = 'Minimum Trades to Consider', minval = 1)
show_table = input.bool(true, title = 'Show Stats Table')
f_robustness(pf, trades, win_rate, min_trades) =>
trades >= min_trades and not na(pf) and pf >= 0 and not na(win_rate) ? pf * math.log(trades) * math.sqrt(win_rate) : -1e10
backtest(ma_len) =>
xMA = ta.sma(close, ma_len)
var float entry_price_long = na
var float entry_price_short = na
var int total_trades = 0
var int winning_trades = 0
var float total_profit = 0.0
var float total_loss = 0.0
long_condition = ta.crossover(close, xMA)
short_condition = ta.crossunder(close, xMA)
float trade_profit = na
if strategy_type == 'Buy & Sell'
if long_condition and na(entry_price_long) and na(entry_price_short)
entry_price_long := close
total_trades := total_trades + 1
total_trades
else
if short_condition and not na(entry_price_long)
trade_profit := close - entry_price_long
if trade_profit > 0
total_profit := total_profit + trade_profit
winning_trades := winning_trades + 1
winning_trades
else
total_loss := total_loss - trade_profit
total_loss
entry_price_long := na
entry_price_short := close
total_trades := total_trades + 1
total_trades
else
if short_condition and na(entry_price_short) and na(entry_price_long)
entry_price_short := close
total_trades := total_trades + 1
total_trades
else
if long_condition and not na(entry_price_short)
trade_profit := entry_price_short - close
if trade_profit > 0
total_profit := total_profit + trade_profit
winning_trades := winning_trades + 1
winning_trades
else
total_loss := total_loss - trade_profit
total_loss
entry_price_short := na
entry_price_long := close
total_trades := total_trades + 1
total_trades
else
if long_condition and na(entry_price_long)
entry_price_long := close
total_trades := total_trades + 1
total_trades
else if short_condition and not na(entry_price_long)
trade_profit := close - entry_price_long
if trade_profit > 0
total_profit := total_profit + trade_profit
winning_trades := winning_trades + 1
winning_trades
else
total_loss := total_loss - trade_profit
total_loss
entry_price_long := na
entry_price_long
float profit_factor = total_loss > 0 ? total_profit / total_loss : total_profit > 0 ? 10000.0 : 0
float win_rate = total_trades > 0 ? winning_trades / total_trades : 0.0
float robustness = f_robustness(profit_factor, total_trades, win_rate, min_trades)
[total_trades, profit_factor, win_rate, robustness]
[tt10, pf10, wr10, r10] = backtest(10)
[tt20, pf20, wr20, r20] = backtest(20)
[tt30, pf30, wr30, r30] = backtest(30)
[tt40, pf40, wr40, r40] = backtest(40)
[tt50, pf50, wr50, r50] = backtest(50)
[tt60, pf60, wr60, r60] = backtest(60)
[tt70, pf70, wr70, r70] = backtest(70)
[tt80, pf80, wr80, r80] = backtest(80)
[tt90, pf90, wr90, r90] = backtest(90)
[tt100, pf100, wr100, r100] = backtest(100)
[tt110, pf110, wr110, r110] = backtest(110)
[tt120, pf120, wr120, r120] = backtest(120)
[tt130, pf130, wr130, r130] = backtest(130)
[tt140, pf140, wr140, r140] = backtest(140)
[tt150, pf150, wr150, r150] = backtest(150)
[tt160, pf160, wr160, r160] = backtest(160)
[tt170, pf170, wr170, r170] = backtest(170)
[tt180, pf180, wr180, r180] = backtest(180)
[tt190, pf190, wr190, r190] = backtest(190)
[tt200, pf200, wr200, r200] = backtest(200)
[tt210, pf210, wr210, r210] = backtest(210)
[tt220, pf220, wr220, r220] = backtest(220)
[tt230, pf230, wr230, r230] = backtest(230)
[tt240, pf240, wr240, r240] = backtest(240)
[tt250, pf250, wr250, r250] = backtest(250)
[tt260, pf260, wr260, r260] = backtest(260)
[tt270, pf270, wr270, r270] = backtest(270)
[tt280, pf280, wr280, r280] = backtest(280)
[tt290, pf290, wr290, r290] = backtest(290)
[tt300, pf300, wr300, r300] = backtest(300)
[tt310, pf310, wr310, r310] = backtest(310)
[tt320, pf320, wr320, r320] = backtest(320)
[tt330, pf330, wr330, r330] = backtest(330)
[tt340, pf340, wr340, r340] = backtest(340)
[tt350, pf350, wr350, r350] = backtest(350)
[tt360, pf360, wr360, r360] = backtest(360)
[tt370, pf370, wr370, r370] = backtest(370)
[tt380, pf380, wr380, r380] = backtest(380)
[tt390, pf390, wr390, r390] = backtest(390)
[tt400, pf400, wr400, r400] = backtest(400)
[tt410, pf410, wr410, r410] = backtest(410)
[tt420, pf420, wr420, r420] = backtest(420)
[tt430, pf430, wr430, r430] = backtest(430)
[tt440, pf440, wr440, r440] = backtest(440)
[tt450, pf450, wr450, r450] = backtest(450)
[tt460, pf460, wr460, r460] = backtest(460)
[tt470, pf470, wr470, r470] = backtest(470)
[tt480, pf480, wr480, r480] = backtest(480)
[tt490, pf490, wr490, r490] = backtest(490)
[tt500, pf500, wr500, r500] = backtest(500)
[tt510, pf510, wr510, r510] = backtest(510)
[tt520, pf520, wr520, r520] = backtest(520)
[tt530, pf530, wr530, r530] = backtest(530)
[tt540, pf540, wr540, r540] = backtest(540)
[tt550, pf550, wr550, r550] = backtest(550)
[tt560, pf560, wr560, r560] = backtest(560)
[tt570, pf570, wr570, r570] = backtest(570)
[tt580, pf580, wr580, r580] = backtest(580)
[tt590, pf590, wr590, r590] = backtest(590)
[tt600, pf600, wr600, r600] = backtest(600)
[tt610, pf610, wr610, r610] = backtest(610)
[tt620, pf620, wr620, r620] = backtest(620)
[tt630, pf630, wr630, r630] = backtest(630)
[tt640, pf640, wr640, r640] = backtest(640)
[tt650, pf650, wr650, r650] = backtest(650)
[tt660, pf660, wr660, r660] = backtest(660)
[tt670, pf670, wr670, r670] = backtest(670)
[tt680, pf680, wr680, r680] = backtest(680)
[tt690, pf690, wr690, r690] = backtest(690)
[tt700, pf700, wr700, r700] = backtest(700)
[tt710, pf710, wr710, r710] = backtest(710)
[tt720, pf720, wr720, r720] = backtest(720)
[tt730, pf730, wr730, r730] = backtest(730)
[tt740, pf740, wr740, r740] = backtest(740)
[tt750, pf750, wr750, r750] = backtest(750)
[tt760, pf760, wr760, r760] = backtest(760)
[tt770, pf770, wr770, r770] = backtest(770)
[tt780, pf780, wr780, r780] = backtest(780)
[tt790, pf790, wr790, r790] = backtest(790)
[tt800, pf800, wr800, r800] = backtest(800)
[tt810, pf810, wr810, r810] = backtest(810)
[tt820, pf820, wr820, r820] = backtest(820)
[tt830, pf830, wr830, r830] = backtest(830)
[tt840, pf840, wr840, r840] = backtest(840)
[tt850, pf850, wr850, r850] = backtest(850)
[tt860, pf860, wr860, r860] = backtest(860)
[tt870, pf870, wr870, r870] = backtest(870)
[tt880, pf880, wr880, r880] = backtest(880)
[tt890, pf890, wr890, r890] = backtest(890)
[tt900, pf900, wr900, r900] = backtest(900)
[tt910, pf910, wr910, r910] = backtest(910)
[tt920, pf920, wr920, r920] = backtest(920)
[tt930, pf930, wr930, r930] = backtest(930)
[tt940, pf940, wr940, r940] = backtest(940)
[tt950, pf950, wr950, r950] = backtest(950)
[tt960, pf960, wr960, r960] = backtest(960)
[tt970, pf970, wr970, r970] = backtest(970)
[tt980, pf980, wr980, r980] = backtest(980)
[tt990, pf990, wr990, r990] = backtest(990)
[tt1000, pf1000, wr1000, r1000] = backtest(1000)
var float best_score = -1e10
var int best_len = na
var int best_trades = na
var float best_pf = na
var float best_wr = na
if not na(r10) and r10 > best_score
best_score := r10
best_len := 10
best_trades := tt10
best_pf := pf10
best_wr := wr10
best_wr
if not na(r20) and r20 > best_score
best_score := r20
best_len := 20
best_trades := tt20
best_pf := pf20
best_wr := wr20
best_wr
if not na(r30) and r30 > best_score
best_score := r30
best_len := 30
best_trades := tt30
best_pf := pf30
best_wr := wr30
best_wr
if not na(r40) and r40 > best_score
best_score := r40
best_len := 40
best_trades := tt40
best_pf := pf40
best_wr := wr40
best_wr
if not na(r50) and r50 > best_score
best_score := r50
best_len := 50
best_trades := tt50
best_pf := pf50
best_wr := wr50
best_wr
if not na(r60) and r60 > best_score
best_score := r60
best_len := 60
best_trades := tt60
best_pf := pf60
best_wr := wr60
best_wr
if not na(r70) and r70 > best_score
best_score := r70
best_len := 70
best_trades := tt70
best_pf := pf70
best_wr := wr70
best_wr
if not na(r80) and r80 > best_score
best_score := r80
best_len := 80
best_trades := tt80
best_pf := pf80
best_wr := wr80
best_wr
if not na(r90) and r90 > best_score
best_score := r90
best_len := 90
best_trades := tt90
best_pf := pf90
best_wr := wr90
best_wr
if not na(r100) and r100 > best_score
best_score := r100
best_len := 100
best_trades := tt100
best_pf := pf100
best_wr := wr100
best_wr
if not na(r110) and r110 > best_score
best_score := r110
best_len := 110
best_trades := tt110
best_pf := pf110
best_wr := wr110
best_wr
if not na(r120) and r120 > best_score
best_score := r120
best_len := 120
best_trades := tt120
best_pf := pf120
best_wr := wr120
best_wr
if not na(r130) and r130 > best_score
best_score := r130
best_len := 130
best_trades := tt130
best_pf := pf130
best_wr := wr130
best_wr
if not na(r140) and r140 > best_score
best_score := r140
best_len := 140
best_trades := tt140
best_pf := pf140
best_wr := wr140
best_wr
if not na(r150) and r150 > best_score
best_score := r150
best_len := 150
best_trades := tt150
best_pf := pf150
best_wr := wr150
best_wr
if not na(r160) and r160 > best_score
best_score := r160
best_len := 160
best_trades := tt160
best_pf := pf160
best_wr := wr160
best_wr
if not na(r170) and r170 > best_score
best_score := r170
best_len := 170
best_trades := tt170
best_pf := pf170
best_wr := wr170
best_wr
if not na(r180) and r180 > best_score
best_score := r180
best_len := 180
best_trades := tt180
best_pf := pf180
best_wr := wr180
best_wr
if not na(r190) and r190 > best_score
best_score := r190
best_len := 190
best_trades := tt190
best_pf := pf190
best_wr := wr190
best_wr
if not na(r200) and r200 > best_score
best_score := r200
best_len := 200
best_trades := tt200
best_pf := pf200
best_wr := wr200
best_wr
if not na(r210) and r210 > best_score
best_score := r210
best_len := 210
best_trades := tt210
best_pf := pf210
best_wr := wr210
best_wr
if not na(r220) and r220 > best_score
best_score := r220
best_len := 220
best_trades := tt220
best_pf := pf220
best_wr := wr220
best_wr
if not na(r230) and r230 > best_score
best_score := r230
best_len := 230
best_trades := tt230
best_pf := pf230
best_wr := wr230
best_wr
if not na(r240) and r240 > best_score
best_score := r240
best_len := 240
best_trades := tt240
best_pf := pf240
best_wr := wr240
best_wr
if not na(r250) and r250 > best_score
best_score := r250
best_len := 250
best_trades := tt250
best_pf := pf250
best_wr := wr250
best_wr
if not na(r260) and r260 > best_score
best_score := r260
best_len := 260
best_trades := tt260
best_pf := pf260
best_wr := wr260
best_wr
if not na(r270) and r270 > best_score
best_score := r270
best_len := 270
best_trades := tt270
best_pf := pf270
best_wr := wr270
best_wr
if not na(r280) and r280 > best_score
best_score := r280
best_len := 280
best_trades := tt280
best_pf := pf280
best_wr := wr280
best_wr
if not na(r290) and r290 > best_score
best_score := r290
best_len := 290
best_trades := tt290
best_pf := pf290
best_wr := wr290
best_wr
if not na(r300) and r300 > best_score
best_score := r300
best_len := 300
best_trades := tt300
best_pf := pf300
best_wr := wr300
best_wr
if not na(r310) and r310 > best_score
best_score := r310
best_len := 310
best_trades := tt310
best_pf := pf310
best_wr := wr310
best_wr
if not na(r320) and r320 > best_score
best_score := r320
best_len := 320
best_trades := tt320
best_pf := pf320
best_wr := wr320
best_wr
if not na(r330) and r330 > best_score
best_score := r330
best_len := 330
best_trades := tt330
best_pf := pf330
best_wr := wr330
best_wr
if not na(r340) and r340 > best_score
best_score := r340
best_len := 340
best_trades := tt340
best_pf := pf340
best_wr := wr340
best_wr
if not na(r350) and r350 > best_score
best_score := r350
best_len := 350
best_trades := tt350
best_pf := pf350
best_wr := wr350
best_wr
if not na(r360) and r360 > best_score
best_score := r360
best_len := 360
best_trades := tt360
best_pf := pf360
best_wr := wr360
best_wr
if not na(r370) and r370 > best_score
best_score := r370
best_len := 370
best_trades := tt370
best_pf := pf370
best_wr := wr370
best_wr
if not na(r380) and r380 > best_score
best_score := r380
best_len := 380
best_trades := tt380
best_pf := pf380
best_wr := wr380
best_wr
if not na(r390) and r390 > best_score
best_score := r390
best_len := 390
best_trades := tt390
best_pf := pf390
best_wr := wr390
best_wr
if not na(r400) and r400 > best_score
best_score := r400
best_len := 400
best_trades := tt400
best_pf := pf400
best_wr := wr400
best_wr
if not na(r410) and r410 > best_score
best_score := r410
best_len := 410
best_trades := tt410
best_pf := pf410
best_wr := wr410
best_wr
if not na(r420) and r420 > best_score
best_score := r420
best_len := 420
best_trades := tt420
best_pf := pf420
best_wr := wr420
best_wr
if not na(r430) and r430 > best_score
best_score := r430
best_len := 430
best_trades := tt430
best_pf := pf430
best_wr := wr430
best_wr
if not na(r440) and r440 > best_score
best_score := r440
best_len := 440
best_trades := tt440
best_pf := pf440
best_wr := wr440
best_wr
if not na(r450) and r450 > best_score
best_score := r450
best_len := 450
best_trades := tt450
best_pf := pf450
best_wr := wr450
best_wr
if not na(r460) and r460 > best_score
best_score := r460
best_len := 460
best_trades := tt460
best_pf := pf460
best_wr := wr460
best_wr
if not na(r470) and r470 > best_score
best_score := r470
best_len := 470
best_trades := tt470
best_pf := pf470
best_wr := wr470
best_wr
if not na(r480) and r480 > best_score
best_score := r480
best_len := 480
best_trades := tt480
best_pf := pf480
best_wr := wr480
best_wr
if not na(r490) and r490 > best_score
best_score := r490
best_len := 490
best_trades := tt490
best_pf := pf490
best_wr := wr490
best_wr
if not na(r500) and r500 > best_score
best_score := r500
best_len := 500
best_trades := tt500
best_pf := pf500
best_wr := wr500
best_wr
if not na(r510) and r510 > best_score
best_score := r510
best_len := 510
best_trades := tt510
best_pf := pf510
best_wr := wr510
best_wr
if not na(r520) and r520 > best_score
best_score := r520
best_len := 520
best_trades := tt520
best_pf := pf520
best_wr := wr520
best_wr
if not na(r530) and r530 > best_score
best_score := r530
best_len := 530
best_trades := tt530
best_pf := pf530
best_wr := wr530
best_wr
if not na(r540) and r540 > best_score
best_score := r540
best_len := 540
best_trades := tt540
best_pf := pf540
best_wr := wr540
best_wr
if not na(r550) and r550 > best_score
best_score := r550
best_len := 550
best_trades := tt550
best_pf := pf550
best_wr := wr550
best_wr
if not na(r560) and r560 > best_score
best_score := r560
best_len := 560
best_trades := tt560
best_pf := pf560
best_wr := wr560
best_wr
if not na(r570) and r570 > best_score
best_score := r570
best_len := 570
best_trades := tt570
best_pf := pf570
best_wr := wr570
best_wr
if not na(r580) and r580 > best_score
best_score := r580
best_len := 580
best_trades := tt580
best_pf := pf580
best_wr := wr580
best_wr
if not na(r590) and r590 > best_score
best_score := r590
best_len := 590
best_trades := tt590
best_pf := pf590
best_wr := wr590
best_wr
if not na(r600) and r600 > best_score
best_score := r600
best_len := 600
best_trades := tt600
best_pf := pf600
best_wr := wr600
best_wr
if not na(r610) and r610 > best_score
best_score := r610
best_len := 610
best_trades := tt610
best_pf := pf610
best_wr := wr610
best_wr
if not na(r620) and r620 > best_score
best_score := r620
best_len := 620
best_trades := tt620
best_pf := pf620
best_wr := wr620
best_wr
if not na(r630) and r630 > best_score
best_score := r630
best_len := 630
best_trades := tt630
best_pf := pf630
best_wr := wr630
best_wr
if not na(r640) and r640 > best_score
best_score := r640
best_len := 640
best_trades := tt640
best_pf := pf640
best_wr := wr640
best_wr
if not na(r650) and r650 > best_score
best_score := r650
best_len := 650
best_trades := tt650
best_pf := pf650
best_wr := wr650
best_wr
if not na(r660) and r660 > best_score
best_score := r660
best_len := 660
best_trades := tt660
best_pf := pf660
best_wr := wr660
best_wr
if not na(r670) and r670 > best_score
best_score := r670
best_len := 670
best_trades := tt670
best_pf := pf670
best_wr := wr670
best_wr
if not na(r680) and r680 > best_score
best_score := r680
best_len := 680
best_trades := tt680
best_pf := pf680
best_wr := wr680
best_wr
if not na(r690) and r690 > best_score
best_score := r690
best_len := 690
best_trades := tt690
best_pf := pf690
best_wr := wr690
best_wr
if not na(r700) and r700 > best_score
best_score := r700
best_len := 700
best_trades := tt700
best_pf := pf700
best_wr := wr700
best_wr
if not na(r710) and r710 > best_score
best_score := r710
best_len := 710
best_trades := tt710
best_pf := pf710
best_wr := wr710
best_wr
if not na(r720) and r720 > best_score
best_score := r720
best_len := 720
best_trades := tt720
best_pf := pf720
best_wr := wr720
best_wr
if not na(r730) and r730 > best_score
best_score := r730
best_len := 730
best_trades := tt730
best_pf := pf730
best_wr := wr730
best_wr
if not na(r740) and r740 > best_score
best_score := r740
best_len := 740
best_trades := tt740
best_pf := pf740
best_wr := wr740
best_wr
if not na(r750) and r750 > best_score
best_score := r750
best_len := 750
best_trades := tt750
best_pf := pf750
best_wr := wr750
best_wr
if not na(r760) and r760 > best_score
best_score := r760
best_len := 760
best_trades := tt760
best_pf := pf760
best_wr := wr760
best_wr
if not na(r770) and r770 > best_score
best_score := r770
best_len := 770
best_trades := tt770
best_pf := pf770
best_wr := wr770
best_wr
if not na(r780) and r780 > best_score
best_score := r780
best_len := 780
best_trades := tt780
best_pf := pf780
best_wr := wr780
best_wr
if not na(r790) and r790 > best_score
best_score := r790
best_len := 790
best_trades := tt790
best_pf := pf790
best_wr := wr790
best_wr
if not na(r800) and r800 > best_score
best_score := r800
best_len := 800
best_trades := tt800
best_pf := pf800
best_wr := wr800
best_wr
if not na(r810) and r810 > best_score
best_score := r810
best_len := 810
best_trades := tt810
best_pf := pf810
best_wr := wr810
best_wr
if not na(r820) and r820 > best_score
best_score := r820
best_len := 820
best_trades := tt820
best_pf := pf820
best_wr := wr820
best_wr
if not na(r830) and r830 > best_score
best_score := r830
best_len := 830
best_trades := tt830
best_pf := pf830
best_wr := wr830
best_wr
if not na(r840) and r840 > best_score
best_score := r840
best_len := 840
best_trades := tt840
best_pf := pf840
best_wr := wr840
best_wr
if not na(r850) and r850 > best_score
best_score := r850
best_len := 850
best_trades := tt850
best_pf := pf850
best_wr := wr850
best_wr
if not na(r860) and r860 > best_score
best_score := r860
best_len := 860
best_trades := tt860
best_pf := pf860
best_wr := wr860
best_wr
if not na(r870) and r870 > best_score
best_score := r870
best_len := 870
best_trades := tt870
best_pf := pf870
best_wr := wr870
best_wr
if not na(r880) and r880 > best_score
best_score := r880
best_len := 880
best_trades := tt880
best_pf := pf880
best_wr := wr880
best_wr
if not na(r890) and r890 > best_score
best_score := r890
best_len := 890
best_trades := tt890
best_pf := pf890
best_wr := wr890
best_wr
if not na(r900) and r900 > best_score
best_score := r900
best_len := 900
best_trades := tt900
best_pf := pf900
best_wr := wr900
best_wr
if not na(r910) and r910 > best_score
best_score := r910
best_len := 910
best_trades := tt910
best_pf := pf910
best_wr := wr910
best_wr
if not na(r920) and r920 > best_score
best_score := r920
best_len := 920
best_trades := tt920
best_pf := pf920
best_wr := wr920
best_wr
if not na(r930) and r930 > best_score
best_score := r930
best_len := 930
best_trades := tt930
best_pf := pf930
best_wr := wr930
best_wr
if not na(r940) and r940 > best_score
best_score := r940
best_len := 940
best_trades := tt940
best_pf := pf940
best_wr := wr940
best_wr
if not na(r950) and r950 > best_score
best_score := r950
best_len := 950
best_trades := tt950
best_pf := pf950
best_wr := wr950
best_wr
if not na(r960) and r960 > best_score
best_score := r960
best_len := 960
best_trades := tt960
best_pf := pf960
best_wr := wr960
best_wr
if not na(r970) and r970 > best_score
best_score := r970
best_len := 970
best_trades := tt970
best_pf := pf970
best_wr := wr970
best_wr
if not na(r980) and r980 > best_score
best_score := r980
best_len := 980
best_trades := tt980
best_pf := pf980
best_wr := wr980
best_wr
if not na(r990) and r990 > best_score
best_score := r990
best_len := 990
best_trades := tt990
best_pf := pf990
best_wr := wr990
best_wr
if not na(r1000) and r1000 > best_score
best_score := r1000
best_len := 1000
best_trades := tt1000
best_pf := pf1000
best_wr := wr1000
best_wr
plot(na(best_len) ? na : ta.sma(close, best_len), color = color.new(color.blue, 0), linewidth = 2, title = 'Optimal SMA')
var table stats_table = table.new(position = position.top_right, columns = 2, rows = 5, bgcolor = color.new(color.black, 85), border_width = 1)
if barstate.islast and show_table
if not na(best_len)
table.cell(stats_table, 0, 0, 'Optimal SMA Length', text_color = color.white)
table.cell(stats_table, 1, 0, str.tostring(best_len), text_color = color.white)
table.cell(stats_table, 0, 1, 'Total Trades', text_color = color.white)
table.cell(stats_table, 1, 1, str.tostring(best_trades), text_color = color.white)
table.cell(stats_table, 0, 2, 'Profit Factor', text_color = color.white)
table.cell(stats_table, 1, 2, str.tostring(best_pf, '#.##'), text_color = color.white)
table.cell(stats_table, 0, 3, 'Win Rate (%)', text_color = color.white)
table.cell(stats_table, 1, 3, str.tostring(best_wr * 100, '#.#'), text_color = color.white)
table.cell(stats_table, 0, 4, 'Robustness Score', text_color = color.white)
table.cell(stats_table, 1, 4, str.tostring(best_score, '#.##'), text_color = color.white)
else
table.cell(stats_table, 0, 0, 'Optimal SMA Length', text_color = color.gray)
table.cell(stats_table, 1, 0, 'Calculating...', text_color = color.gray)
table.cell(stats_table, 0, 1, 'Total Trades', text_color = color.gray)
table.cell(stats_table, 1, 1, '--', text_color = color.gray)
table.cell(stats_table, 0, 2, 'Profit Factor', text_color = color.gray)
table.cell(stats_table, 1, 2, '--', text_color = color.gray)
table.cell(stats_table, 0, 3, 'Win Rate (%)', text_color = color.gray)
table.cell(stats_table, 1, 3, '--', text_color = color.gray)
table.cell(stats_table, 0, 4, 'Robustness Score', text_color = color.gray)
table.cell(stats_table, 1, 4, '--', text_color = color.gray)
/////////////////////////////
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © chaitu50c
//@version=6
// Inputs
gapType = input.string(title = 'Gap Type', defval = 'Open/Close', options = ['Open/Close', 'High/Low'])
bufferPrice = input.float(title = 'Price Buffer (points)', defval = 5.0, step = 0.1)
clusterRangePrice = input.float(title = 'Cluster Range (points)', defval = 100.0, step = 0.1)
lineWidth = input.int(title = 'Line Width', defval = 2, minval = 1)
daysBack = input.int(title = 'Days to include', defval = 1, minval = 1, maxval = 1)
// Color inputs
colorAbove = input.color(title = 'Color for Levels Above Price', defval = color.red)
colorBelow = input.color(title = 'Color for Levels Below Price', defval = color.green)
// Persistent arrays
var array<float> levels = array.new_float()
var array<line> linesArr = array.new_line()
var array<int> levelTimes = array.new_int()
// Session retention cutoff
dayStart = time('D')
retention = dayStart - (daysBack - 1) * 24 * 60 * 60 * 1000
// Purge old lines
if array.size(levelTimes) > 0
int idx = array.size(levelTimes) - 1
while idx >= 0
if array.get(levelTimes, idx) < retention
line.delete(array.get(linesArr, idx))
array.remove(linesArr, idx)
array.remove(levelTimes, idx)
array.remove(levels, idx)
idx := idx - 1
idx
// Gap detection logic
bool isGap = false
float lvl = na
if gapType == 'Open/Close'
bool gapGR = close[1] > open[1] and close < open and math.abs(close[1] - open) <= bufferPrice
bool gapRG = close[1] < open[1] and close > open and math.abs(close[1] - open) <= bufferPrice
isGap := gapGR or gapRG
lvl := gapGR ? close[1] : gapRG ? open : na
lvl
else
bool condColor = close[1] > open[1] and close < open
bool hl1 = condColor and math.abs(high[1] - low) <= bufferPrice
bool hl2 = condColor and math.abs(low[1] - high) <= bufferPrice
bool ll = condColor and math.abs(low[1] - low) <= bufferPrice
bool hh = condColor and math.abs(high[1] - high) <= bufferPrice
isGap := hl1 or hl2 or ll or hh
lvl := hl1 ? high[1] : hl2 ? low : ll ? low[1] : hh ? high : na
lvl
// Plot new clustered line if needed
if isGap and not na(lvl)
// determine color
clr = lvl < close ? colorBelow : colorAbove
if array.size(levels) == 0
array.push(levels, lvl)
array.push(levelTimes, dayStart)
ln = line.new(bar_index, lvl, bar_index + 1, lvl, xloc.bar_index, extend.both, clr, line.style_solid, lineWidth)
array.push(linesArr, ln)
else
bool exists = false
for i = 0 to array.size(levels) - 1 by 1
if math.abs(array.get(levels, i) - lvl) <= clusterRangePrice
exists := true
break
if not exists
array.push(levels, lvl)
array.push(levelTimes, dayStart)
ln = line.new(bar_index, lvl, bar_index + 1, lvl, xloc.bar_index, extend.both, clr, line.style_solid, lineWidth)
array.push(linesArr, ln)
// Dynamically update line colors
if array.size(linesArr) > 0
for i = 0 to array.size(linesArr) - 1 by 1
float level_i = array.get(levels, i)
line ln_i = array.get(linesArr, i)
clr_i = level_i < close ? colorBelow : colorAbove
line.set_color(ln_i, clr_i)
/////////////////////////////////////
//@version=5
// --- EMA sur le timeframe courant ---
ema50 = ta.ema(close, 50)
ema100 = ta.ema(close, 100)
ema200 = ta.ema(close, 200)
//ema50_plot = plot(ema50, color=color.gray, linewidth=2, title="EMA 50")
//ema100_plot = plot(ema100, color=color.navy, linewidth=2, title="EMA 100")
//ema200_plot = plot(ema200, color=color.black, linewidth=2, title="EMA 200")
// --- Filling entre les EMA du timeframe courant ---
//fill(ema50_plot, ema100_plot, color=color.new(color.blue, 90), title="Filling EMA50-EMA100")
//fill(ema100_plot, ema200_plot, color=color.new(color.purple, 90), title="Filling EMA100-EMA200")
// --- EMA200 sur H4 ---
ema200_h4 = request.security(syminfo.tickerid, "240", ta.ema(close, 200))
//plot(ema200_h4, color=color.new(color.black, 0), linewidth=2, style=plot.style_linebr, title="EMA200 H4")
// --- EMA200 sur H1 ---
ema200_h1 = request.security(syminfo.tickerid, "60", ta.ema(close, 200))
plot(ema200_h1, color=color.new(color.green, 0), linewidth=2, style=plot.style_linebr, title="EMA200 H1")
// --- EMA200 sur M15 ---
ema200_m15 = request.security(syminfo.tickerid, "15", ta.ema(close, 200))
plot(ema200_m15, color=color.new(color.orange, 0), linewidth=2, style=plot.style_linebr, title="EMA200 M15")
// --- Condition : prix touche EMA200 H4 ---
touch_ema200_h4 = (low <= ema200_h4 and high >= ema200_h4)
// --- Condition : prix touche EMA200 H1 ---
touch_ema200_h1 = (low <= ema200_h1 and high >= ema200_h1)
// --- Condition : prix touche EMA200 M15 ---
touch_ema200_m15 = (low <= ema200_m15 and high >= ema200_m15)
// --- Conditions de croisement EMA100/EMA200 ---
cross_up = ta.crossover(ema100, ema200)
cross_down = ta.crossunder(ema100, ema200)
// --- Alertes instantanées (tick par tick) ---
if touch_ema200_h4
alert("Le prix touche l'EMA200 H4 sur " + syminfo.ticker + " (" + timeframe.period + ")", alert.freq_all)
if touch_ema200_h1
alert("Le prix touche l'EMA200 H1 sur " + syminfo.ticker + " (" + timeframe.period + ")", alert.freq_all)
if touch_ema200_m15
alert("Le prix touche l'EMA200 M15 sur " + syminfo.ticker + " (" + timeframe.period + ")", alert.freq_all)
if cross_up
alert("EMA100 croise au-dessus EMA200 sur " + syminfo.ticker + " (" + timeframe.period + ")", alert.freq_all)
if cross_down
alert("EMA100 croise en-dessous EMA200 sur " + syminfo.ticker + " (" + timeframe.period + ")", alert.freq_all)
// --- Alertes classiques pour compatibilité (optionnel) ---
alertcondition(cross_up, title="EMA100 croise au-dessus EMA200", message="EMA100 croise au-dessus EMA200 sur {{ticker}} ({{interval}})")
alertcondition(cross_down, title="EMA100 croise en-dessous EMA200", message="EMA100 croise en-dessous EMA200 sur {{ticker}} ({{interval}})")
alertcondition(touch_ema200_h4, title="Prix touche EMA200 H4", message="Le prix touche l'EMA200 H4 sur {{ticker}} ({{interval}})")
alertcondition(touch_ema200_h1, title="Prix touche EMA200 H1", message="Le prix touche l'EMA200 H1 sur {{ticker}} ({{interval}})")
alertcondition(touch_ema200_m15, title="Prix touche EMA200 M15", message="Le prix touche l'EMA200 M15 sur {{ticker}} ({{interval}})")
Yer İmleri