Скачать MetaTrader 5

Помогите найти ошибку в коде

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Pavel Pavlov
286
Pavel Pavlov  

Есть код советника, который торгует на основе Awesome Oscillator... но, никак не могу настроить количество цифр в знаках валют.

Если пятизначное число в символе, то скрипт выставляет стоплосс и тейкпрофик не от последних знаков, а с самого начала, к примеру:

Пара EurUsd=1.4187, то скрипт выставит тейкпрофик 71.4187

Чего уже только не перепробывал, не могу найти ошибку:


extern int TakeProfit= 70, StopLoss= 70;
extern double Lots= 0.01;


extern int MagicNumber=21212121;
datetime NextProcessTime;

int STOP_LEVEL, AttemptCount= 10, AttemptDelay= 1000;

double DM;
/*============================================================

==============================================================*/
int init()  {

 if (Digits==4 || Digits==5) 
        DM=100;
 else
        DM=10;

 StopLoss=DM*StopLoss;
 TakeProfit=DM*TakeProfit;
 STOP_LEVEL= MarketInfo(Symbol(), MODE_STOPLEVEL);
 NextProcessTime= 0;
}
/*============================================================

==============================================================*/
int start() {
 double AO1, AO2; bool OK, Buy, Sell;

 if (TimeCurrent()< NextProcessTime) return;
 OK= true;
 //----------------------------------------------------------
   
 AO1= iAO( Symbol(), Period(), 1);
 AO2= iAO( Symbol(), Period(), 2);
   
 Buy=  AO1> 0 && AO2<= 0;
 Sell= AO1< 0 && AO2>= 0;

 //----------------------------------------------------------
 if (Buy) OK= CloseAll(OP_SELL);
 if (Sell)OK= CloseAll(OP_BUY);

 if (NoOpenOrders()) {
        if (Buy)
        OK= SendOrder(OP_BUY);
            
    if (Sell)
        OK= SendOrder(OP_SELL);            
 }

 if (OK)
        NextProcessTime= Time[0]+ 60* Period(); // when current period will elapse
 else
        NextProcessTime= 0; // there was an error during sending an order, repeat cycle
}
/*============================================================

==============================================================*/
bool SendOrder(int dir)  {

 double sl, tp;

 if (StopLoss!= 0) 
        sl= StopLoss* Point; 
 else
        sl= 0; 

 if (TakeProfit!= 0)
        tp= TakeProfit* Point; 
  else
        tp= 0; 

 return(OpenOrder(dir, sl, tp, ""));

}
/*============================================================

==============================================================*/
bool OpenOrder(int cmd, double volume, double stop, double take)  {
 int i, j, ticket, t=0; double prc, sl, tp, lots; string cmt; color clr;

 lots = CheckLots(Lots);
    
 for (i= 0; i< AttemptCount; i++) {
        for (j= 0; (j< 50) && IsTradeContextBusy(); j++) Sleep(100);
      RefreshRates();

        if (cmd== OP_BUY) {
            prc = Ask;
            sl = stop;
            tp = take;
         clr = Blue;
        }
        if (cmd== OP_SELL) {
            prc = Bid;
            sl = stop;
            tp = take;
         clr = Red;
        }

        cmt = "";
        if (t > 0)
            cmt= t;

        ticket= OrderSend(Symbol(), cmd, lots, prc, 3, 0, 0, cmt, MagicNumber,0,clr);
        if (ticket != -1 && ( sl > 0 || tp > 0) ) {
            
            OrderSelect( ticket, SELECT_BY_TICKET, MODE_TRADES);

            for (i=0; i< AttemptCount; i++) {
                for (j=0; (j<50) && IsTradeContextBusy(); j++)
                    Sleep(100);
                RefreshRates();

                if( cmd== OP_BUY ) {

                if( tp != 0 ) 
                  tp= CheckTakeProfit(cmd, OrderOpenPrice(), take);
                       else 
                         tp= 0;
        
                    if( sl != 0 ) 
                      sl= CheckStopLoss(cmd, OrderOpenPrice(), stop);
                       else 
                         sl = 0;

                  if ( OrderModify(ticket, 0, sl, tp, 0) ) {
                      break;
                  }
                }
                
                if (cmd== OP_SELL ) {
                  if( tp != 0 ) 
                   tp = CheckTakeProfit(cmd, OrderOpenPrice(), take);
                  else 
                     tp = 0;
        
                       if (sl!= 0 ) 
                      sl= CheckStopLoss(cmd, OrderOpenPrice(), stop);
                       else 
                         sl= 0;

                  if ( OrderModify(ticket, 0, sl,tp, 0) ) {
                      break;
                  }                
                }

                Print("OpenTrade: error \'"+ErrorDescription(GetLastError())+"\' when setting SL/TP");
                Sleep(AttemptDelay);
            }

            return (true);
        }
        else { 
        
         if( ticket > 0 ) {
            return( true );
         }
        }
        Print("OpenOrder: error "+ ErrorDescription(GetLastError()));
        Sleep(AttemptDelay);
 } //for (i= 0; i< AttemptCount

 Print("OpenOrder failed after "+ AttemptCount+ " attempts");
 return (false);
}
/*============================================================

==============================================================*/
double CheckTakeProfit(int dir, double openPrc, double take) {
 double tp = 0; string Msg= "Take profit is too close to market price. Corrected to acceptable value";
   
 RefreshRates();
 if (dir == OP_BUY)  {
        tp= openPrc+ take;
    
   if (tp- Bid< STOP_LEVEL* Point) {
        tp = Bid + STOP_LEVEL* Point;   
                Print(Msg);
   }
 } else if (dir == OP_SELL)  {
        tp = openPrc - take;
      
      
   if (Ask- tp< STOP_LEVEL* Point) {
        tp = Ask - STOP_LEVEL* Point;
      Print(Msg);
        }
 }
 return(tp);
}
/*============================================================

==============================================================*/
double CheckStopLoss(int dir, double openPrc, double stop) {
 double sl = 0;  string Msg= "Stop loss is too close to market price. Corrected to acceptable value";

 RefreshRates();

 if (dir == OP_BUY)  {

        sl = openPrc - stop;
   if (Bid- sl< STOP_LEVEL*Point) {
       sl= Bid - STOP_LEVEL*Point;
                 Print(Msg);
   }
 } else if (dir == OP_SELL) {

   sl = openPrc + stop;     
   if (sl- Ask< STOP_LEVEL*Point) {
                sl= Ask + STOP_LEVEL* Point;
      Print(Msg);
        }
 }
   
 return(sl);
}
/*============================================================

==============================================================*/
double CheckLots(double lots) {

 double lot, lotmin, lotmax, lotstep, margin;
    
 lotmin= MarketInfo(Symbol(), MODE_MINLOT);
 lotmax= MarketInfo(Symbol(), MODE_MAXLOT);
 lotstep= MarketInfo(Symbol(), MODE_LOTSTEP);
 margin= MarketInfo(Symbol(), MODE_MARGINREQUIRED);

 if (lots*margin> AccountFreeMargin()) lots= AccountFreeMargin()/ margin;

 lot = MathFloor(lots/lotstep + 0.5) * lotstep;

 if (lot< lotmin) lot = lotmin;
 if (lot> lotmax) lot = lotmax;

 return (lot);
}
/*============================================================

==============================================================*/
bool NoOpenOrders(){
 int total = OrdersTotal();
  
 for(int i= 0; i < total; i++) {
        OrderSelect(i, SELECT_BY_POS,MODE_TRADES);
   if (OrderMagicNumber()== MagicNumber && OrderSymbol()== Symbol())
        return (false); 
 }
 return (true);
}
/*============================================================

==============================================================*/
bool CloseOrder(int ticket, int dir, double volume, color clr, int t = 0)  {
 int i, j, cmd; double prc, sl, tp, lots;  string cmt;

 for (i= 0; i< AttemptCount; i++) {

        for (j=0; (j< 50) && IsTradeContextBusy(); j++)  Sleep(100);
   RefreshRates();

        if (dir == OP_BUY) 
                prc = Bid;
        else if (dir == OP_SELL)   
                prc = Ask;
      
        bool OK= OrderClose(ticket,volume,prc, 3, clr);
        if (OK) 
                return (true);
   else {
                Print( "CloseOrder error "+ ErrorDescription(GetLastError()) );
      Sleep(AttemptDelay);
   }
 }

 Print("Unable to close order after "+ AttemptCount+ " attempts");
 return (false);
}
/*============================================================

==============================================================*/
bool CloseAll(int typ) {
 bool OK= true;
 for (int i = OrdersTotal()-1; i >= 0; i--) {
   OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      
   if(OrderSymbol()== Symbol() && OrderMagicNumber() == MagicNumber) {

        if (OrderType()== OP_BUY && typ== OP_BUY)
                        OK= CloseOrder(OrderTicket(), OP_BUY, OrderLots(), Blue); 

      if (OrderType()== OP_SELL && typ== OP_SELL)
                        OK= CloseOrder( OrderTicket(), OP_SELL, OrderLots(), Red); 
        }
 }
 return(OK);
}
Alexander
2441
Alexander  

Прежде всего замените

if (Digits==4 || Digits==5) 
        DM=100;
 else
        DM=10;

на

if (Digits==3 || Digits==5) 
        DM=10;
 else
        DM=1;

А вот где Вы два раза перемножаете ТР еще не нашел. А в общем код написан очень небрежно. Неправильны функции закрытия ордеров.

Нашел, замени

return(OpenOrder(dir, sl, tp, ""));

на

return(OpenOrder(dir, Lots, sl, tp));
Pavel Pavlov
286
Pavel Pavlov  
Roger:

Прежде всего замените

на

А вот где Вы два раза перемножаете ТР еще не нашел. А в общем код написан очень небрежно. Неправильны функции закрытия ордеров.

Нашел, замени

на


я учусь еще только :)
Pavel Pavlov
286
Pavel Pavlov  
160777:

я учусь еще только :)

на чужих кодах и ошибках
user999
44
user999  

Уважаемые господа. Я старый программист, видел много языков за 30 лет работы на многих программировал, но чем больше мне приходится писать программы на языке Метаквоте, тем больше возникает неудержимое желание найти того, кто сочинил этот язык, оторвать ему я... и заставить съесть. И я еле удерживаю себя от этого соблазна.

Помню несколько месяцев назад функция определяющая количество лотов в уже открытого ордера начала давать ноль. Визуально видит 5 лотов, а функция дает ноль. Оказывается, что после ошибки определения длины строки функция определения размера лота перестает работать корректно.

