//+------------------------------------------------------------------+ //| Quant Probability V17.0 | //| Logic: Breakout Likelihood | //| Asset: EURUSD (H1/H4) | //+------------------------------------------------------------------+ #property version "17.00" #property description "Statistical Breakout Probability EA" #include #include input group "1. Probability Settings" input bool InpReverseSignals = false; // Reverse Bias input double InpPercStep = 1.0; // Percentage Step for levels input int InpNbrLevels = 1; // Number of Levels to calculate input int InpHistoryBars = 2000; // Lookback for statistics input group "2. ATR Risk Management" input int InpATR_Period = 14; input double InpSL_Multiplier = 2.0; input double InpTP_Multiplier = 4.0; input bool UseAutoBE = true; input group "3. Execution" input double FixedLot = 0.05; input int MagicNumber = 171717; input int MaxSpread = 12; //--- Statistical Counters int g_total_green = 0; int g_total_red = 0; int g_hit_high_green = 0; int g_hit_low_green = 0; int g_hit_high_red = 0; int g_hit_low_red = 0; int HandleATR; CTrade Trade; CPositionInfo Position; //+------------------------------------------------------------------+ //| OnInit: Calculate History Probabilities | //+------------------------------------------------------------------+ int OnInit() { HandleATR = iATR(_Symbol, PERIOD_CURRENT, InpATR_Period); Trade.SetExpertMagicNumber(MagicNumber); // Calculate Historical Data CalculateProbabilities(); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| CalculateProbabilities: The Statistical Engine | //+------------------------------------------------------------------+ void CalculateProbabilities() { MqlRates rates[]; ArraySetAsSeries(rates, true); int copied = CopyRates(_Symbol, PERIOD_CURRENT, 0, InpHistoryBars, rates); if(copied <= 2) return; for(int i = copied-2; i > 0; i--) { bool green = (rates[i+1].close > rates[i+1].open); bool red = (rates[i+1].close < rates[i+1].open); if(green) { g_total_green++; if(rates[i].high >= rates[i+1].high) g_hit_high_green++; if(rates[i].low <= rates[i+1].low) g_hit_low_green++; } if(red) { g_total_red++; if(rates[i].high >= rates[i+1].high) g_hit_high_red++; if(rates[i].low <= rates[i+1].low) g_hit_low_red++; } } } //+------------------------------------------------------------------+ //| OnTick | //+------------------------------------------------------------------+ void OnTick() { if(SymbolInfoInteger(_Symbol, SYMBOL_SPREAD) > MaxSpread) return; static datetime last_bar; datetime current_bar = (datetime)SeriesInfoInteger(_Symbol, PERIOD_CURRENT, SERIES_LASTBAR_DATE); if(current_bar == last_bar) return; last_bar = current_bar; if(CountPositions() == 0) { ExecuteProbStrategy(); } } //+------------------------------------------------------------------+ //| Execute Strategy | //+------------------------------------------------------------------+ void ExecuteProbStrategy() { double atr[]; ArraySetAsSeries(atr, true); if(CopyBuffer(HandleATR, 0, 1, 1, atr) <= 0) return; MqlRates rates[]; ArraySetAsSeries(rates, true); if(CopyRates(_Symbol, PERIOD_CURRENT, 1, 1, rates) <= 0) return; bool is_green = (rates[0].close > rates[0].open); bool is_red = (rates[0].close < rates[0].open); double prob_high = 0; double prob_low = 0; if(is_green && g_total_green > 0) { prob_high = (double)g_hit_high_green / g_total_green; prob_low = (double)g_hit_low_green / g_total_green; } else if(is_red && g_total_red > 0) { prob_high = (double)g_hit_high_red / g_total_red; prob_low = (double)g_hit_low_red / g_total_red; } bool buySignal = (prob_high > prob_low); bool sellSignal = (prob_low > prob_high); if(InpReverseSignals) { bool temp = buySignal; buySignal = sellSignal; sellSignal = temp; } double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double slDist = atr[0] * InpSL_Multiplier; double tpDist = atr[0] * InpTP_Multiplier; if(buySignal && prob_high > 0) { Trade.Buy(FixedLot, _Symbol, ask, ask - slDist, ask + tpDist, "Prob-Long"); } else if(sellSignal && prob_low > 0) { Trade.Sell(FixedLot, _Symbol, bid, bid + slDist, bid - tpDist, "Prob-Short"); } } //+------------------------------------------------------------------+ //| Helpers | //+------------------------------------------------------------------+ int CountPositions() { int count = 0; for(int i = 0; i < PositionsTotal(); i++) { if(Position.SelectByIndex(i)) if(Position.Magic() == MagicNumber && Position.Symbol() == _Symbol) count++; } return count; }