// Define session times (Eastern Time) private readonly TimeSpan asianSessionStart = new TimeSpan(18, 0, 0); // 6 PM ET private readonly TimeSpan asianSessionEnd = new TimeSpan(4, 0, 0); // 4 AM ET private readonly TimeSpan londonSessionStart = new TimeSpan(3, 0, 0); // 3 AM ET private readonly TimeSpan newYorkSessionEnd = new TimeSpan(16, 0, 0); // 4 PM ET
protected override void OnStart() { Print("Enhanced Range Breakout Bot Started");
// Ensure we are operating on the correct instrument if (SymbolName != TradeSymbol) { Print("This bot is configured to trade " + TradeSymbol + ". Please switch to the correct chart."); Stop(); }
atr = Indicators.AverageTrueRange(14, MovingAverageType.Simple); // ATR for volatility filtering
// Moving Average for trend filtering if (UseMovingAverage) { movingAverage = Indicators.MovingAverage(MarketSeries.Close, MaPeriod, MovingAverageType.Simple); }
protected override void OnBar() { var currentTime = Server.Time.ToLocalTime().TimeOfDay;
// Step 1: Identify Range During Asian Session if (currentTime >= asianSessionStart || currentTime <= asianSessionEnd) { if (!rangeSet) { asianHigh = MarketSeries.High.LastValue; asianLow = MarketSeries.Low.LastValue; rangeSet = true; rangeBroken = false; Print("Setting range: Asian High = " + asianHigh + ", Asian Low = " + asianLow); } else { asianHigh = Math.Max(asianHigh, MarketSeries.High.LastValue); asianLow = Math.Min(asianLow, MarketSeries.Low.LastValue); } }
// Step 2: Look for Breakouts During London and New York Session if (currentTime > asianSessionEnd && currentTime < newYorkSessionEnd) { double atrValue = atr.Result.LastValue; double range = asianHigh - asianLow;
// Check for valid volatility (Range must be greater than ATR * Multiplier) if (range >= atrValue * ATRMultiplier) { Print("Range detected: " + range + " ATR = " + atrValue);
// Additional Moving Average filter to confirm trend direction if (UseMovingAverage) { bool isBullish = MarketSeries.Close.LastValue > movingAverage.Result.LastValue;
// Breakout: Buy if price breaks above the range and trend is bullish if (!rangeBroken && MarketSeries.Close.LastValue > asianHigh && isBullish) { Print("Breakout detected! Going long."); OpenPosition(TradeType.Buy); rangeBroken = true; } // Breakout: Sell if price breaks below the range and trend is bearish else if (!rangeBroken && MarketSeries.Close.LastValue < asianLow && !isBullish) { Print("Breakout detected! Going short."); OpenPosition(TradeType.Sell); rangeBroken = true; } } else // No moving average filter { // Breakout: Buy if price breaks above the range if (!rangeBroken && MarketSeries.Close.LastValue > asianHigh) { Print("Breakout detected! Going long."); OpenPosition(TradeType.Buy); rangeBroken = true; } // Breakout: Sell if price breaks below the range else if (!rangeBroken && MarketSeries.Close.LastValue < asianLow) { Print("Breakout detected! Going short."); OpenPosition(TradeType.Sell); rangeBroken = true; } } } else { Print("No trades: Volatility too low. Range: " + range + ", ATR Multiplier: " + atrValue * ATRMultiplier); } }
// Step 3: Close All Positions at the End of New York Session if (currentTime >= newYorkSessionEnd) { CloseAllPositions(); rangeSet = false; // Reset range for the next day Print("New York session ended. Positions closed, range reset."); } }
private void OpenPosition(TradeType tradeType) { var positionSize = CalculatePositionSize(); var stopLossInPips = StopLossPips; var takeProfitInPips = TakeProfitPips;
var result = ExecuteMarketOrder(tradeType, SymbolName, positionSize, "RangeBreakout", stopLossInPips, takeProfitInPips);
if (UseTrailingStop && result.IsSuccessful) { SetTrailingStop(result.Position); } }
private double CalculatePositionSize() { // Risk calculation based on Stop Loss and Account Balance double accountRisk = Account.Balance * RiskPercentage / 100; double pipValue = Symbol.PipValue; double positionSize = accountRisk / (StopLossPips * pipValue);
calamejunior
26 Sep 2024, 04:07 ( Updated at: 26 Sep 2024, 05:02 )
RE: Bots not working on .NET 6
PanagiotisCharalampous said:
@calamejunior