Cualquier pregunta de novato, para no saturar el foro. Profesionales, no pasen de largo. En ninguna parte sin ti - 6. - página 103

 
hoz:

Si son las 7.43 y no me he acostado... ¡Así que supongo que se escribe grial!

No, no hace falta insultar así :)) Yusuf me dio el Grial. Estoy sentado en mis maletas, esperando el maná del cielo, me voy a las Maldivas :))

 
artmedia70:
Así que muéstrame lo que has hecho... Aquí no hay telépatas, están de vacaciones.

extern string time1 = "n";// 
extern string time2="m";
extern double lot=0.2;// объявили лот
extern int slippage=2;// объявили макс отклонение от цены





int start()
{
double max;// максимальная цена 6-ти свечей
double min;// минимальная цена 6-ти свечей
int hour1 = TimeHour(StrToTime(time1)); // время часы
int minute1 = TimeMinute(StrToTime(time1));// время минуты


if (hour1 == TimeHour(TimeCurrent()) && minute1 == TimeMinute(TimeCurrent()))// если время подошло то
{
min=Low[iLowest(Symbol(),0,MODE_LOW,6,1)]; // вычисляем минимальную цену последних 6 свечей
max=High[iHighest(Symbol(),0,MODE_HIGH,6,1)]; // вычисляем максимальную цену последних 6 свечей
double volum=max-min;// общий объем локалки последних 6 свечей М5
 int ticket1=-1;
 int ticket2=-1;
if ((volum<=0.0018)==true)// если объем свечей меньше или равно z пунктов 

if (ticket1<0)
{ 
OrderSend ( Symbol (), OP_BUYSTOP, lot,max+Point,3,min-Point,max+0.0022, NULL,0,time2, Red);
Alert(GetLastError());
}
if(ticket2<0)
{
OrderSend( Symbol (), OP_SELLSTOP, lot,min-Point,3,max+Point,min-0.0022, NULL,0,time2, Yellow);
Alert(GetLastError());
}


return;


if (OrderSelect(1,SELECT_BY_POS,MODE_HISTORY)) ///если первый открытый ордер закрылся с профитом 
if(OrderProfit()>0)
{
OrderDelete(OrderTicket());// удаляем второй отложенный
}

}



bool closeorder;//определим переменную закрытия ордеров
closeorder=true;

if (closeorder==true)// вечернее закрытие всех отложенных ордеров, и рыночных позиций
{
int hour2 = TimeHour(StrToTime(time2));// вычисляем время закрытия ордеров
int minute2 = TimeMinute(StrToTime(time2));

if (hour2 == TimeHour(TimeCurrent()) && minute2 == TimeMinute(TimeCurrent()))// если время ***
{// определяем количество открытых позиций, и отложенных ордеров
for(int i=OrdersTotal()-1; i>=0; i--)
 if (OrderSelect(1,SELECT_BY_POS,MODE_TRADES))break; //определяем место где будем искать ( рабочие позиции)
if (OrderType()==OP_BUY ) OrderClose (OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),slippage);// Закрытие ордера бай если такой есть
if (OrderType()==OP_SELL) OrderClose (OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),slippage);//Закрытие ордера селл если такой есть
if (OrderType()==OP_BUYSTOP)
{ 
OrderDelete(OrderTicket()); //удаляем отложенный байстоп
}                    
if(OrderType()==OP_SELLSTOP)
{ 
OrderDelete(OrderTicket()); //удаляем отложенный sellstop
}                    

He subido el código general del Asesor Experto, para que quede más claro lo que debe hacer... Sé que es un lío, pero aún no he aprendido otra cosa =)))
Te diré una vez más dónde está la estupidez
abrir órdenes pendientes: abre una orden pendiente sin la contraria o un montón de órdenes pendientes en una dirección.
Elimina los pedidos: a veces bien por la noche a una hora claramente especificada, y a veces en un día, o no cierra en absoluto ...

Bueno, la condición es :
Si la primera orden pendiente abierta se cierra con beneficio, la segunda se elimina inmediatamente - dudo que lo haya escrito correctamente, pero no puedo comprobarlo en acción ya que no quiero abrir dos posiciones opuestas=(((((
 
artmedia70:
Cuando se busca la última orden cerrada, se debe encontrar primero la más reciente cerrada, pero se debe sacar del bucle la comprobación del cierre en la toma, de lo contrario se comprobará el cierre en la toma para cada orden cerrada y, si es así, se recordará la hora de la primera orden cerrada en la toma en el bucle y no la última.


Bueno, esto es la optimización del código. El resultado no cambiará, tal y como yo lo veo. Simplemente se tarda más en calcular. He arreglado el código, pero sigue igual.

//+-------------------------------------------------------------------------------------+
//| Получаем состояние последней позиции (Открыта или закрыта)                          |
//+-------------------------------------------------------------------------------------+
datetime GetLastOrderState()
{
   datetime lastOrderCloseTime = -1,               // Время закрытия последнего открытого ордера
            lastOOTMarket = -1,          // Время открытия последнего открытого ордера рыночного
            lastOOTHist = -1;            // Время открытия последнего открытого ордера из истории
   
   for (int i=OrdersHistoryTotal()-1; i>=0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
      if (OrderType() > 1) continue;               // Все удалённые отложки нас не интересуют..
  
      if (lastOrderCloseTime < OrderCloseTime())   // Находим время закрытия..
          lastOrderCloseTime = OrderCloseTime();   // ..последней закрытой позиции в истории
      Comment("Время закрытия последнего ордера в истории lastOrderCloseTime = ", lastOrderCloseTime);
   }

   if (MathAbs(OrderTakeProfit() - OrderOpenPrice()) < i_tp * pt) return(0);
      Comment("OrderTakeProfit() - OrderOpenPrice() < i_tp * pt = ", MathAbs(OrderTakeProfit() - OrderOpenPrice()) < i_tp * pt);
   lastOOTHist = OrderOpenTime();   // Тогда время открытия последней закрытой позиции из истории
      Comment("Время закрытия последнего ордера в истории lastOOTHist = ", lastOOTHist);
   
      Comment("Время открытия последнего открытого ордера = ", lastOOTHist);
  
   for (int h=OrdersTotal()-1; i>=0; i--)
   {   
      if (!OrderSelect(h, SELECT_BY_POS, MODE_TRADES)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
      {
         if (lastOOTMarket < OrderOpenTime())
             lastOOTMarket = OrderOpenTime();
  
         if (lastOOTMarket < lastOOTHist)      // Если время открытия последнего открытого ордера (рыночного) ниже последнего открытого ордера из истории..
             lastOrderCloseTime = OrderCloseTime(); // Значит это искомый ордер
      }
   }

   Comment("Время закрытия последнего открытого ордера = ", lastOrderCloseTime);
   return (lastOrderCloseTime);
}

Aun así, hay algo que no funciona.

 
ex1m:

He intentado mostrarte el código de un EA, sé que es un lío, pero nunca he aprendido a hacerlo de otra manera)))
Le diré una vez más dónde está la estupidez
Apertura de órdenes pendientes: abre una orden pendiente sin la contraria o un montón de órdenes pendientes en una dirección.
Borrado de pedidos: los borra cada vez, a veces bien por la noche a una hora claramente especificada, y a veces en un día, o no los cierra...

Pues bien, la condición:
Si la primera orden pendiente abierta cierra con beneficio, la segunda se borrará inmediatamente - también dudo que lo haya escrito correctamente, pero no puedo comprobarlo en el trabajo, porque no quiero abrir dos posiciones opuestas=(((((



Responder a una pregunta con una pregunta. ¿Qué demonios es eso?

if ((volum<=0.0018)==true)// если объем свечей меньше или равно z пунктов 

Descifra para mí, no entiendo :)

Las comprobaciones para abrir una posición deben realizarse después de intentar abrir una posición. Es decir

if (ticket1<0)

Se coloca después de enviar un pedido.

El precio tiene que ser mayor o menor que el Asc o el Bid para abrir la posición. Así es para el Buy:

 if (OOP > Ask)
 
hoz:


Bueno, esto es la optimización del código. El resultado no cambiará, tal y como yo lo veo. Simplemente se tarda más en calcular. He arreglado el código, pero sigue igual.

Todavía hay algo que no funciona.

No, no es una optimización del código. Sólo busca exactamente la última. Una vez que hayamos completado la búsqueda de todas las órdenes cerradas y hayamos encontrado la última orden cerrada de ellas, sólo entonces debemos comprobar si se cierra por la toma y, si se cierra por la toma, sólo entonces tiene sentido seguir buscando el resto.

Si comprobamos que hay uno cerrado dentro del bucle, ¿qué obtendremos? Obtendremos un error de lógica:
. Supongamos que hemos elegido una orden que se cerró hace un año. Su tiempo será de todas formas mayor que -1, por lo que lo comprobamos para cerrarlo en la toma (se comprueba dentro del bucle). Sí, se cerró en la toma... ¿Qué hace su función a continuación? Correcto - sigue funcionando con esa orden cerrada en la marca hace un año. Déjame ver qué más está mal. Acabo de llegar a casa...

 

Estaba escrito: 2. Si la última posición abierta se cierra en la toma, entonces cierra todo.

Entonces, es así:

//-----------------------------------------------------------------------------------------------+
bool isCloseByTakeLastOpenPos (string sy, int mn, int delta) {
   datetime t=0;
   int   i, k, j=-1;
   
// Сначала определим, что последняя закрытая позиция была закрыта по тейку (в пределах дельты)
   k=OrdersHistoryTotal()-1;
   for(i=k; i>=0; i--) {
      if (OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) {
         if (OrderMagicNumber()!=mn)   continue;
         if (OrderSymbol()!=sy)        continue;
         if (OrderType()>1)            continue;            // Сначала забыл вписать, подправил
         if (t<OrderCloseTime()) {t=OrderCloseTime(); j=i;}
         }
      }  
   // Нашли последнюю. Проверим её закрытие по тейку
   if (OrderSelect(j,SELECT_BY_POS,MODE_HISTORY)) {                      
      if (OrderProfit()+OrderSwap()+OrderCommission()<=0)   return(false);          // Закрыта с убытком или в ноль
      if (MathAbs(OrderTakeProfit()-OrderClosePrice())>delta*Point) return(false);  // закрыта в профите, но не в пределах дельты
      else t=OrderOpenTime();    // Если последняя закрытая была закрыта по тейку (в пределах дельты), запомним время её открытия
      }
   else {Print("FUNC isCloseByTakeLastOpenPos : не удалось выбрать ордер в истории");return(false);}
// Здесь мы имеем последнюю закрытую позицию в профите и закрытую по тейку (в пределах дельты), ищем дальше
   k=OrdersTotal()-1;
   for(i=k; i>=0; i--) {
      if (OrderSelect(i,SELECT_BY_POS)) {
         if (OrderMagicNumber()!=mn)   continue;
         if (OrderSymbol()!=sy)        continue;
         if (OrderType()>1)            continue;
         if (t<OrderOpenTime()) return(false);  // Выбранная рыночная позиция открыта позже закрытой по тейку
         }
      else {Print("FUNC isCloseByTakeLastOpenPos : не удалось выбрать рыночный ордер");return(false);}
      }
   return(true);  // Найденная закрытая по тейку позиция была открыта позже всех, возвращаем её время открытия
}
//-----------------------------------------------------------------------------------------------+

Pasamos a la función el símbolo que queremos comprobar, el número mágico y el delta (distancia en pips == diferencia entre la toma de la orden y el precio de cierre), así:

   if (isCloseByTakeLastOpenPos (Symbol(), Magic, 5)) { // Если последняя открытая была закрыта по тейку ...
      // ... тут обрабатываем эту ситуёвину
      }
   else {   // Иначе ...
      // тут обрабатываем, если последняя закрытая была открыта не последней или ...
      // ... последняя закрытая была закрыта с убытком или в профите, но за пределами дельты
      }

No he comprobado esta función, la escribí por mi cuenta. Por lo tanto, le dejaré que busque los errores.

Se puede hacer int y utilizar códigos de retorno. Por ejemplo, si la posición buscada no existe o existe, pero se cierra con pérdidas, devuelve -1;
si existe y se cierra con ganancias, pero no dentro de la delta, devuelve 0;
si existe y se cierra con ganancias y en Take (dentro de la delta), devuelve 1...

El margen de imaginación es enorme...

 
artmedia70:

Si, por el contrario, comprobamos el cierre de la toma, ¿qué obtenemos? Obtendremos un error lógico:

Supongamos que hemos seleccionado un pedido que se cerró hace un año. Su tiempo será de todos modos superior a -1, por lo que lo comprobamos para cerrarlo en la toma (esta comprobación dentro del bucle se incluye al código). Sí, se cerró en la toma...


Así, si hacemos un bucle en todos los pedidos, el bucle recorrerá igualmente todos los pedidos. La hora de cierre de cada pedido se comparará con la seleccionada anteriormente. Pero aquí es donde nos encontramos con un problema de rendimiento. El TakeProfit se comprobará constantemente en el bucle, con cada posición cerrada, en lugar de sólo con la última. ¿No es así?
 
PapaYozh:

Sí.

Pero existe Open[], con un precio de apertura.


Lo tengo, gracias :)
 
hoz:

Por lo tanto, si usted recorre todos los pedidos, el ciclo recorrerá en todo caso todos los pedidos. La hora de cierre de cada orden se comparará con la anterior seleccionada. Pero aquí es donde nos encontramos con un problema de rendimiento. El TakeProfit se comprobará constantemente en el bucle, con cada posición cerrada, en lugar de sólo con la última. ¿No es así?
Ya he escrito un ejemplo de la función.
 
hoz:

Por lo tanto, si se realiza un ciclo a través de todos los pedidos, el ciclo se realizará igualmente a través de todos los pedidos. La hora de cierre de cada orden se comparará con la anterior seleccionada. Pero aquí tenemos un problema de rendimiento. El TakeProfit se comprobará constantemente en el bucle, con cada posición cerrada, en lugar de sólo con la última. ¿No es así?

Eso es un fallo:

   for (int i=OrdersHistoryTotal()-1; i>=0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
      if (OrderType() > 1) continue;               // Все удалённые отложки нас не интересуют.. 
  
      if (lastOrderCloseTime < OrderCloseTime())   // Находим время закрытия..
          lastOrderCloseTime = OrderCloseTime();   // ..последней закрытой позиции в истории
      
      if (MathAbs(OrderTakeProfit() - OrderOpenPrice()) < i_tp * pt) return(0); // ЗДЕСЬ ВЫХОДИМ ПРИ ПЕРВОМ ВСТРЕЧНОМ
      
      lastOOTHist = OrderOpenTime();   // Тогда время открытия последней закрытой позиции из истории
   }
Razón de la queja: