Arrastre y suelte SL y TP en el probador. - página 12

 
Andrey Khatimlianskii:

¿Presumir? )

O muestra el código o cierra el hilo.

El código está disperso. Una parte está en el Asesor Experto y otra en el indicador. No voy a publicar todo el Asesor Experto y el indicador. Si está interesado en una parte determinada, puedo publicarla. Por favor, hágame saber qué necesita exactamente.
 
khorosh:
El código está disperso. Una parte está en el Asesor Experto y otra en el indicador. No voy a publicar todo el Asesor Experto y el indicador. Si está interesado en una parte determinada, puedo exponerla. Por favor, indique qué necesita exactamente.

Es que no entiendo por qué necesitas mantener un hilo si tu tema ya está resuelto y los demás no sacamos nada en claro de la discusión.

Sugerencia de añadir constructiva )

 
Andrey Khatimlianskii:

Es que no entiendo por qué necesitas mantener un hilo si tu asunto ya está resuelto y los demás no sacamos nada en claro de la discusión.

Sugerido para añadir algo de constructividad )

Ok, lo tienes :) Estoy publicando todo lo relacionado con arrastrar y soltar SL. Para el TP, no lo he hecho hasta ahora, no es particularmente necesario todavía. Pero no es un problema hacerlo por analogía. Pego el indicador en su totalidad, he sacado del EA todo lo referente al arrastre del SL. No he estudiado las innovaciones del idioma, hago muchas cosas a la antigua, así que no juzgues.

Código del indicador:

//+------------------------------------------------------------------+
//|                                      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");
        }
} 

Piezas de EA:

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:

Todavía no he hecho un TP, no lo necesito particularmente todavía.

Por eso es posible tirar del precio de apertura hacia arriba y poner un SL en beneficio ;)

Gracias por los comentarios constructivos.

 
Andrey Khatimlianskii:

De ahí la oportunidad de tirar del precio de apertura hacia arriba y poner el SL en beneficios ;)

Gracias por los comentarios constructivos.

¿Qué tiene esto que ver con el lucro?
 
khorosh:
¿Qué tiene esto que ver con el lucro?
¿Y cómo entenderemos exactamente lo que hay que modificar cuando se añada lo mismo para el TP?
 

También debería añadir una condición a la función ModifYSL(double priceModifySL=0) por si acaso. Como se dice, no se puede estropear un montón de gachas con mantequilla).

...
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:
Necesitamos introducir otra variable global para modificar el TR. Llamé a la variable global"ModifySL" por una razón. Y luego está la GV "ModifyTP".
Sí, está claro. Lo que quiero decir es lo siguiente: si la orden no tiene stop, podemos arrastrar la línea de la propia orden y el stop se pondrá donde "arrastramos" la línea. Este es el caso si no tenemos el procesamiento de la comida para llevar. Y si tenemos tratamiento tanto de los stops como de los toes, pero la orden no tiene ninguno de los dos, entonces si dibujamos la línea de la orden, ¿qué debemos poner? ¿Una toma o una parada?
 
Artyom Trishkin:
Sí, ya lo veo. Lo que quiero decir es lo siguiente: si la orden no tiene stop, podemos arrastrar la línea de la propia orden, y el stop se colocará donde "arrastramos" la línea. Este es el caso si no tenemos el procesamiento de la comida para llevar. Y si tenemos tratamiento tanto de los stops como de los toes, pero la orden no tiene ninguno de los dos, entonces si dibujamos la línea de la orden, ¿qué debemos poner? ¿Una toma o una parada?
Ya veo. Entonces deberíamos añadir botones para establecer el tipo de modificación o hacerlo como lo hacemos en un gráfico real. Debemos establecer la dirección inicial del movimiento del precio de la orden para determinar lo que debe ser tomado por TP o SL. No pensé en ello al principio porque es de menor importancia para mí y en mi EA para pruebas manuales de estrategias, el SL y el TP se establecen inmediatamente al colocar las órdenes. Has hecho una buena observación. Gracias, lo tendré en cuenta.
 
khorosh:
Lo tengo. Entonces, o bien se hacen botones adicionales para establecer el tipo de modificación, o se hace como se hace en el gráfico real. La dirección inicial del movimiento del precio de la orden para determinar lo que el TP o SL debe tirar.
O podemos combinarlo con los botones del teclado ;)