رباط

MQL5 Experts Scripts

Spécifications

//+------------------------------------------------------------------+
//|                                            AdvancedPriceAction.mq5 |
//|                                 Copyright 2026, Trading Strategy AI |
//+------------------------------------------------------------------+
#property copyright "Trading Strategy AI"
#property version   "1.00"
#property strict

#include <Trade\Trade.mqh>

input group "Trading Settings"
input double RiskPercent      = 0.5;
input int    MagicNumber      = 123456;
input int    MaxSpread        = 20;
input int    SlippagePoints   = 10;
input bool   AllowAutoTrading = true;
input bool   AllowManualExit  = true;

input group "Timeframe Settings"
input ENUM_TIMEFRAMES StructureTF = PERIOD_M15;
input ENUM_TIMEFRAMES SwingTF     = PERIOD_M5;
input ENUM_TIMEFRAMES EntryTF     = PERIOD_M1;

input group "Logic Settings"
input int    SwingLookback     = 120;
input int    SwingDepth        = 2;
input int    LevelMergePoints  = 25;
input int    FanStepPoints     = 150;
input int    FanCount          = 4;
input int    StopBufferPoints  = 20;
input int    ReactionBufferPts = 15;
input double BreakoutRR        = 2.0;
input double ReactionRR        = 1.0;

CTrade trade;
string prefix = "APA_";
datetime last_entry_bar = 0;

double levels[];
double last_high = 0.0, last_low = 0.0;
datetime last_high_time = 0, last_low_time = 0;

double P() { return SymbolInfoDouble(_Symbol, SYMBOL_POINT); }
int SpreadPts() { return (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD); }

double Norm(double v) { return NormalizeDouble(v, _Digits); }

double ClampLot(double lot)
{
   double minv = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double maxv = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
   double step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
   lot = MathMax(minv, MathMin(maxv, lot));
   lot = MathFloor(lot / step) * step;
   return NormalizeDouble(lot, 2);
}

double LotsByRisk(double sl_points)
{
   if(sl_points <= 0) return ClampLot(SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN));
   double bal = AccountInfoDouble(ACCOUNT_BALANCE);
   double risk_money = bal * RiskPercent / 100.0;
   double tick_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
   double tick_size  = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
   if(tick_value <= 0 || tick_size <= 0) return ClampLot(SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN));
   double value_per_point = tick_value * (P() / tick_size);
   return ClampLot(risk_money / (sl_points * value_per_point));
}

bool NewBar(ENUM_TIMEFRAMES tf, datetime &stamp)
{
   datetime t = iTime(_Symbol, tf, 0);
   if(t == 0 || t == stamp) return false;
   stamp = t;
   return true;
}

bool HasOpenPosition()
{
   for(int i = PositionsTotal() - 1; i >= 0; --i)
   {
      ulong ticket = PositionGetTicket(i);
      if(ticket == 0) continue;
      if(PositionGetString(POSITION_SYMBOL) == _Symbol && (int)PositionGetInteger(POSITION_MAGIC) == MagicNumber)
         return true;
   }
   return false;
}

bool CloseByType(long pos_type = -1)
{
   bool ok = true;
   for(int i = PositionsTotal() - 1; i >= 0; --i)
   {
      ulong ticket = PositionGetTicket(i);
      if(ticket == 0) continue;
      if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
      if((int)PositionGetInteger(POSITION_MAGIC) != MagicNumber) continue;
      long type = PositionGetInteger(POSITION_TYPE);
      if(pos_type != -1 && type != pos_type) continue;
      if(!trade.PositionClose(ticket)) ok = false;
   }
   return ok;
}

void AddLevel(double price)
{
   double band = LevelMergePoints * P();
   for(int i = 0; i < ArraySize(levels); ++i)
   {
      if(MathAbs(levels[i] - price) <= band)
      {
         levels[i] = (levels[i] + price) * 0.5;
         return;
      }
   }
   int n = ArraySize(levels);
   ArrayResize(levels, n + 1);
   levels[n] = price;
}

bool SwingAt(MqlRates &r[], int i)
{
   for(int j = 1; j <= SwingDepth; ++j)
   {
      if(r[i].high <= r[i - j].high || r[i].high < r[i + j].high) return false;
   }
   return true;
}

bool SwingLowAt(MqlRates &r[], int i)
{
   for(int j = 1; j <= SwingDepth; ++j)
   {
      if(r[i].low >= r[i - j].low || r[i].low > r[i + j].low) return false;
   }
   return true;
}

void BuildStructure()
{
   MqlRates r[];
   int n = CopyRates(_Symbol, SwingTF, 1, SwingLookback, r);
   if(n <= SwingDepth * 2 + 1) return;

   ArrayResize(levels, 0);
   for(int i = SwingDepth; i < n - SwingDepth; ++i)
   {
      if(SwingAt(r, i))
      {
         last_high = r[i].high;
         last_high_time = r[i].time;
         AddLevel(r[i].high);
      }
      if(SwingLowAt(r, i))
      {
         last_low = r[i].low;
         last_low_time = r[i].time;
         AddLevel(r[i].low);
      }
   }
}

void DrawLevels()
{
   for(int i = ObjectsTotal(0, 0, -1) - 1; i >= 0; --i)
   {
      string name = ObjectName(0, i, 0, -1);
      if(StringFind(name, prefix + "LVL_") == 0 || StringFind(name, prefix + "FAN_") == 0)
         ObjectDelete(0, name);
   }

   for(int i = 0; i < ArraySize(levels); ++i)
   {
      string name = prefix + "LVL_" + IntegerToString(i);
      ObjectCreate(0, name, OBJ_HLINE, 0, 0, levels[i]);
      ObjectSetInteger(0, name, OBJPROP_COLOR, clrSilver);
      ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DOT);
   }

   datetime t0 = (last_high_time > last_low_time ? last_high_time : last_low_time);
   double p0 = (last_high_time > last_low_time ? last_high : last_low);
   bool fromHigh = last_high_time > last_low_time;
   for(int k = 1; k <= FanCount; ++k)
   {
      string name = prefix + "FAN_" + IntegerToString(k);
      double p1 = fromHigh ? p0 - k * FanStepPoints * P() : p0 + k * FanStepPoints * P();
      ObjectCreate(0, name, OBJ_TREND, 0, t0, p0, TimeCurrent() + PeriodSeconds(EntryTF) * 300, p1);
      ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, true);
      ObjectSetInteger(0, name, OBJPROP_COLOR, fromHigh ? clrTomato : clrLimeGreen);
   }
}

bool CloseAbove(double level)
{
   MqlRates b[2];
   if(CopyRates(_Symbol, EntryTF, 1, 2, b) != 2) return false;
   return (b[0].close > level && b[1].close <= level);
}

bool CloseBelow(double level)
{
   MqlRates b[2];
   if(CopyRates(_Symbol, EntryTF, 1, 2, b) != 2) return false;
   return (b[0].close < level && b[1].close >= level);
}

bool BullReaction(double level)
{
   MqlRates b[1];
   if(CopyRates(_Symbol, EntryTF, 1, 1, b) != 1) return false;
   double buf = ReactionBufferPts * P();
   return (b[0].low <= level + buf && b[0].close > b[0].open && b[0].close > level);
}

bool BearReaction(double level)
{
   MqlRates b[1];
   if(CopyRates(_Symbol, EntryTF, 1, 1, b) != 1) return false;
   double buf = ReactionBufferPts * P();
   return (b[0].high >= level - buf && b[0].close < b[0].open && b[0].close < level);
}

