// "First non-garbage strategy" (NGS) sclass NGSStrategy extends G22CandleBasedStrategy { settable double minDistance = 0.4; // input.float(0.4, minval=0, step=0.02) settable int period1 = 100; // the "slow" MA settable int period2 = 5; // the fast MA (for opening) settable double maMinMove = 0.07; // MA trend threshold settable double stopLoss = 2; settable double trailStart = 1; settable double trailPullback = 0.3; settable bool doLongs = true; settable bool doShorts = true; settable bool unblockAfterCrossingBand; settable bool unblockAfterTouchingBand = true; // per-run fields settable bool blockLong; settable bool blockShort; void reset :: after { resetFields(this, "blockShort blockLong"); } void unblockLong { if (blockLong) { log("Long unblock"); blockLong(false); } } void unblockShort { if (blockShort) { log("Short unblock"); blockShort(false); } } ma1 = ta.sma(close, period1) ma2 = ta.sma(close, period2) upperBand=ma1*(1+minDistance/100) lowerBand=ma1*(1-minDistance/100) percentToTicks(percent) => close*percent/100/syminfo.mintick maMove = (ma1/ma1[1]-1)*100 // in percent maRising = maMove >= maMinMove maFalling = maMove <= -maMinMove plot(ma1, color=maRising ? color.green : maFalling ? color.red : color.gray, linewidth=2) plot(ma2, color=color.blue) fill(plot(lowerBand, color=na), plot(upperBand, color=na), color=color.new(color.gray, 75)) longCondition = doLongs and ma2 > upperBand and maRising shortCondition = doShorts and ma2 < lowerBand and maFalling evenBar = bar_index-math.floor(bar_index/2)*2 == 0 plotshape(longCondition and evenBar, style=shape.labelup, location=location.top, color=color.green) plotshape(shortCondition and evenBar, style=shape.labeldown, location=location.bottom, color=color.red) plotshape(blockLong and not evenBar, style=shape.xcross, location=location.top, color=color.green) plotshape(blockShort and not evenBar, style=shape.xcross, location=location.bottom, color=color.red) //if barstate.isrealtime // log(time/100000) // Manual adjustments //if time == 1676775600000 // blockLong := false //if time == 1676818800000 // strategy.close_all(comment = "Manual close") if ma2 > ma1 // longCondition blockShort := unblockShort() if ma2 < ma1 // shortCondition blockLong := unblockLong() stopLossAndTP() => strategy.exit("Exit", comment_loss="Stop loss", loss=percentToTicks(stopLoss), comment_trailing="Trailing stop", trail_points=percentToTicks(trailStart), trail_offset=percentToTicks(trailPullback)) if longCondition and not blockLong strategy.entry("Long", strategy.long) stopLossAndTP() blockLong := true if shortCondition and not blockShort strategy.entry("Short", strategy.short) stopLossAndTP() blockShort := true drift = drift() if drift > 0 and close < lowerBand strategy.close_all(comment = "Below band") if unblockAfterCrossingBand blockLong := unblockLong() if drift < 0 and close > upperBand strategy.close_all(comment = "Above band") if unblockAfterCrossingBand blockShort := unblockShort() */ if (unblockAfterTouchingBand && close < upperBand) unblockLong(); if (unblockAfterTouchingBand && close > lowerBand) unblockShort(); */ }