А вот последних 2 недели я обнаружил еще один глюк Мететрейдера 4-го. Он оказывается обладает свойством САМОПРОИЗВОЛЬНОГО ЗАКРЫТИЯ ОРДЕРОВ. Писец. Зверь такой...

Вот представтье, что есть некий эксперт, который абсолютно корректно работает. Ни ошибки ни проблем. И ордеров сам тоже не закрывает. Прекрасно торгует в прибыль. Грааль.

Берем второй эксперт. На 100% идертичный этому, только ордера открывает РЕВЕРСИВНО. Если первый на Бай, то второй на СЕЛЛ. На той же валютной паре.

И вот здесь-то и все начинается. Ошибок в журнале тоже нет никаких. Однако после открытия ордера он в ту же минуту начинает закрываться. То ли на одном из роботов, торгующих в Аверс, то ли тот, что торгует в реверс.

Хотя есть функция isTradeAllowed() которая должна иключать ОДНОВРЕМЕННУЮ ПОПЫТКУ РОБОТОВ использовать торговый канал.

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

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

Тогда функция закрытия ордеров прописанная в ином месте программы начала самопроизвольно активироваться и закрывать ордера.

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


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


Может разработчик прояснит эти феноменальные свойства мвоего детища.....

Комбинатор
16032
Комбинатор  
user999:

Я старый программист

Старый != хороший.

99.5% что проблема в кривизне рук.

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

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

user999
44
user999  
TheXpert:

Старый != хороший.

99.5% что проблема в кривизне рук.

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

Робот работает идеально, когда в метатрейдере один. Два одинаковых робота - не работают корректно. Ошибок тоже нет.
user999
44
user999  

Вы предлагаете публиковать код ? И что мы будем искать в идеально работающем коде ? Фантом связи с реверсивным роботом ? Проблема в Метатрейдере - там ее нужно искать. Метатрейдер инициирует функцию закрытия ордера. Любую функцию закрытия ордера в коде из тех что осталась. Удаляем блок один - с функцией закрытия ордера - эта же функция срабатывает в любом оставшемся блоке. Програмно блок с этой функцией по условию задачи нигде не запускается. Причем уделание одного из блоков приводит к инициированию этой же функции в ином месте кода где бы она не была. Ошибка перестает проявляться если удалить из программы все функции закрытия ордеров. Никаких "чудес" не происходит и ордера сами по себе не закрываются. И так работает годами.Если прграмма эксперта запускается в Метатрейдере одна - работает абсолютно корректно. Две корректно работающие пграммы вместе работают некорректно с феноменом самопроизвольно закрывающихся ордеров.

Victor Nikolaev
Модератор
14657
Victor Nikolaev  
user999:

Вы предлагаете публиковать код ? И что мы будем искать в идеально работающем коде ? Фантом связи с реверсивным роботом ? Проблема в Метатрейдере - там ее нужно искать. Метатрейдер инициирует функцию закрытия ордера. Любую функцию закрытия ордера в коде из тех что осталась. Удаляем блок один - с функцией закрытия ордера - эта же функция срабатывает в любом оставшемся блоке. Програмно блок с этой функцией по условию задачи нигде не запускается. Причем уделание одного из блоков приводит к инициированию этой же функции в ином месте кода где бы она не была. Ошибка перестает проявляться если удалить из программы все функции закрытия ордеров. Никаких "чудес" не происходит и ордера сами по себе не закрываются. И так работает годами.Если прграмма эксперта запускается в Метатрейдере одна - работает абсолютно корректно. Две корректно работающие пграммы вместе работают некорректно с феноменом самопроизвольно закрывающихся ордеров.


Идеального кода не бывает
Andrey F. Zelinsky
31774
Andrey F. Zelinsky  
user999:

Вы предлагаете публиковать код ? И что мы будем искать в идеально работающем коде ? Фантом связи с реверсивным роботом ? Проблема в Метатрейдере - там ее нужно искать. Метатрейдер инициирует функцию закрытия ордера. Любую функцию закрытия ордера в коде из тех что осталась. Удаляем блок один - с функцией закрытия ордера - эта же функция срабатывает в любом оставшемся блоке. Програмно блок с этой функцией по условию задачи нигде не запускается. Причем уделание одного из блоков приводит к инициированию этой же функции в ином месте кода где бы она не была. Ошибка перестает проявляться если удалить из программы все функции закрытия ордеров. Никаких "чудес" не происходит и ордера сами по себе не закрываются. И так работает годами.Если прграмма эксперта запускается в Метатрейдере одна - работает абсолютно корректно. Две корректно работающие пграммы вместе работают некорректно с феноменом самопроизвольно закрывающихся ордеров.

1. Если вы "старый программист" (поставил в кавычки), то должны понимать, что 1) без кода, 2) скрина с описанием, 3) файла лога вы ведёте не просто пустой разговор, пустой базар.

2. Метатрейдер не "инициирует функцию закрытия ордера", - этим занимает советник "криво" написанный или "шаловливые ручки" горе-трейдера.

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

user999
44
user999  
void CloseThisSymbolAll() {
for (int l_pos_0 = OrdersTotal() - 1; l_pos_0 >= 0; l_pos_0--) {
OrderSelect(l_pos_0, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() == Symbol()) {
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
if (OrderType() == OP_BUY)
{ 
for(xyz=1; xyz<=OrderExecuteTry; xyz++)
{ 
// check trade context avilability

while(IsTradeAllowed()==false) 
{
Sleep(1000*WaitSecondsInterval); // 
} 
err_ticket=OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, Blue);
Print("-Clozet-2-");
// block begin
if(err_ticket>0)
{
break;
}
else
{
Gle=GetLastError();
Print(">--> Ошибка закрытия ордера на покупку: ", GetLastError());
if(UseEmail == true && xyz>=OrderExecuteTry-1) SendMail("FXBASIC error notification","Error Close Buy Order: "+ DoubleToStr(Gle,0) + " Time of Error: "+TimeToStr(TimeCurrent(), TIME_DATE|TIME_SECONDS));
Sleep(1000*WaitSecondsInterval); // время ожидания до очередной попытки закрытия ордера
// check trade context avilability

while(IsTradeAllowed()==false) 
{
Sleep(1000*WaitSecondsInterval); // 
}
RefreshRates();
}

} 
} 
if (OrderType() == OP_SELL) 
{
for(xyz=1; xyz<=OrderExecuteTry; xyz++)
{ 
// check trade context avilability

while(IsTradeAllowed()==false) 
{
Sleep(1000*WaitSecondsInterval); // 
} 
err_ticket=OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, Red);
Print("-Clozet-3-");
// block begin
if(err_ticket>0)
{
break;
}
else
{
Gle=GetLastError();
Print(">--> Ошибка закрытия ордера на продажу: ", GetLastError());
if(UseEmail == true && xyz>=OrderExecuteTry-1) SendMail("FXBASIC error notification","Error Close Sell Order: "+ DoubleToStr(Gle,0) + " Time of Error: "+TimeToStr(TimeCurrent(), TIME_DATE|TIME_SECONDS));
Sleep(1000*WaitSecondsInterval); // время ожидания до очередной попытки закрытия ордера
// check trade context avilability

while(IsTradeAllowed()==false) 
{
Sleep(1000*WaitSecondsInterval); // 
}
RefreshRates();
}

} 
}
}
Sleep(1000);
}
}
}

вот Вам типичный код функции закрытия всех ордеров. Код вызывыется вручную по команде с центрального робота если необходимо закрыить все ордера. Реально блок никогда не работает сам в программе и не вызывается никакой функцией кроме ручного запуска. Именно этот блок начал самопроизвольно закрывать ордера. Я удалил этот блок вовсе. Начал закрывать ордера иной блок самопроизвольно, который также по условию програмно не вызывался. Какая из функций даного блока прописана с твкими уникальными свойствами что блок может сам инициировать закрытие ордера ? И почему он этого не делат когда робот работает в Метатрейдере один ?

123
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий