Не корректный трэйлинг отложенного ордера

 

Друзья выручайте!!!

Проблема с тралом отложенного ордера! Суть такая

1. Ордер тралится, но только 1 раз на величину шага!

2. После модификации Тейк пропадает из поля зрения. Во вкладке эксперт появляются некорректные значения = 5-6000 путнктов! И фраза invalid stop

Как я пытался исправить проблему

1. NormalizePrice в функции трала не помогло. Перестал выставлять ордера

2. NormalizeDouble тоже не помогло.

3. Попробовал разные коды реализации этой функции, но только последний вариант оказался близок к истине

Прикрепляю код

//+------------------------------------------------------------------+
//|                                         ZigZag_Sell_Strategy.mq5 |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+

#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//------------Trade classes
#include <Trade/AccountInfo.mqh>
CAccountInfo aInfo;
#include <Trade/PositionInfo.mqh>
CPositionInfo pInfo;
#include <Trade/Trade.mqh>
CTrade trade;
#include <Trade/SymbolInfo.mqh>
CSymbolInfo sInfo;
#include <Trade\OrderInfo.mqh>
COrderInfo oInfo;
//------------------------------
ulong magicNum=74840;
ulong zzTicket = ORDER_TICKET;
//------------Time
datetime firstTime = 0;
datetime curTime[];
//------------Input variables
input double SL=500.1;
input double TP=10.1;
input double lot = 1.0;
input int indent=50;
input int tralStart = 25;
input int tralStep = 25;
input int maxSellOrders=1;
input int zzDepth    =71;  // Depth
input int zzDeviation=18;   // Deviation
input int zzBackstep =20;   // Back Step
//----------------Variables
double stopLoss;
double takeProfit;
double priceClose;
double priceOpen;
double newPrice;
double newStopLoss;
double newTakeProfit;

//---------------Buffers
double zzBuffer[];      // main buffer
double highBarBuffer[];     // ZigZag high extremes (peaks)
double lowBarBuffer[];      // ZigZag low extremes (bottoms)
MqlRates mqlRates[];
int zzHandle=INVALID_HANDLE;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
   zzHandle=iCustom(_Symbol, _Period, "ZigZag_my");
   if(zzHandle == INVALID_HANDLE) {
      Print("Ошибка загрузки данных индикатора ZigZAg", GetLastError());
      return(INIT_FAILED);
   }
   trade.SetExpertMagicNumber(magicNum);

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
   IndicatorRelease(zzHandle);

}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {

   ArraySetAsSeries(zzBuffer, true);
   ArraySetAsSeries(highBarBuffer, true);
   ArraySetAsSeries(lowBarBuffer, true);
   ArraySetAsSeries(mqlRates, true);

   if(CopyTime(_Symbol, _Period, 0, 3, curTime)==-1) {
      Print("Ошибка копирования времени в массив curTime[] ", GetLastError());
      return;
   }
   if(CopyRates(_Symbol, _Period, 0, 3, mqlRates)==-1) {
      Print("Ошибка копирования исторических данных в массив mqlRates[] ", GetLastError());
      return;
   }
   if(CopyBuffer(zzHandle, 0, 0, 3, zzBuffer)==-1) {
      Print("Ошибка копирования данных в массив zzBuffer[] ", GetLastError());
      return;
   }
   if(CopyBuffer(zzHandle, 1, 0, 3, highBarBuffer)==-1) {
      Print("Ошибка копирования данных в массив zzBuffer[] ", GetLastError());
      return;
   }
   if(CopyBuffer(zzHandle, 2, 0, 3, lowBarBuffer)==-1) {
      Print("Ошибка копирования данных в массив zzBuffer[] ", GetLastError());
      return;
   }

   priceClose=mqlRates[1].close;


   if(curTime[0]!=firstTime) {
      if(!checkTrading()) {
         Print("Ошибка выполнения условий для открытия позиций!!! ", GetLastError());
         return;
      }
      if(!openSellStopPos()) {
         Print("Ошибка установки SELLSTOP ордера!!! ", GetLastError());
         return;
      }
      if(!tralSellStopOrder()) {
         Print("Ошибка трэйлинга SELLSTOP ордера!!! ", GetLastError());
         return;
      }

      firstTime=curTime[0];
   }

}
//+------------------------------------------------------------------+
bool checkTrading() {
   bool canTrade=false;
   if(aInfo.TradeAllowed() && aInfo.TradeExpert() && sInfo.IsSynchronized() && aInfo.FreeMargin()) {
      canTrade=true;
   }
   return(canTrade);
}

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
bool openSellStopPos() {

   if(aInfo.MarginMode() == ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) {
      if(OrdersTotal()<maxSellOrders) {
         if(highBarBuffer[1]>lowBarBuffer[0] && highBarBuffer[1]>lowBarBuffer[2]) {
            int spread = sInfo.Spread();
            priceOpen = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID)-indent*_Point - spread*_Point, _Digits);
            stopLoss=NormalizeDouble(priceOpen+SL*_Point, _Digits);
            takeProfit=NormalizeDouble(priceOpen-TP*_Point, _Digits);
            trade.SellStop(lot, priceOpen, _Symbol, stopLoss, takeProfit, ORDER_TIME_DAY, 0);
         }
      }
   }
   return(true);
}

//+------------------------------------------------------------------+
bool tralSellStopOrder() {

   for(int i = OrdersTotal()-1; i>=0; i-- ) {
      if(oInfo.SelectByIndex(i)) {
         if(oInfo.Symbol()==_Symbol && oInfo.Magic()==magicNum) {
            if(oInfo.OrderType()==ORDER_TYPE_SELL_STOP) {
               if(oInfo.PriceCurrent()+(tralStart+tralStep)*_Point < oInfo.StopLoss()) {
                  newPrice=oInfo.PriceCurrent()-tralStart*_Point;
                  newStopLoss=newPrice+(priceOpen+oInfo.StopLoss());
                  newTakeProfit=newPrice-(priceOpen-oInfo.TakeProfit());
                  trade.OrderModify(oInfo.Ticket(), newPrice, newStopLoss, newTakeProfit, ORDER_TIME_DAY, 0);
               }
            }
         }
      }
   }
   return(true);
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
 
kirillyurkov:

Друзья выручайте!!!

Проблема с тралом отложенного ордера! Суть такая

  1. Ордер тралится, но только 1 раз на величину шага!
  2. После модификации Тейк пропадает из поля зрения. Во вкладке эксперт появляются некорректные значения = 5-6000 путнктов! И фраза invalid stop

Как я пытался исправить проблему

  1.  NormalizePrice в функции трала не помогло. Перестал выставлять ордера
  2.  NormalizeDouble тоже не помогло.
  3.  Попробовал разные коды реализации этой функции, но только последний вариант оказался близок к истине

Прикрепляю код

Здравствуйте, Кирилл!

В Вашем коде несколько моментов, которые не дают нормально работать советнику. Там, где внёс исправления, оставил свои комментарии. Трейлинг отложенного ордера пришлось полностью переделать. Надеюсь, что разберётесь, тем более потенциал роста в программировании у Вас очень высокий, по сравнению с моим. Чтобы не плодить "портянки", исправленный код советника прикрепляю в файле.

С уважением, Владимир.

Файлы:
 
MrBrooklin #:

Здравствуйте, Кирилл!

В Вашем коде несколько моментов, которые не дают нормально работать советнику. Там, где внёс исправления, оставил свои комментарии. Трейлинг отложенного ордера пришлось полностью переделать. Надеюсь, что разберётесь, тем более потенциал роста в программировании у Вас очень высокий, по сравнению с моим. Чтобы не плодить "портянки", исправленный код советника прикрепляю в файле.

С уважением, Владимир.

Владимир, спасибо!! Помогли разобраться!! Код рабочий! Можно юзать!! Будет здорово если кому то еще пригодится!!!

 

Кое что тоже сам додумал. Практически нет разницы в кодах. Использую класс СOrderInfo. Не тралю ордер на каждом тике. Трал происходит на открытии новой свечи прои соблюдении условия. Буду рад если кому-то это поможет. Для buystop нужно просто перевернуть SL i TP. Советник не плохо выкупает и продает коррекции на тренде по более выгодным ценам. Но тренд нужно определять самим. Этого "дурака" я пока не знаю как этому научить)) 

//+------------------------------------------------------------------+
//|                                         ZigZag_Sell_Strategy.mq5 |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+

#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//------------Trade classes
#include <Trade/AccountInfo.mqh>
CAccountInfo aInfo;
#include <Trade/PositionInfo.mqh>
CPositionInfo pInfo;
#include <Trade/Trade.mqh>
CTrade trade;
#include <Trade/SymbolInfo.mqh>
CSymbolInfo sInfo;
#include <Trade\OrderInfo.mqh>
COrderInfo oInfo;
//------------------------------
ulong magicNum=74840;
ulong orderTicket = ORDER_TICKET;
ulong positionTicket = POSITION_TICKET;
//------------Time
datetime firstTime = 0;
datetime curTime[];
//------------Input variables
input int  SL=1000;
input int  TP=10;
input double lot = 1.0;
input int indent=50;
input int tralStart = 25;
input int tralStep = 25;
input int maxSellOrders=1;
input int zzDepth    =71;  // Depth
input int zzDeviation=18;   // Deviation
input int zzBackstep =20;   // Back Step
//----------------Variables
int spread;
double stopLoss=0;
double takeProfit=0;
double priceClose;
double priceOpen;
double newPrice;
double newStopLoss=0;
double newTakeProfit=0;

//---------------Buffers
double zzBuffer[];      // main buffer
double highBarBuffer[];     // ZigZag high extremes (peaks)
double lowBarBuffer[];      // ZigZag low extremes (bottoms)
MqlRates mqlRates[];
int zzHandle=INVALID_HANDLE;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
   zzHandle=iCustom(_Symbol, _Period, "ZigZag_my");
   if(zzHandle == INVALID_HANDLE) {
      Print("Ошибка загрузки данных индикатора ZigZAg", GetLastError());
      return(INIT_FAILED);
   }
   trade.SetExpertMagicNumber(magicNum);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
   IndicatorRelease(zzHandle);

}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {

   ArraySetAsSeries(zzBuffer, true);
   ArraySetAsSeries(highBarBuffer, true);
   ArraySetAsSeries(lowBarBuffer, true);
   ArraySetAsSeries(mqlRates, true);

   if(CopyTime(_Symbol, _Period, 0, 3, curTime)==-1) {
      Print("Ошибка копирования времени в массив curTime[] ", GetLastError());
      return;
   }
   if(CopyRates(_Symbol, _Period, 0, 3, mqlRates)==-1) {
      Print("Ошибка копирования исторических данных в массив mqlRates[] ", GetLastError());
      return;
   }
   if(CopyBuffer(zzHandle, 0, 0, 3, zzBuffer)==-1) {
      Print("Ошибка копирования данных в массив zzBuffer[] ", GetLastError());
      return;
   }
   if(CopyBuffer(zzHandle, 1, 0, 3, highBarBuffer)==-1) {
      Print("Ошибка копирования данных в массив zzBuffer[] ", GetLastError());
      return;
   }
   if(CopyBuffer(zzHandle, 2, 0, 3, lowBarBuffer)==-1) {
      Print("Ошибка копирования данных в массив zzBuffer[] ", GetLastError());
      return;
   }

   priceClose=mqlRates[1].close;


   if(curTime[0]!=firstTime) {
      if(!checkTrading()) {
         Print("Ошибка выполнения условий для открытия позиций!!! ", GetLastError());
         return;
      }
      if(!openSellStopOrder()) {
         Print("Ошибка установки SELLSTOP ордера!!! ", GetLastError());
         return;
      }
      if(!tralSellStopOrder()) {
         Print("Ошибка трэйлинга SELLSTOP ордера!!! ", GetLastError());
         return;
      }

      firstTime=curTime[0];
   }

}
//+------------------------------------------------------------------+
bool checkTrading() {
   bool canTrade=false;
   if(aInfo.TradeAllowed() && aInfo.TradeExpert() && sInfo.IsSynchronized() && aInfo.FreeMargin()) {
      canTrade=true;
   }
   return(canTrade);
}

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
bool openSellStopOrder() {

   if(aInfo.MarginMode() == ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) {
      if(OrdersTotal()<maxSellOrders) {
         if(highBarBuffer[1]>lowBarBuffer[0] && highBarBuffer[1]>lowBarBuffer[2]) {
            priceOpen = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID)-indent*_Point, _Digits);
            stopLoss=NormalizeDouble(priceOpen+SL*_Point, _Digits);
            takeProfit=NormalizeDouble(priceOpen-TP*_Point, _Digits);
            trade.SellStop(lot, priceOpen, _Symbol, stopLoss, takeProfit, ORDER_TIME_DAY, 0);
         }
      }
   }
   return(true);
}

//+------------------------------------------------------------------+
bool tralSellStopOrder() {

   for(int i = OrdersTotal()-1; i>=0; i-- ) {
      if(oInfo.SelectByIndex(i)) {
         if(oInfo.Symbol()==_Symbol && oInfo.Magic()==magicNum) {
            if(oInfo.OrderType()==ORDER_TYPE_SELL_STOP) {
               if(oInfo.PriceCurrent()-priceOpen>tralStart*_Point) {
                  newPrice=oInfo.PriceCurrent()-tralStart*_Point;
                  newStopLoss=newPrice+SL*_Point;
                  newTakeProfit = MathAbs(newPrice-TP*_Point);
                  trade.OrderModify(oInfo.Ticket(), NormalizeDouble(newPrice, _Digits),
                                    NormalizeDouble(newStopLoss, _Digits),
                                    NormalizeDouble(newTakeProfit, _Digits), ORDER_TIME_DAY, 0);
               }
            }
         }
      }
   }
   return(true);
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
Причина обращения: