Cualquier pregunta de los recién llegados sobre MQL4 y MQL5, ayuda y discusión sobre algoritmos y códigos - página 31

 
Vitalie Postolache:
El error está en algún lugar más arriba en el código, en el área de selección de pedidos.
No toco el resto.
 
spoiltboy:
No toco el resto.
En cualquier caso, es necesario ver el código anterior y posterior, no sólo las líneas de condición.
 
Artyom Trishkin:
En cualquier caso, necesitas ver el código anterior y posterior, no sólo las líneas de condición.
extern int pointsl=100, pointtp=100, MagicB=111111, MagicS=2222, bars=10; extern double lotB=0.1, lotS=0.1;
double slB, tpB, slS, tpS; double x=0, z=0;


void OnTick()
{
double maxpr1=9999; double minpr1=9999;

for(int shift1=0; shift1<barras; shift1++)
{double i=iHigh(Symbol(), PERIOD_CURRENT, shift1);
si (i>maxpr1){maxpr1=i;}}

for(int shiftA1=0; shiftA1<barras; shiftA1++)
{double y=iLow(Symbol(), PERIOD_CURRENT, shiftA1);
si (y<minpr1) {minpr1=y;}}

if (BuyLimitCount()==0 && BuyCount()==0){
slB=NormalizarDoble(minpr1-puntosl*Punto,5);
tpB=NormalizarDoble(minpr1+puntosl*Punto,5);
int ticketUP=OrderSend(Symbol(), OP_BUYLIMIT, lotB, minpr1, 3, slB, tpB, "", MagicB, 0, Red);
if (ticketUP==-1) Print("ERROR OP_BUY"); else Print("OP_BUY OK");}

if (SellLimitCount()==0 && SellCount() ==0){
slS=NormalizarDoble(maxpr1+puntosl*Punto,5);
tpS=NormalizarDoble(maxpr1+puntosl*Punto,5);
int ticketD=OrderSend(Symbol(), OP_SELLLIMIT, lotS, maxpr1, 3, slS, tpS, "", MagicS, 0, Blue);
if (ticketD==-1) Print("ERROR OP_SELL"); else Print("OP_SELL OK");}

if (x!=maxpr1){x=maxpr1; OrderDelete(ticketD);}
if (z!=minpr1){z=minpr1; OrderDelete(ticketUP);}


double maxpr=-9999; double minpr=9999;

for(int shift=0; shift<bars; shift++)
{double e=iHigh(Symbol(), PERIOD_CURRENT, shift);
si (e>maxpr){maxpr=e;}}

for(int shiftA=0; shiftA<barras; shiftA++)
{double r=iLow(Symbol(), PERIOD_CURRENT, shiftA);
si (r<minpr) {minpr=r;}}

cadena a;
if(barras==1)a="barra:";
else a= IntegerToString(bars,1) + " bars: ";
Comment("Último ", a, "max ", DoubleToStr(maxpr, 5), ", min ", DoubleToStr(minpr, 5),";
}

int BuyLimitCount(){
int count=0;
for(int i=Total de Pedidos()-1; i>=0; i--){
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true){
if(OrderMagicNumber()==MagicB){
if(OrderType()==OP_BUYLIMIT)
count++;}}return(count);}

int BuyCount(){
int count=0;
for(int i=Total de Pedidos()-1; i>=0; i--){
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true){
if(OrderMagicNumber()==MagicB){
if(OrderType()==OP_BUY)
count++;}}}return(count);}

int CuentaLímiteDeVenta(){
int count=0;
for(int i=Total de Pedidos()-1; i>=0; i--){
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true){
if(OrderMagicNumber()==MagicS){
if(OrderType()==OP_SELLLIMIT)
count++;}}}return(count);}

int CuentaVenta(){
int count=0;
for(int i=Total de Pedidos()-1; i>=0; i--){
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==true){
if(OrderMagicNumber()==MagicS){
if(OrderType()==OP_SELL)
count++;}}}return(count);}
 
spoiltboy:
...
Y de todos modos, ¿qué intentas hacer con este, perdón, espeluznante código?
 
spoiltboy:

No puedes limpiar el código y pegarlo correctamente con el SRC, ¿verdad?

¿Por qué no aplica OrderSelect antes de intentar borrar?

 
spoiltboy:
...

No sé por qué necesitas tantos bucles ahí, cuando puedes rellenar los campos de la estructura requerida sobre el número de órdenes y posiciones en uno solo.

He eliminado cosas innecesarias y también he eliminado el borrado. No es necesario borrar por ticket (todavía hay que saberlo antes de borrar), sino en el bucle para encontrar el orden correcto por índice, y borrarlo.

Por lo tanto, necesitamos una función más para buscar y eliminar órdenes, que debe ser llamada en caso de una condición, pero qué tipo de condición - no lo entendí de inmediato al mirar a través de su código, y no tenía tiempo para mirarlo a través. Describa las condiciones necesarias con palabras y le diremos cómo eliminarlas.

Lo había escrito por mi cuenta, sin mirar, por lo que puede haber errores en la función que rellena la estructura con el número de órdenes y posiciones - no lo he comprobado.

//--- input variables
input    double   LotB=0.1;      // Лот Buy
input    double   LotS=0.1;      // Лот Sell
input    int      Pointsl=100;   // StopLoss в пунктах
input    int      Pointtp=100;   // TakeProfit в пунктах
input    int      NumBars=10;    // Количество баров для поиска Max/Min
input    int      Magic=100500;  // Magic

//--- global variables
struct DataNumOrders
  {
   int buy;          // Количество позиций Buy
   int sell;         // Количество позиций Sell
   int buy_limit;    // Количество ордеров BuyLimit
   int buy_stop;     // Количество ордеров BuyStop
   int sell_limit;   // Количество ордеров SellLimit
   int sell_stop;    // Количество ордеров SellStop
  };
DataNumOrders numOrders;   // Количество ордеров
double lotB, lotS;
int    pointsl, pointtp, numBars;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   numBars=(NumBars<1?1:NumBars>Bars?Bars:NumBars);
   pointsl=(Pointsl<0?0:Pointsl);
   pointtp=(Pointtp<0?0:Pointtp);
   double minLot=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   double maxLot=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
   lotB=(LotB<minLot?minLot:LotB>maxLot?maxLot:LotB);
   lotS=(LotS<minLot?minLot:LotS>maxLot?maxLot:LotS);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   //--- заполним структуру количеством ордеров и позиций
   GetNumOrders(Symbol(),Magic,numOrders);
  
   //--- найдём максимальную и минимальную цены за bars свечей
   double maxPrice=0.0; double minPrice=DBL_MAX;
   for(int i=0; i<numBars; i++) {
      double max_i=iHigh(Symbol(),PERIOD_CURRENT,i);
      if(max_i>maxPrice) maxPrice=max_i;
      double min_i=iLow(Symbol(),PERIOD_CURRENT,i);
      if(min_i<minPrice) minPrice=min_i;
      }

   //--- выставим BuyLimit
   if(numOrders.buy_limit==0 && numOrders.buy==0) {
      double slB=(pointsl==0?0:NormalizeDouble(minPrice-pointsl*Point(),Digits()));
      double tpB=(pointtp==0?0:NormalizeDouble(minPrice+pointtp*Point(),Digits()));
      int ticketUP=OrderSend(Symbol(), OP_BUYLIMIT, lotB, minPrice, 3, slB, tpB, "", Magic, 0, clrRed);
      if(ticketUP==-1) Print("ERROR OP_BUY");
      else Print("OP_BUY OK");
      }
   //--- выставим SellLimit
   if(numOrders.buy_limit==0 && numOrders.sell==0) {
      double slS=(pointsl==0?0:NormalizeDouble(maxPrice+pointsl*Point(),Digits()));
      double tpS=(pointtp==0?0:NormalizeDouble(maxPrice-pointtp*Point(),Digits()));
      int ticketD=OrderSend(Symbol(), OP_SELLLIMIT, lotS, maxPrice, 3, slS, tpS, "", Magic, 0, clrBlue);
      if(ticketD==-1) Print("ERROR OP_SELL");
      else Print("OP_SELL OK");
      }

   //--- Тут должно быть удаление, но не понятно при каких условиях. Опишите их
  
  
   //---
   string a=(numBars==1)?"bar: ":IntegerToString(numBars,1)+" bar's: ";
   Comment("Last ", a, "max ", DoubleToStr(maxPrice, Digits()), ", min ", DoubleToStr(minPrice, Digits()),".");
  }
//+------------------------------------------------------------------+
//| Записывает в структуру количество позиций и отложенных ордеров   |
//+------------------------------------------------------------------+
void GetNumOrders(string symbol_name, int magic_number, DataNumOrders &number_of) {
   ZeroMemory(number_of);
   for(int i=OrdersTotal()-1; i>=0; i--) {
      if(OrderSelect(i,SELECT_BY_POS)) {
         if(OrderMagicNumber()!=magic_number) continue;
         if(OrderSymbol()!=symbol_name)       continue;
         if(OrderType()==OP_BUY)       number_of.buy++;
         if(OrderType()==OP_BUYLIMIT)  number_of.buy_limit++;
         if(OrderType()==OP_BUYSTOP)   number_of.buy_stop++;
         if(OrderType()==OP_SELL)      number_of.sell++;
         if(OrderType()==OP_SELLLIMIT) number_of.sell_limit++;
         if(OrderType()==OP_SELLSTOP)  number_of.sell_stop++;
         }
      }
}
//+------------------------------------------------------------------+
 
Artyom Trishkin:
En general, ¿qué es lo que se intenta hacer con este, perdón, espeluznante código?
El EA cuenta los mínimos y máximos de las últimas X barras y coloca las órdenes en ellas. Entonces, si el máximo o el mínimo disminuye o aumenta, tenemos que borrar la orden y abrirla con los nuevos datos.


 

cómo escribir lo siguiente :

Si el precio ha variado en un 1%, por ejemplo, el día de apertura más que el día de cierre en un 1%.

 
Movlat Baghiyev:

cómo escribir lo siguiente :

Si el precio ha variado un 1%, digamos que el día de apertura es mayor que el de cierre en un 1%.

Eso es diferente, ahora está claro a qué se refiere el 1% ;)

if(Open[x] > Close[x]+Open[x]*0.01) {code}
 
spoiltboy:
El Asesor Experto cuenta los mínimos y máximos de las últimas X barras y coloca las órdenes según ellos. Además, si hay una disminución del máximo o un aumento del mínimo, hay que eliminar la orden correspondiente y abrirla con los nuevos datos.


¿Por qué borrar cuando se puede modificar el precio de consigna y el stop y takeout en relación con el nuevo nivel? Al fin y al cabo, sólo se colocan órdenes pendientes cuando no hay órdenes pendientes ni posiciones de mercado. Así que: si hay una orden pendiente en el mercado y no hay una posición de mercado correspondiente, entonces sólo tenemos que modificar los precios en la orden pendiente - el precio establecido a un nuevo nivel y su orden de parada - respectivamente al nuevo nivel.

Cada vez que necesites recordar los precios encontrados de Max y Min. Si el precio actual encontrado de Max es menor que el anterior, modificamos el BuyLimit pendiente y memorizamos el nuevo precio de Max. Por el precio de Min, espejéalo.