Как эксперту открывать ордер в любой момент времени

 

Здраствуйте. Прошу помочь.

Хочу продавать когда цена коснется верхней полосы Боллинджера и закривать на средней полосе и покупать когда цена коснется нижней полосы и закривать на средней. Для етого прописал:

double LB, UB, ma;

double Price= iClose(NULL, 0, 0);


LB = iBands(NULL, PERIOD_M15, Bands_period, Bands_deviation, 0, PRICE_CLOSE, MODE_LOWER, 0);

UB = iBands(NULL, PERIOD_M15, Bands_period, Bands_deviation, 0, PRICE_CLOSE, MODE_UPPER, 0);

ma = iMA(NULL, PERIOD_M15, 20, 0, 0, PRICE_CLOSE, 0);

 

if(OrderType()==OP_BUY)   

           {

               if (Price>= ma)

               {

               Ticket=OrderClose(OrderTicket(),OrderLots(),Bid,50,Violet);

               return(0);

               }

if(total==0) 

     {

      if(Price <= LB)

        {

        Ticket=OrderSend(Symbol(), OP_BUY,Lots,Ask,50,0,"Длинная позиция",16384,0,Red);

        return(0);

        }

     

Почему при тестировании не открывает и не закрывает в местах где жолтые стрелки на рисунке:

 
Рисунок
Файлы:
55e8suqbpa.png  12 kb
 

Возможно, Вы работаете на таймфрейме отличном от PERIOD_M15, а линии индикатора на PERIOD_M15 находятся как раз в том месте, где открываются/закрываются сделки.

Возможно, Ваш советник работает только при открытии новой свечи (бара). Где цена была в момент начала свечи после события, там и открылась сделка. Полного кода нет, поэтому приходится гадать. По картинке похоже на это.

И ещё, если Вы описываете событие пересечения ценой линии индикатора, тогда необходимо указывать два условия: сейчас цена выше или равна, но на предыдущей свече была ниже.

Код на форуме вставляйте через кнопочку </>

 
Aleksei Stepanenko:

Возможно, Вы работаете на таймфрейме отличном от PERIOD_M15, а линии индикатора на PERIOD_M15 находятся как раз в том месте, где открываются/закрываются сделки.

Возможно, Ваш советник работает только при открытии новой свечи (бара). Где цена была в момент начала свечи после события, там и открылась сделка. Полного кода нет, поэтому приходится гадать. По картинке похоже на это.

И ещё, если Вы описываете событие пересечения ценой линии индикатора, тогда необходимо указывать два условия: сейчас цена выше или равна, но на предыдущей свече была ниже.

Код на форуме вставляйте через кнопочку </>

Спасибо за ответ! Тестирование на таймфрейме М15 проводил. Думаю второе предположение верно. Только я незнаю как сделать чтоб советник работал не на открытии нового бара а на текущем.
extern double StopLoss   =0;
extern double TakeProfit =0;
extern double Lots       =0.1;
extern double Prots      =0.0;
string Symb;

extern int    Bands_period = 20;
extern double Bands_deviation = 2;


//----------------------------------------------------------------------------------------------------------//
int start()
{

int cnt, total;
int Ticket;
double LB, UB, SBB, ma;
double Price= iClose(NULL, 0, 0);
total=OrdersTotal();

LB = iBands(NULL, PERIOD_M15, Bands_period, Bands_deviation, 0, PRICE_CLOSE, MODE_LOWER, 0);
UB = iBands(NULL, PERIOD_M15, Bands_period, Bands_deviation, 0, PRICE_CLOSE, MODE_UPPER, 0);
ma = iMA(NULL, PERIOD_M15, 20, 0, 0, PRICE_CLOSE, 0);



//-------------------------------------------Закрытие позиций------------------------------------------   
   for(cnt=0;cnt<total;cnt++)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if(OrderType()<=OP_SELL &&    
         OrderSymbol()==Symbol())  
        {
         if(OrderType()==OP_BUY)   
           {
               if (Price>= ma)
               {
               Ticket=OrderClose(OrderTicket(),OrderLots(),Bid,50,Violet);
               return(0);
               }
            }    
         if(OrderType()==OP_SELL)   
            {
               if (Price <= ma) 
               {
               Ticket=OrderClose(OrderTicket(),OrderLots(),Ask,50,Violet);
               return(0);
               }
            }
         }
                    
      }
//-----------------------------------------------Конец закрытия позиции------------------------------------
   if(total==0) // если нет позиций
     {
      // открытие длинной позиции
      if(Price <= LB)
        {
        Ticket=OrderSend(Symbol(), OP_BUY,Lots,Ask,50,0,"Длинная позиция",16384,0,Red);
        return(0);
        }
      
      // открытие короткой позиции
      if(Price >= UB)
        {
         Ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,50,0,"Короткая позиция",16384,0,Red);
         return(0);
        }
     }
return(0);
}
Вот весь код
 

Причесал Ваш код, но не проверял. Попробуйте.

#property version   "1.00"
#property strict

input int    Bands_period = 20;
input double Bands_deviation = 2;

input int StopLoss   =0;
input int TakeProfit =0;
input double Lots       =0.1;
input int Magic=16384;

//символ и таймфрейм текущего графика
string symbol;
ENUM_TIMEFRAMES frame;
int digits;
double point;
double loss, profit;

double Price;
double LB, UB, ma;
double LB1, UB1, ma1;

int total, result, ticket;

int OnInit()
   {
   symbol=Symbol();
   frame=(ENUM_TIMEFRAMES)Period();
   digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
   point=SymbolInfoDouble(symbol,SYMBOL_POINT);
   return(INIT_SUCCEEDED);
   }

void OnTick()
   {
   Price= iClose(symbol,frame,0);
   LB = iBands(symbol,frame, Bands_period, Bands_deviation, 0, PRICE_CLOSE, MODE_LOWER, 0);
   UB = iBands(symbol,frame, Bands_period, Bands_deviation, 0, PRICE_CLOSE, MODE_UPPER, 0);
   ma = iMA(symbol,frame, 20, 0, 0, PRICE_CLOSE, 0);
   LB1 = iBands(symbol,frame, Bands_period, Bands_deviation, 0, PRICE_CLOSE, MODE_LOWER, 1);
   UB1 = iBands(symbol,frame, Bands_period, Bands_deviation, 0, PRICE_CLOSE, MODE_UPPER, 1);
   ma1 = iMA(symbol,frame, 20, 0, 0, PRICE_CLOSE, 1);
   
//-------------------------------------------Закрытие позиций------------------------------------------   
   total=OrdersTotal();
   for(int cnt=total-1; cnt>=0; cnt--)
      {
      if(OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES) && OrderType()<=OP_SELL && OrderSymbol()==symbol && OrderMagicNumber()==Magic)
         {
         if(OrderType()==OP_BUY && Price>=ma && Price<ma1)   
            {
            result=OrderClose(OrderTicket(),OrderLots(),Bid,50,clrViolet);
            }    
         if(OrderType()==OP_SELL && Price<=ma && Price>ma1)   
            {
            result=OrderClose(OrderTicket(),OrderLots(),Ask,50,clrViolet);
            }
         }
      }
//-----------------------------------------------Открытие позиции------------------------------------
   if(total==0) // если нет позиций
      {
      // открытие длинной позиции
      if(Price<=LB && Price>LB1)
        {
        loss=StopLoss!=0?NormalizeDouble(Ask-StopLoss*point,digits):0;
        profit=TakeProfit!=0?NormalizeDouble(Ask+point*TakeProfit,digits):0;
        ticket=OrderSend(symbol,OP_BUY,Lots,NormalizeDouble(Ask,digits),50,loss,profit,"Длинная позиция",Magic,0,clrRed);
        }
      // открытие короткой позиции
      if(Price>=UB && Price<UB1)
         {
         loss=StopLoss!=0?NormalizeDouble(Bid+StopLoss*point,digits):0;
         profit=TakeProfit!=0?NormalizeDouble(Bid-point*TakeProfit,digits):0;
         ticket=OrderSend(symbol,OP_SELL,Lots,NormalizeDouble(Bid,digits),50,loss,profit,"Короткая позиция",Magic,0,clrRed);
         }
      }
   }
 

В вашем коде нет ограничений по открытию сделок в начале бара. Скорее всего Вы используете модель "По ценам открытия".

Поставьте все тики или хотя бы контрольные точки.


 
Aleksei Stepanenko:

Причесал Ваш код, но не проверял. Попробуйте.

Алексей спасибо за помощь. Код компилируется но на тестере: USDCAD,M15: OrderSend error 130. Я так понимаю что это ошибка если стоп лосс слишком близко но у нас нет СЛ и ТП.

 
Aleksei Stepanenko:

Причесал Ваш код, но не проверял. Попробуйте.

Может это ошибка но как цена может быть ниже нижней ленты Боллинджера на текущем баре и выше нижней ленты на предидущем, если цена пробила лаенту она оказалась ниже всех лент.


Файлы:
 
Юра Юра:
 OrderSend error 130
  

Проверил, у меня нет. Попробуйте может всё в скобки взять:

loss=(StopLoss!=0)?(NormalizeDouble(Ask-StopLoss*point,digits)):0;

Или поставьте loss=0; Поищите ошибку самостоятельно. Пробуйте по-разному, так-сяк и делайте выводы.

Сделайте принт, посмотрите, что пишет.

printf("loss= "+loss);
 
Юра Юра:

Может это ошибка но как цена может быть ниже нижней ленты Боллинджера на текущем баре и выше нижней ленты на предидущем, если цена пробила лаенту она оказалась ниже всех лент.

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

Это условие нужно для того, что когда вы поставите стоп, и ордер будет закрываться по стопу, и если цена ещё останется ниже линии индикатора, то откроется новый ордер, хотя нового пересечения не было.
 
Aleksei Stepanenko:

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

Это условие нужно для того, что когда вы поставите стоп, и ордер будет закрываться по стопу, и если цена ещё останется ниже линии индикатора, то откроется новый ордер, хотя нового пересечения не было.

Дай Вам Бог здоров'я!))