bool NearLevel(double price, double &lvl)
{
   double best = DBL_MAX;
   bool found = false;
   for(int i = 0; i < ArraySize(levels); ++i)
   {
      double d = MathAbs(price - levels[i]);
      if(d < best)
      {
         best = d;
         lvl = levels[i];
         found = true;
      }
   }
   return found && best <= (LevelMergePoints + ReactionBufferPts) * P();
}

void Buy(double sl, double tp)
{
   double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double lot = LotsByRisk(MathAbs(ask - sl) / P());
   trade.SetExpertMagicNumber(MagicNumber);
   trade.SetDeviationInPoints(SlippagePoints);
   trade.Buy(lot, _Symbol, ask, Norm(sl), Norm(tp), "APA BUY");
}

void Sell(double sl, double tp)
{
   double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double lot = LotsByRisk(MathAbs(sl - bid) / P());
   trade.SetExpertMagicNumber(MagicNumber);
   trade.SetDeviationInPoints(SlippagePoints);
   trade.Sell(lot, _Symbol, bid, Norm(sl), Norm(tp), "APA SELL");
}

void EvaluateSignals()
{
   if(!AllowAutoTrading || SpreadPts() > MaxSpread || HasOpenPosition()) return;

   MqlRates b[1];
   if(CopyRates(_Symbol, EntryTF, 1, 1, b) != 1) return;
   double c = b[0].close;
   double lvl = 0.0;

   if(last_high > 0 && CloseAbove(last_high))
   {
      double sl = last_low - StopBufferPoints * P();
      double tp = c + (c - sl) * BreakoutRR;
      Buy(sl, tp);
      return;
   }
   if(last_low > 0 && CloseBelow(last_low))
   {
      double sl = last_high + StopBufferPoints * P();
      double tp = c - (sl - c) * BreakoutRR;
      Sell(sl, tp);
      return;
   }

   if(NearLevel(c, lvl))
   {
      if(BullReaction(lvl))
      {
         double sl = lvl - StopBufferPoints * P();
         double tp = c + (c - sl) * ReactionRR;
         Buy(sl, tp);
      }
      else if(BearReaction(lvl))
      {
         double sl = lvl + StopBufferPoints * P();
         double tp = c - (sl - c) * ReactionRR;
         Sell(sl, tp);
      }
   }
}

void Panel()
{
   string b = prefix + "BTN_";
   if(ObjectFind(0, b + "ALL") < 0)
   {
      ObjectCreate(0, b + "ALL", OBJ_BUTTON, 0, 0, 0);
      ObjectSetInteger(0, b + "ALL", OBJPROP_XDISTANCE, 20);
      ObjectSetInteger(0, b + "ALL", OBJPROP_YDISTANCE, 20);
      ObjectSetInteger(0, b + "ALL", OBJPROP_XSIZE, 90);
      ObjectSetInteger(0, b + "ALL", OBJPROP_YSIZE, 22);
      ObjectSetString(0, b + "ALL", OBJPROP_TEXT, "Close All");
   }
   if(ObjectFind(0, b + "BUY") < 0)
   {
      ObjectCreate(0, b + "BUY", OBJ_BUTTON, 0, 0, 0);
      ObjectSetInteger(0, b + "BUY", OBJPROP_XDISTANCE, 120);
      ObjectSetInteger(0, b + "BUY", OBJPROP_YDISTANCE, 20);
      ObjectSetInteger(0, b + "BUY", OBJPROP_XSIZE, 90);
      ObjectSetInteger(0, b + "BUY", OBJPROP_YSIZE, 22);
      ObjectSetString(0, b + "BUY", OBJPROP_TEXT, "Close Buy");
   }
   if(ObjectFind(0, b + "SELL") < 0)
   {
      ObjectCreate(0, b + "SELL", OBJ_BUTTON, 0, 0, 0);
      ObjectSetInteger(0, b + "SELL", OBJPROP_XDISTANCE, 220);
      ObjectSetInteger(0, b + "SELL", OBJPROP_YDISTANCE, 20);
      ObjectSetInteger(0, b + "SELL", OBJPROP_XSIZE, 90);
      ObjectSetInteger(0, b + "SELL", OBJPROP_YSIZE, 22);
      ObjectSetString(0, b + "SELL", OBJPROP_TEXT, "Close Sell");
   }
}

void Status()
{
   string n = prefix + "STATUS";
   string txt = "APA | spread=" + IntegerToString(SpreadPts()) + " | levels=" + IntegerToString(ArraySize(levels));
   if(ObjectFind(0, n) < 0)
   {
      ObjectCreate(0, n, OBJ_LABEL, 0, 0, 0);
      ObjectSetInteger(0, n, OBJPROP_XDISTANCE, 20);
      ObjectSetInteger(0, n, OBJPROP_YDISTANCE, 52);
      ObjectSetInteger(0, n, OBJPROP_COLOR, clrWhite);
   }
   ObjectSetString(0, n, OBJPROP_TEXT, txt);
}

int OnInit()
{
   trade.SetExpertMagicNumber(MagicNumber);
   trade.SetDeviationInPoints(SlippagePoints);
   Panel();
   return INIT_SUCCEEDED;
}

void OnDeinit(const int reason) { Comment(""); }

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
   if(id != CHARTEVENT_OBJECT_CLICK || !AllowManualExit) return;
   if(sparam == prefix + "BTN_ALL")  CloseByType(-1);
   if(sparam == prefix + "BTN_BUY")  CloseByType(POSITION_TYPE_BUY);
   if(sparam == prefix + "BTN_SELL") CloseByType(POSITION_TYPE_SELL);
}

void OnTick()
{
   if(NewBar(EntryTF, last_entry_bar))
   {
      BuildStructure();
      DrawLevels();
      EvaluateSignals();
      Status();
   }
}

Répondu

1
Développeur 1
Évaluation
Projets
0
0%
Arbitrage
0
En retard
0
Gratuit
2
Développeur 2
Évaluation
(395)
Projets
509
23%
Arbitrage
60
57% / 25%
En retard
59
12%
Chargé
3
Développeur 3
Évaluation
Projets
0
0%
Arbitrage
0
En retard
0
Gratuit
4
Développeur 4
Évaluation
(83)
Projets
95
32%
Arbitrage
9
22% / 56%
En retard
5
5%
Travail
5
Développeur 5
Évaluation
(3)
Projets
4
0%
Arbitrage
1
100% / 0%
En retard
1
25%
Gratuit
6
Développeur 6
Évaluation
(1)
Projets
1
0%
Arbitrage
1
0% / 0%
En retard
0
Travail
7
Développeur 7
Évaluation
(5)
Projets
6
50%
Arbitrage
0
En retard
0
Travail
Publié : 1 code
8
Développeur 8
Évaluation
(1)
Projets
1
0%
Arbitrage
0
En retard
1
100%
Gratuit
9
Développeur 9
Évaluation
Projets
0
0%
Arbitrage
0
En retard
0
Gratuit
10
Développeur 10
Évaluation
Projets
0
0%
Arbitrage
0
En retard
0
Gratuit
11
Développeur 11
Évaluation
Projets
0
0%
Arbitrage
0
En retard
0
Gratuit
12
Développeur 12
Évaluation
Projets
1
0%
Arbitrage
0
En retard
0
Gratuit
13
Développeur 13
Évaluation
(64)
Projets
144
46%
Arbitrage
20
40% / 20%
En retard
32
22%
Gratuit
14
Développeur 14
Évaluation
Projets
0
0%
Arbitrage
0
En retard
0
Gratuit
15
Développeur 15
Évaluation
Projets
0
0%
Arbitrage
0
En retard
0
Gratuit
16
Développeur 16
Évaluation
(1)
Projets
1
0%
Arbitrage
0
En retard
0
Gratuit
Publié : 1 code

Informations sur le projet

Budget
30+ USD

Client

Commandes passées1
Nombre d'arbitrages0