Advertisement
cjmt2

MultiTF_CandleOverlayEA

Jun 19th, 2025
441
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.47 KB | Source Code | 0 0
  1. //+-------------------------------------------------------------------------------------+
  2. //|                                                         MultiTF_CandleOverlayEA.mq5 |
  3. //|                        Expert pentru multiple timeframe overlay și trade management |
  4. //+-------------------------------------------------------------------------------------+
  5. #property copyright "ChatGPT"
  6. #property version   "1.00"
  7. #property strict
  8. #define ColorAqua clrAqua
  9. #define ColorRed clrRed
  10.  
  11. input double Lots       = 0.1;
  12. input double SL_Points  = 100;    // stop loss in points
  13. input double TP_Points  = 200;    // take profit in points
  14. input double TrailStart = 50;     // trailing start in points
  15. input double TrailStep  = 20;     // trailing step in points
  16.  
  17. //--- simbolul curent
  18. string symbol;
  19.  
  20. //--- handle-uri pentru timeframe-uri
  21. ENUM_TIMEFRAMES tfH1 = PERIOD_H1;
  22. ENUM_TIMEFRAMES tfH4 = PERIOD_H4;
  23. ENUM_TIMEFRAMES tfD1 = PERIOD_D1;
  24. ENUM_TIMEFRAMES tfW1 = PERIOD_W1;
  25.  
  26. //--- nume obiecte grafice
  27. string objNameH1 = "Candle_H1";
  28. string objNameH4 = "Candle_H4";
  29. string objNameD1 = "Candle_D1";
  30. string objNameW1 = "Candle_W1";
  31.  
  32. //+------------------------------------------------------------------+
  33. //| Expert initialization function                                   |
  34. //+------------------------------------------------------------------+
  35. int OnInit()
  36.   {
  37.    symbol = _Symbol;
  38.    //ChartSetInteger(0, CHART_SHOW_PERIOD_SEPARATORS, false); // ascunde liniile perioadelor pentru claritate
  39.  
  40.    // curata obiecte vechi
  41.    ObjectDelete(0,objNameH1);
  42.    ObjectDelete(0,objNameH4);
  43.    ObjectDelete(0,objNameD1);
  44.    ObjectDelete(0,objNameW1);
  45.  
  46.    return(INIT_SUCCEEDED);
  47.   }
  48.  
  49. //+------------------------------------------------------------------+
  50. //| Functie pentru obtinerea valorilor OHLC pentru o anumita TF      |
  51. //+------------------------------------------------------------------+
  52. bool GetOHLC(ENUM_TIMEFRAMES tf, datetime &time_open, double &open, double &high, double &low, double &close)
  53.   {
  54.    MqlRates rates[];
  55.    if(CopyRates(symbol, tf, 0, 1, rates) != 1)
  56.      return(false);
  57.  
  58.    time_open = rates[0].time;
  59.    open  = rates[0].open;
  60.    high  = rates[0].high;
  61.    low   = rates[0].low;
  62.    close = rates[0].close;
  63.    return(true);
  64.   }
  65.  
  66. //+------------------------------------------------------------------+
  67. //| Functie desenare candela suprapusa pe M1                         |
  68. //+------------------------------------------------------------------+
  69. void DrawCandleOverlay(string name, datetime time_open, double open, double high, double low, double close, color col)
  70.   {
  71.    // Șterge obiectul vechi daca exista
  72.    ObjectDelete(0,name);
  73.  
  74.    // Creaza un obiect rectangle pe grafic cu următoarele coordonate:
  75.    // pe orizontala, de la time_open pana la timpul curent (acum)
  76.    // pe verticala, intre low si high
  77.  
  78.    datetime time_now = TimeCurrent();
  79.  
  80.    // creeaza rectangle
  81.    if(!ObjectCreate(0, name, OBJ_RECTANGLE, 0, time_open, high, time_now, low))
  82.      {
  83.       Print("Eroare la crearea obiectului ", name);
  84.       return;
  85.      }
  86.  
  87.    // setari vizuale
  88.    ObjectSetInteger(0, name, OBJPROP_COLOR, col);
  89.    ObjectSetInteger(0, name, OBJPROP_BACK, true);      // sa fie in spate
  90.    ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
  91.    ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);
  92.  
  93.    // Opacitate in functie de close > open
  94.    if(close > open)
  95.       ObjectSetInteger(0, name, OBJPROP_BGCOLOR, ColorToARGB(ColorAqua, 60));
  96.    else
  97.       ObjectSetInteger(0, name, OBJPROP_BGCOLOR, ColorToARGB(ColorRed, 60));
  98.   }
  99.  
  100. //+------------------------------------------------------------------+
  101. //| Functie pentru conversia culorii cu opacitate                   |
  102. //+------------------------------------------------------------------+
  103. ulong ColorToARGBAlpha(color c, uchar alpha)
  104.   {
  105.    return(((ulong)alpha << 24) | ((ulong)c & 0xFFFFFF));
  106.   }
  107.  
  108. //+------------------------------------------------------------------+
  109. //| Verifica regula simpla de intrare                                 |
  110. //+------------------------------------------------------------------+
  111. int CheckTradeSignal()
  112.   {
  113.    datetime t_open;
  114.    double open, high, low, close;
  115.  
  116.    // Preluam OHLC pentru fiecare timeframe
  117.    if(!GetOHLC(tfH1, t_open, open, high, low, close)) return 0;
  118.    bool h1Buy  = (close > open);
  119.    bool h1Sell = (close < open);
  120.  
  121.    if(!GetOHLC(tfH4, t_open, open, high, low, close)) return 0;
  122.    bool h4Buy  = (close > open);
  123.    bool h4Sell = (close < open);
  124.  
  125.    if(!GetOHLC(tfD1, t_open, open, high, low, close)) return 0;
  126.    bool d1Buy  = (close > open);
  127.    bool d1Sell = (close < open);
  128.  
  129.    if(!GetOHLC(tfW1, t_open, open, high, low, close)) return 0;
  130.    bool w1Buy  = (close > open);
  131.    bool w1Sell = (close < open);
  132.  
  133.    // Conditii pentru BUY: toate in sus
  134.    if(h1Buy && h4Buy && d1Buy && w1Buy) return 1;
  135.  
  136.    // Conditii pentru SELL: toate in jos
  137.    if(h1Sell && h4Sell && d1Sell && w1Sell) return -1;
  138.  
  139.    return 0; // fara semnal clar
  140.   }
  141.  
  142. //+------------------------------------------------------------------+
  143. //| Functie executie ordine BUY                                       |
  144. //+------------------------------------------------------------------+
  145. bool OpenBuy()
  146.   {
  147.    double price = SymbolInfoDouble(symbol, SYMBOL_ASK);
  148.    double sl    = price - SL_Points * _Point;
  149.    double tp    = price + TP_Points * _Point;
  150.  
  151.    MqlTradeRequest request;
  152.    MqlTradeResult  result;
  153.    ZeroMemory(request);
  154.    ZeroMemory(result);
  155.  
  156.    request.action   = TRADE_ACTION_DEAL;
  157.    request.symbol   = symbol;
  158.    request.volume   = Lots;
  159.    request.type     = ORDER_TYPE_BUY;
  160.    request.price    = price;
  161.    request.sl       = sl;
  162.    request.tp       = tp;
  163.    request.deviation= 10;
  164.    request.magic    = 123456;
  165.    request.comment  = "MultiTF_Buy";
  166.  
  167.    if(!OrderSend(request, result))
  168.      {
  169.       Print("Eroare la deschiderea BUY: ", GetLastError());
  170.       return false;
  171.      }
  172.    Print("Buy deschis la ", price);
  173.    return true;
  174.   }
  175.  
  176. //+------------------------------------------------------------------+
  177. //| Functie executie ordine SELL                                      |
  178. //+------------------------------------------------------------------+
  179. bool OpenSell()
  180.   {
  181.    double price = SymbolInfoDouble(symbol, SYMBOL_BID);
  182.    double sl    = price + SL_Points * _Point;
  183.    double tp    = price - TP_Points * _Point;
  184.  
  185.    MqlTradeRequest request;
  186.    MqlTradeResult  result;
  187.    ZeroMemory(request);
  188.    ZeroMemory(result);
  189.  
  190.    request.action   = TRADE_ACTION_DEAL;
  191.    request.symbol   = symbol;
  192.    request.volume   = Lots;
  193.    request.type     = ORDER_TYPE_SELL;
  194.    request.price    = price;
  195.    request.sl       = sl;
  196.    request.tp       = tp;
  197.    request.deviation= 10;
  198.    request.magic    = 123456;
  199.    request.comment  = "MultiTF_Sell";
  200.  
  201.    if(!OrderSend(request, result))
  202.      {
  203.       Print("Eroare la deschiderea SELL: ", GetLastError());
  204.       return false;
  205.      }
  206.    Print("Sell deschis la ", price);
  207.    return true;
  208.   }
  209.  
  210. //+------------------------------------------------------------------+
  211. //| Functie de gestionare a trailing stop                            |
  212. //+------------------------------------------------------------------+
  213. void ManageTrailingStop()
  214.   {
  215.    ulong magic = 123456;
  216.    for(int i=PositionsTotal()-1; i>=0; i--)
  217.      {
  218.       ulong ticket = PositionGetTicket(i);
  219.       if(PositionGetInteger(POSITION_MAGIC) != magic) continue;
  220.       if(PositionGetString(POSITION_SYMBOL) != symbol) continue;
  221.  
  222.       double open_price = PositionGetDouble(POSITION_PRICE_OPEN);
  223.       double current_price = SymbolInfoDouble(symbol, (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) ? SYMBOL_BID : SYMBOL_ASK);
  224.       double sl = PositionGetDouble(POSITION_SL);
  225.       ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
  226.  
  227.       // Calculate profit in points
  228.       double profit_points = (pos_type==POSITION_TYPE_BUY) ? (current_price - open_price)/_Point : (open_price - current_price)/_Point;
  229.  
  230.       if(profit_points > TrailStart)
  231.         {
  232.          double new_sl;
  233.          if(pos_type==POSITION_TYPE_BUY)
  234.            {
  235.             new_sl = current_price - TrailStep * _Point;
  236.             if(new_sl > sl)
  237.               {
  238.                // modifica SL in trailing
  239.                ModifyPositionSL(ticket, new_sl);
  240.               }
  241.            }
  242.          else
  243.            {
  244.             new_sl = current_price + TrailStep * _Point;
  245.             if(new_sl < sl || sl==0)
  246.               {
  247.                ModifyPositionSL(ticket, new_sl);
  248.               }
  249.            }
  250.         }
  251.      }
  252.   }
  253.  
  254. //+------------------------------------------------------------------+
  255. //| Modificare SL pozitie                                            |
  256. //+------------------------------------------------------------------+
  257. void ModifyPositionSL(ulong ticket, double new_sl)
  258.   {
  259.    MqlTradeRequest request;
  260.    MqlTradeResult  result;
  261.    ZeroMemory(request);
  262.    ZeroMemory(result);
  263.  
  264.    request.action   = TRADE_ACTION_SLTP;
  265.    request.position = ticket;
  266.    request.sl       = new_sl;
  267.    request.tp       = PositionGetDouble(POSITION_TP);
  268.  
  269.    if(!OrderSend(request, result))
  270.      {
  271.       Print("Eroare la modificarea SL: ", GetLastError());
  272.      }
  273.    else
  274.       Print("SL modificat la ", DoubleToString(new_sl, _Digits));
  275.   }
  276.  
  277. //+------------------------------------------------------------------+
  278. //| Functia principala OnTick                                        |
  279. //+------------------------------------------------------------------+
  280. void OnTick()
  281.   {
  282.    // 1. Afisare candela suprapusa pe fiecare timeframe
  283.    datetime t_open; double open, high, low, close;
  284.    if(GetOHLC(tfH1, t_open, open, high, low, close))
  285.       DrawCandleOverlay(objNameH1, t_open, open, high, low, close, (close>open) ? clrAqua : clrRed);
  286.  
  287.    if(GetOHLC(tfH4, t_open, open, high, low, close))
  288.       DrawCandleOverlay(objNameH4, t_open, open, high, low, close, (close>open) ? clrAqua : clrRed);
  289.  
  290.    if(GetOHLC(tfD1, t_open, open, high, low, close))
  291.       DrawCandleOverlay(objNameD1, t_open, open, high, low, close, (close>open) ? clrAqua : clrRed);
  292.  
  293.    if(GetOHLC(tfW1, t_open, open, high, low, close))
  294.       DrawCandleOverlay(objNameW1, t_open, open, high, low, close, (close>open) ? clrAqua : clrRed);
  295.  
  296.    // 2. Verificam semnalul
  297.    int signal = CheckTradeSignal();
  298.  
  299.    // 3. Managementul pozitiei
  300.    ulong magic = 123456;
  301.    bool hasPosition = false;
  302.    ENUM_POSITION_TYPE pos_type = POSITION_TYPE_BUY;
  303.  
  304.    for(int i=PositionsTotal()-1; i>=0; i--)
  305.      {
  306.       if(PositionGetInteger(POSITION_MAGIC) != magic) continue;
  307.       if(PositionGetString(POSITION_SYMBOL) != symbol) continue;
  308.  
  309.       hasPosition = true;
  310.       pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
  311.       break;
  312.      }
  313.  
  314.    // 4. Executie ordine conform semnalului si pozitiei existente
  315.    if(signal == 1)  // BUY
  316.      {
  317.       if(!hasPosition || pos_type == POSITION_TYPE_SELL)
  318.         {
  319.          // inchidem sell daca exista
  320.          if(hasPosition && pos_type == POSITION_TYPE_SELL)
  321.            ClosePosition(symbol, POSITION_TYPE_SELL);
  322.  
  323.          // deschidem BUY
  324.          OpenBuy();
  325.         }
  326.      }
  327.    else if(signal == -1) // SELL
  328.      {
  329.       if(!hasPosition || pos_type == POSITION_TYPE_BUY)
  330.         {
  331.          // inchidem buy daca exista
  332.          if(hasPosition && pos_type == POSITION_TYPE_BUY)
  333.            ClosePosition(symbol, POSITION_TYPE_BUY);
  334.  
  335.          // deschidem SELL
  336.          OpenSell();
  337.         }
  338.      }
  339.    else
  340.      {
  341.       // fara semnal inchidem toate pozitiile noastre
  342.       if(hasPosition)
  343.         CloseAllPositions(symbol, magic);
  344.      }
  345.  
  346.    // 5. Management trailing stop
  347.    ManageTrailingStop();
  348.   }
  349.  
  350. //+------------------------------------------------------------------+
  351. //| Inchide pozitie dupa tip                                          |
  352. //+------------------------------------------------------------------+
  353. void ClosePosition(string symb, ENUM_POSITION_TYPE type)
  354.   {
  355.    for(int i=PositionsTotal()-1; i>=0; i--)
  356.      {
  357.       if(PositionGetInteger(POSITION_MAGIC) != 123456) continue;
  358.       if(PositionGetString(POSITION_SYMBOL) != symb) continue;
  359.       if(PositionGetInteger(POSITION_TYPE) != type) continue;
  360.  
  361.       ulong ticket = PositionGetTicket(i);
  362.       ClosePositionByTicket(ticket);
  363.      }
  364.   }
  365.  
  366. //+------------------------------------------------------------------+
  367. //| Inchide toate pozitiile pentru simbol si magic                   |
  368. //+------------------------------------------------------------------+
  369. void CloseAllPositions(string symb, ulong magic)
  370.   {
  371.    for(int i=PositionsTotal()-1; i>=0; i--)
  372.      {
  373.       if(PositionGetInteger(POSITION_MAGIC) != magic) continue;
  374.       if(PositionGetString(POSITION_SYMBOL) != symb) continue;
  375.  
  376.       ulong ticket = PositionGetTicket(i);
  377.       ClosePositionByTicket(ticket);
  378.      }
  379.   }
  380.  
  381. //+------------------------------------------------------------------+
  382. //| Inchide pozitia dupa ticket                                       |
  383. //+------------------------------------------------------------------+
  384. void ClosePositionByTicket(ulong ticket)
  385.   {
  386.    MqlTradeRequest request;
  387.    MqlTradeResult  result;
  388.    ZeroMemory(request);
  389.    ZeroMemory(result);
  390.  
  391.    request.action = TRADE_ACTION_CLOSE_BY;
  392.    request.position = ticket;
  393.  
  394.    if(!OrderSend(request,result))
  395.      Print("Eroare inchidere pozitie: ", GetLastError());
  396.    else
  397.      Print("Pozitie inchisa, ticket: ", ticket);
  398.   }
  399. //+------------------------------------------------------------------+
  400.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement