Перетаскивание SL и TP в тестере. - страница 12

 
Andrey Khatimlianskii:

Хвастаетесь? )

Либо показывайте код, либо закрывайте тему.

Код разбросан. Часть в советнике, часть в индикаторе. Полностью советник и индикатор выкладывать не буду. А если какой то конкретный кусок интересует могу выложить. Пишите, что конкретно надо.
 
khorosh:
Код разбросан. Часть в советнике, часть в индикаторе. Полностью советник и индикатор выкладывать не буду. А если какой то конкретный кусок интересует могу выложить. Пишите, что конкретно надо.

Я просто не понимаю, зачем поддерживать ветку, если ваш вопрос уже решен, а остальные от обсуждения ничего не получат.

Предложил добавить конструктива ) 

 
Andrey Khatimlianskii:

Я просто не понимаю, зачем поддерживать ветку, если ваш вопрос уже решен, а остальные от обсуждения ничего не получат.

Предложил добавить конструктива ) 

Ладно, уговорили.) Выкладываю всё что касается перетаскивания SL. Для ТП я пока не делал, не особенно это пока нужно. Ну по аналогии сделать не проблема. Индикатор выкладываю полностью, а из советника выдернул всё, что касается перетаскивания SL. Нововведения языка не изучал, многое делаю по старинке, так что не обессудьте.

Код индикатора:

//+------------------------------------------------------------------+
//|                                      Test_ChartXYToTimePrice.mq4 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "khorosh"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
if(!GlobalVariableCheck(GetNameTF(Period())+" "+Symbol()+" ModifySL"))
  {  
   GlobalVariableSet(GetNameTF(Period())+" "+Symbol()+" ModifySL", 0.0);
  }
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,1);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   if(id==CHARTEVENT_MOUSE_MOVE && IsTesting())
     {
      if(MouseState((uint)sparam)=="DN")
        {
      //--- подготовим переменные
      int      x     =(int)lparam;
      int      y     =(int)dparam;
      datetime dt    =0;
      double   price =0;
      int      window=0;
      //--- преобразуем координаты X и Y  в терминах дата/время
      if(ChartXYToTimePrice(0,x,y,window,dt,price))
         //--- сделаем обратное преобразование: (X,Y) => (Time,Price)
         if(ChartTimePriceToXY(0,window,dt,price,x,y))
           {
            GlobalVariableSet(GetNameTF(Period())+" "+Symbol()+" ModifySL", StringToDouble(price));
           }   
         else
            Print("ChartTimePriceToXY return error code: ",GetLastError());
        }
      else
         Print("ChartXYToTimePrice return error code: ",GetLastError());
      Print("+--------------------------------------------------------------+");
    }
   if(MouseState((uint)sparam)=="UP") {GlobalVariableSet(GetNameTF(Period())+" "+Symbol()+" ModifySL", 0.0);} 
  }  
}
string MouseState(uint state) 
  { 
    string res; 
   res+=(((state& 1)== 1)?"DN":"UP");   // mouse left 
   return(res); 
  } 
 //+----------------------------------------------------------------------------+
//|  Возвращает наименование таймфрейма                                        |
//+----------------------------------------------------------------------------+
string GetNameTF(int TimeFrame) {
        switch (TimeFrame) {
                case PERIOD_M1:  return("M1");
                case PERIOD_M5:  return("M5");
                case PERIOD_M15: return("M15");
                case PERIOD_M30: return("M30");
                case PERIOD_H1:  return("H1");
                case PERIOD_H4:  return("H4");
                case PERIOD_D1:  return("Daily");
                case PERIOD_W1:  return("Weekly");
                case PERIOD_MN1: return("Monthly");
                default:                     return("UnknownPeriod");
        }
} 

Куски из советника:

double PriceModifySL   = 0.0;
int TicketModifSlOrder = 0;
int StopLevel = 0;
void OnTick()
 {
//---
StopLevel=MarketInfo(Symbol(),MODE_STOPLEVEL);
if(IsTesting()) {PriceModifySL = GlobalVariableGet(GetNameTF(Period())+" "+Symbol()+" ModifySL");}
else {PriceModifySL=0;}
if(PriceModifySL==0.0) {TicketModifSlOrder=0;}
if(IsTesting() && PriceModifySL>0.0001) {ModifYSL(PriceModifySL);}
 
//---
  }
//================================================================================================================================+
//                                                         ФУНКЦИИ                                                                |
//================================================================================================================================+
void ModifYSL(double priceModifySL=0)
 {
  double sl=0;
  if(TicketModifSlOrder==0)
    {  
     for(int i=0; i<OrdersTotal(); i++) 
      { 
       if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) 
         { 
          if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber) 
            {
             if(MathAbs(OrderStopLoss()-priceModifySL)<20*Point) 
               { 
                TicketModifSlOrder=OrderTicket(); break;
               }
            }
         }  
      }
    }
   if(TicketModifSlOrder==0)
     {
      for(int i=0; i<OrdersTotal(); i++) 
      { 
       if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) 
         { 
          if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber) 
            {
             if(MathAbs(OrderOpenPrice()-priceModifySL)<30*Point) 
               { 
                TicketModifSlOrder=OrderTicket(); break;
               }
            }
         }  
      }
     }     
   if(OrderSelect(TicketModifSlOrder, SELECT_BY_TICKET))
     {
      sl=priceModifySL;                                
      if(MathAbs(sl-Ask)>StopLevel*Point() && MathAbs(sl-Bid)>StopLevel*Point())
        { 
         ModifyOrder1(-1, sl, -1, 0);
        }           
     }
 }
//=================================================================================================================================
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 28.11.2006                                                     |
//|  Описание : Модификация одного предварительно выбранного ордера.           |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    pp - цена установки ордера                                              |
//|    sl - ценовой уровень стопа                                              |
//|    tp - ценовой уровень тейка                                              |
//|    ex - дата истечения                                                     |
//+----------------------------------------------------------------------------+
void ModifyOrder1(double pp=-1, double sl=0, double tp=0, datetime ex=0) {
  bool   fm;
  color  cl=IIFc(OrderType()==OP_BUY
              || OrderType()==OP_BUYLIMIT
              || OrderType()==OP_BUYSTOP, clModifyBuy, clModifySell);
  double op, pa, pb, os, ot;
  int    dg=MarketInfo(OrderSymbol(), MODE_DIGITS), er, it;

  if (pp<=0) pp=OrderOpenPrice();
  if (sl<0 ) sl=OrderStopLoss();
  if (tp<0 ) tp=OrderTakeProfit();
  
  pp=NormalizeDouble(pp, dg);
  sl=NormalizeDouble(sl, dg);
  tp=NormalizeDouble(tp, dg);
  op=NormalizeDouble(OrderOpenPrice() , dg);
  os=NormalizeDouble(OrderStopLoss()  , dg);
  ot=NormalizeDouble(OrderTakeProfit(), dg);

  if (pp!=op || sl!=os || tp!=ot) {
    for (it=1; it<=NumberOfTry; it++) {
      if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
      while (!IsTradeAllowed()) Sleep(5000);
      RefreshRates();
      fm=OrderModify(OrderTicket(), pp, sl, tp, ex, cl);
      if (fm) {
        PlaySound("wait.wav"); break;
      } else {
        er=GetLastError();
        PlaySound("timeout.wav");
        pa=MarketInfo(OrderSymbol(), MODE_ASK);
        pb=MarketInfo(OrderSymbol(), MODE_BID);
        Print("Error(",er,") modifying order: ",ErrorDescription(er),", try ",it);
        Print("Ask=",pa,"  Bid=",pb,"  sy=",OrderSymbol(),
              "  op="+GetNameOP(OrderType()),"  pp=",pp,"  sl=",sl,"  tp=",tp);
        Sleep(1000*10);
      }
    }
  }
}
 
khorosh:

Для ТП я пока не делал, не особенно это пока нужно.

Поэтому и появилась возможность тянуть цену открытия вверх и ставить СЛ в прибыли ;)

Спасибо за конструктив. 

 
Andrey Khatimlianskii:

Поэтому и появилась возможность тянуть цену открытия вверх и ставить СЛ в прибыли ;)

Спасибо за конструктив. 

А как это связано с тейкпрофитом?
 
khorosh:
А как это связано с тейкпрофитом?
А как будем понимать что именно модифицировать когда будет добавлено то же самое для ТП?
 

Там ещё на всякий случай надо добавить одно условие в функции ModifYSL(double priceModifySL=0). Как говорится кашу маслом не испортишь.)

...
if(TicketModifSlOrder>0) // Вот это!!!
  {
   if(OrderSelect(TicketModifSlOrder, SELECT_BY_TICKET))
     {
      sl=priceModifySL;                                
      if(MathAbs(sl-Ask)>StopLevel*Point() && MathAbs(sl-Bid)>StopLevel*Point())
        { 
         ModifyOrder1(-1, sl, -1, 0);
        }           
     }
  }


 

 
khorosh:
Нужно ввести ещё одну глобальную переменную для модификации ТР. Я же не зря назвал глобальную переменную "ModifySL" . А будет ещё GV  "ModifyTP".
Да это понятно. Имеется в виду вот что: если у ордера нет стопа, то можно потащить линию самого ордера, и стоп будет выставлен туда, куда "притащим" линию. Это в случае, если нет обработки тейка. А если есть обработка и стопов, и тейков, но у ордера нет ни того, ни другого, то если потянуть линию ордера, то что устанавливать? Тейк или стоп?
 
Artyom Trishkin:
Да это понятно. Имеется в виду вот что: если у ордера нет стопа, то можно потащить линию самого ордера, и стоп будет выставлен туда, куда "притащим" линию. Это в случае, если нет обработки тейка. А если есть обработка и стопов, и тейков, но у ордера нет ни того, ни другого, то если потянуть линию ордера, то что устанавливать? Тейк или стоп?
Понял. Тогда либо делать дополнительно кнопки для задания вида модификации, либо сделать так как это делается на реальном графике. Первоначальным направлением движения от цены ордера определять, что должны вытащить ТП или SL. Как то не подумал об этом, поскольку для меня это второстепенное дело, ввиду того в моём советнике для ручного тестирования стратегий при установке ордера SL и TP устанавливаются сразу. Правильно подметили. Спасибо, буду иметь ввиду.
 
khorosh:
Понял. Тогда либо делать дополнительно кнопки для задания вида модификации, либо сделать так как это делается на реальном графике. Первоначальным направлением движения от цены ордера определять, что должны вытащить ТП или SL.
А можно совместить с кнопками клавиатуры ;)
Причина обращения: