エラー、バグ、質問 - ページ 958

 
antt:

異なる入力パラメータを送信する。シンボル、周期、入力パラメータは同じで、インジケータも同じです。ターミナルはリソースの消費を最小限に抑えようとするため、この場合、インジケーターの新しいコピーは作成されず、つまり、1つのmql5プログラムが実際に動作します。

この素朴な疑問にもアドバイスをお願いします。https://www.mql5.com/ru/forum/1111/page975#comment_469324 、 誰も知らないからです。)))

 

訂正のご協力をお願いします。Strategy Testerではすべて完璧に動作しますが、m1のRTSデモでは3ロットのポジションの代わりに3ロットずつの2つの注文が送信され、合計6ロットのポジションとなることがあります。

#property copyright "Copyright 2013, DKeN"
#property link      ""
#property version   "1.00"
/*
1 Название: Параболик
2 Терминал: МТ5
3​ Рабочий инструмент: любой инструмент и период
4​ Индикатор: параболик
5​ Правила:
 при пересечение входим в направлении пересечения по рынку , 
 профит делим на 3 части , при закрытие первого выставляем стоп в ноль или чуть в плюс, 
 если профит не достигнут, а цена ушла в минус переворачиваем позицию при пересечении параболика…
6​ второй вариант: при пересечение входим в направлении пересечения по рынку , профит делим на 2 части , при закрытие первой части вторую оставляем до пересечения параболика
7​ настройки: а) к-во лотов
б) индикатор
в) время работы
8. возможность работы по нескольким инструментам на одном счете

если торгуем на РТС необходимо строго со спецификацией инструмента данные задавать!

*/
input string comment="";
//комментарий к ордеру
input int    slippage=10; 
//проскальзывание
input double lot=3;
//рабочий лот позиции
input int    takeprofit=200;
//тейк профит основной позиции
input int    stoploss=1000;
//стоп лосс основной позиции
input int    mode=1;
/*режим выхода 1 или 2*/
input int    takeprofit1=100;
//точка закрытия первой части профита в пунктах
input double lot1=1;
//объем закрываемой части ордера
input double bu1=10; 
//для режима 1, пренос в безубыток +1
input int    takeprofit2=150;
//точка закрытия второй части профита в пунктах
input double lot2=1;
//объем закрываемой позиции

input ENUM_TIMEFRAMES tf=0; 
//период, 0 - по умолчанию с графика текущий
input double step=0.02;
input double maximum=0.2;
//настрйоки для сар step,maximum
input string times="00:00-24:00";
//поддерживаются интервалы через , например 00:00-12:00, 16:00-20:00 и т.д. поддержка ночного перехода например 22:00-05:00
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int psar=-1;
ulong semafor=0;

int OnInit()
  {
//---
   psar=iSAR(NULL,tf,step,maximum);
   if(psar==INVALID_HANDLE){
       PrintFormat("Не удалось создать хэндл индикатора iSAR для пары %s/%s, код ошибки %d", _Symbol, EnumToString(_Period),GetLastError());
       return (-1);
   }    
   semafor=0;
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   if(psar!=INVALID_HANDLE) IndicatorRelease(psar);
   Comment("");
   
  }
  
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
     
   bool bWork=time_check(times);
   Comment("Торговый интервал времени");
   if(!bWork)Comment("Неторговый интервал времени. Разрешено закрытие по обратному сигналу и частичное закрытие. Открытие новых сделок запрещено.");
   double sar[],dLot,open,stop,take;
   
   ENUM_POSITION_TYPE type;
   ArraySetAsSeries(sar,true);  
   string n=_Symbol;
   
   if(CopyBuffer(psar,0,0,2,sar)>=0){     
      //1 - предыдущее значение
      //0 - текущий бар
      MqlRates rates[];
      MqlTick tick;
      
      ArraySetAsSeries(rates,true);
      int op=0;
      
      if(CopyRates(NULL,tf,0,2,rates)>0){
         
         if(SymbolInfoTick(n,tick)){
            if(tick.bid<sar[1] && sar[1]<rates[0].open) op=-1;
            else if(tick.ask>sar[1] && sar[1]>rates[0].open) op=1;
         }
                 
         //првоерим если позиции в рынке нет, попробуем открыть по сигналу
         if(!PositionSelect(n)) {
            order_OrderDeleteAll(n); //удалим отложки
            
            if(op==0) return; //сигнала нет!   
            
            if(bWork){
               if(op==1) order_OrderSend(n,ORDER_TYPE_BUY,lot,0,stoploss,takeprofit,comment);
               if(op==-1) order_OrderSend(n,ORDER_TYPE_SELL,lot,0,stoploss,takeprofit,comment);
            }
            
         }else{
            type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
            dLot=PositionGetDouble(POSITION_VOLUME);
            
            if(dLot==lot){
                  int orders[];
                  int all=order_OrdersTotal(n,orders);
                  
                  open=PositionGetDouble(POSITION_PRICE_OPEN);
                  
                  if(type==POSITION_TYPE_BUY && orders[ORDER_TYPE_SELL_LIMIT]==0){
                     if(mode==2 || mode==1)order_OrderSend(n,ORDER_TYPE_SELL_LIMIT,lot1,open+takeprofit1*_Point,0,0,"");
                     if(mode==1)order_OrderSend(n,ORDER_TYPE_SELL_LIMIT,lot2,open+takeprofit2*_Point,0,0,"");
                  }
                  
                  if(type==POSITION_TYPE_SELL && orders[ORDER_TYPE_BUY_LIMIT]==0){
                     if(mode==2 || mode==1)order_OrderSend(n,ORDER_TYPE_BUY_LIMIT,lot1,open-takeprofit1*_Point,0,0,"");
                     if(mode==1)order_OrderSend(n,ORDER_TYPE_BUY_LIMIT,lot2,open-takeprofit2*_Point,0,0,"");
                  }
                  
            }else if(dLot<lot && mode==1){
               open=PositionGetDouble(POSITION_PRICE_OPEN);
               stop=PositionGetDouble(POSITION_SL);
               take=PositionGetDouble(POSITION_TP);
               
               if(type==POSITION_TYPE_BUY && (stop<open || stop==0.0)) order_OrderModify(n,open+bu1*_Point,take);
               if(type==POSITION_TYPE_SELL && (stop>open || stop==0.0)) order_OrderModify(n,open-bu1*_Point,take);
            }
            
            //Print(GetLastError()," op=",op," type=",type);           
            if(op==0) return;
            //позиция к этому моменту могла быть уже закрыта, перепроверим и проверим ее лот и тип
            if(PositionSelect(n)){
               type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
               dLot=PositionGetDouble(POSITION_VOLUME);
               //осуществим переворот, да так чтобы закрыть остаток и открыть начальным лотом
               if(type==POSITION_TYPE_BUY && op==-1) {
                  order_OrderDeleteAll(n); //удалим отложки
                  order_OrderSend(n,ORDER_TYPE_SELL,dLot,0,0,0,comment);
               }else if(type==POSITION_TYPE_SELL && op==1) {
                  order_OrderDeleteAll(n); //удалим отложки
                  order_OrderSend(n,ORDER_TYPE_BUY,dLot,0,0,0,comment);
               }
            }
            
         }
      }
     
   }
   
  }
//+------------------------------------------------------------------+
bool order_OrderModify(string name,double sl,double tp){
/* 
SL & TP Modification
Торговый приказ на модификацию уровней StopLoss и/или TakeProfit. Требуется указание 4 полей:
action 
symbol 
sl 
tp 
*/
   MqlTradeRequest  rq={0};      // структура запроса
   MqlTradeResult   rs={0};    
   
   rq.action=TRADE_ACTION_SLTP; 
   rq.symbol=name;
   rq.sl=sl;
   rq.tp=tp;
   
   return (OrderSend(rq,rs)); 
}
bool order_OrderSend(string name,ENUM_ORDER_TYPE type,double dlot,double open,double sl,double tp,string cmt){
   MqlTradeRequest  rq={0};      // структура запроса
   MqlTradeResult   rs={0};    
   MqlTick tick={0};
   MqlTradeCheckResult cr={0};    
   if(PositionSelect(name)) semafor=0;
   
   if(semafor>0) return (false);
   
   if(type==ORDER_TYPE_BUY || type==ORDER_TYPE_SELL){
      
      
         
      rq.action=TRADE_ACTION_DEAL;
      rq.symbol=name;
      rq.volume=NLot(name,dlot);
      rq.type=type;
      
      bool ntick=SymbolInfoTick(name,tick);
      
      if(open<=0){
         if(type==ORDER_TYPE_BUY) rq.price=tick.ask;
         else if(type==ORDER_TYPE_SELL) rq.price=tick.bid;
      }else{
         rq.price=open; //если цена указана явно, то откроем по цене+проскальзывание
      }
      
      rq.sl=0;
      rq.tp=0;
      //выставим стоп
      if(sl>0 && type==ORDER_TYPE_BUY) rq.sl=NormalizeDouble(rq.price-sl*_Point,_Digits);
      else if(sl>0 && type==ORDER_TYPE_SELL) rq.sl=NormalizeDouble(rq.price+sl*_Point,_Digits);
      //выставим тейк
      if(tp>0 && type==ORDER_TYPE_BUY) rq.tp=NormalizeDouble(rq.price+tp*_Point,_Digits);
      else if(tp>0 && type==ORDER_TYPE_SELL) rq.tp=NormalizeDouble(rq.price-tp*_Point,_Digits);
      
      rq.deviation=slippage;//допустимое проскальзывание
      rq.type_filling=ORDER_FILLING_FOK;
   
      rq.comment=cmt;
   }else{
      
      
      rq.action=TRADE_ACTION_PENDING;
      rq.symbol=name;
      rq.volume=NLot(name,dlot);
      rq.type=type;
      rq.deviation=slippage;//допустимое проскальзывание
      rq.type_time=ORDER_TIME_DAY;
//ORDER_TIME_GTC; //ордер будет до снятия его программно или вручную

      //bool ntick=SymbolInfoTick(name,tick);
      
      rq.price=open; 
      
      rq.sl=sl; //должна быть ценой!
      rq.tp=tp;
      rq.type_filling=ORDER_FILLING_RETURN;

      rq.comment=cmt;
   }
   
      
   if(OrderCheck(rq,cr)){
         
            if(OrderSend(rq,rs)){
               if(rs.retcode!=TRADE_RETCODE_DONE && rs.retcode!=TRADE_RETCODE_PLACED){
                  Comment("Debug: order_OrderSend(retcode=",ResultRetcodeDescription(cr.retcode),")");
               }
                  
               semafor=rs.deal;
                   
               if(rs.retcode==TRADE_RETCODE_DONE || rs.retcode==TRADE_RETCODE_PLACED){
                  
                       
                  if(type==ORDER_TYPE_BUY || type==ORDER_TYPE_SELL){
                     rq.action= TRADE_ACTION_SLTP; 
                     rq.order= rs.order;
           
                     return (OrderSend(rq,rs)); 
                  }
               }
               
               return (true);
            }
            
         
   }else{   
         semafor=0;
         Comment("Debug: order_OrderSend(retcode=",ResultRetcodeDescription(cr.retcode),")");
   }
   
   
   return (false);
   
}
/*удаляет отложки*/
bool order_OrderDeleteAll(string name){
   ulong ticket;
   MqlTradeRequest rq={0};
   MqlTradeResult rs={0};
   
   for(int i=OrdersTotal()-1;i>=0;i--){
      
      if((ticket=OrderGetTicket(i))>0){
         ZeroMemory(rq);
         ZeroMemory(rs);
         rq.action=TRADE_ACTION_REMOVE;
         rq.order=ticket;
         
         OrderSend(rq,rs);
      }
   }
   
   return (false);
}

int order_OrdersTotal(string name,int &orders[]){
   ulong ticket;
   int total=0;
   ArrayResize(orders,10,0);
   ArrayInitialize(orders,0);
//--- пройдем по всем отложенным ордерам
   for(int i=OrdersTotal()-1;i>=0;i--)
      if((ticket=OrderGetTicket(i))>0)
         if(OrderGetString(ORDER_SYMBOL)==name){
             orders[(int)OrderGetInteger(ORDER_TYPE)]++;
             total++;
         }    
//---
   return(total);
  }


//+------------------------------------------------------------------+ 
//| возврат стрингового результата торговой операции по его коду     | 
//+------------------------------------------------------------------+ 
string ResultRetcodeDescription(int retcode) 
  { 
   string str; 
//---- 
   switch(retcode) 
     { 
      case TRADE_RETCODE_REQUOTE: str="Реквота"; break; 
      case TRADE_RETCODE_REJECT: str="Запрос отвергнут"; break; 
      case TRADE_RETCODE_CANCEL: str="Запрос отменен трейдером"; break; 
      case TRADE_RETCODE_PLACED: str="Ордер размещен"; break; 
      case TRADE_RETCODE_DONE: str="Заявка выполнена"; break; 
      case TRADE_RETCODE_DONE_PARTIAL: str="Заявка выполнена частично"; break; 
      case TRADE_RETCODE_ERROR: str="Ошибка обработки запроса"; break; 
      case TRADE_RETCODE_TIMEOUT: str="Запрос отменен по истечению времени";break; 
      case TRADE_RETCODE_INVALID: str="Неправильный запрос"; break; 
      case TRADE_RETCODE_INVALID_VOLUME: str="Неправильный объем в запросе"; break; 
      case TRADE_RETCODE_INVALID_PRICE: str="Неправильная цена в запросе"; break; 
      case TRADE_RETCODE_INVALID_STOPS: str="Неправильные стопы в запросе"; break; 
      case TRADE_RETCODE_TRADE_DISABLED: str="Торговля запрещена"; break; 
      case TRADE_RETCODE_MARKET_CLOSED: str="Рынок закрыт"; break; 
      case TRADE_RETCODE_NO_MONEY: str="Нет достаточных денежных средств для выполнения запроса"; break; 
      case TRADE_RETCODE_PRICE_CHANGED: str="Цены изменились"; break; 
      case TRADE_RETCODE_PRICE_OFF: str="Отсутствуют котировки для обработки запроса"; break; 
      case TRADE_RETCODE_INVALID_EXPIRATION: str="Неверная дата истечения ордера в запросе"; break; 
      case TRADE_RETCODE_ORDER_CHANGED: str="Состояние ордера изменилось"; break; 
      case TRADE_RETCODE_TOO_MANY_REQUESTS: str="Слишком частые запросы"; break; 
      case TRADE_RETCODE_NO_CHANGES: str="В запросе нет изменений"; break; 
      case TRADE_RETCODE_SERVER_DISABLES_AT: str="Автотрейдинг запрещен сервером"; break; 
      case TRADE_RETCODE_CLIENT_DISABLES_AT: str="Автотрейдинг запрещен клиентским терминалом"; break; 
      case TRADE_RETCODE_LOCKED: str="Запрос заблокирован для обработки"; break; 
      case TRADE_RETCODE_FROZEN: str="Ордер или позиция заморожены"; break; 
      case TRADE_RETCODE_INVALID_FILL: str="Указан неподдерживаемый тип исполнения ордера по остатку "; break; 
      case TRADE_RETCODE_CONNECTION: str="Нет соединения с торговым сервером"; break; 
      case TRADE_RETCODE_ONLY_REAL: str="Операция разрешена только для реальных счетов"; break; 
      case TRADE_RETCODE_LIMIT_ORDERS: str="Достигнут лимит на количество отложенных ордеров"; break; 
      case TRADE_RETCODE_LIMIT_VOLUME: str="Достигнут лимит на объем ордеров и позиций для данного символа"; break; 
      default: str="Неизвестный результат"; 
     } 
//---- 
   return(str); 
  } 
  
  double NLot(string name,double dlot){
      double stepLot=SymbolInfoDouble(name,SYMBOL_VOLUME_STEP);
      
      return (MathFloor(dlot/stepLot)*stepLot);
  }
  
  bool time_check(string timeList){
      //разделим строку на подстроки (разделитель , )
      ushort usep1=StringGetCharacter(",",0);
      ushort usep2=StringGetCharacter("-",0);
      ushort usep3=StringGetCharacter(":",0);
      string param[],param2[],param3[],param4[];
      long start_hour=0,start_minute=0,start_seconds=0;
      long end_hour=0,end_minute=0,end_seconds=0;
      datetime start_tm=0,end_tm=0,tm[];
      ArrayInitialize(tm,0);
      ArraySetAsSeries(tm,true);
      CopyTime(_Symbol,PERIOD_D1,0,2,tm);
      MqlDateTime dt={0};
      TimeToStruct(TimeCurrent(),dt);
      
      int c=StringSplit(timeList,usep1,param);
      if(c<0) return (true);//диапозон не задан, можно торговать весь день
      for(int i=0;i<c;i++){
         StringTrimRight(param[i]);
         StringTrimLeft(param[i]);
         
         if(StringSplit(param[i],usep2,param2)==2){
            StringTrimRight(param2[0]);
            StringTrimLeft(param2[0]);
            StringTrimRight(param2[1]);
            StringTrimLeft(param2[1]);
            //удалили возможные лишние пробелы, теперь у нас есть время начала и окончания
            //разделим на чч.мм.сс
            if(StringSplit(param2[0],usep3,param3)>=1){
            //время начала
               start_hour=StringToInteger(param3[0]);
               if(ArraySize(param3)>=2) start_minute=StringToInteger(param3[1]);
               if(ArraySize(param3)==3) start_seconds=StringToInteger(param3[2]);
            }
            if(StringSplit(param2[1],usep3,param4)>=1){
            //время окончания
               end_hour=StringToInteger(param4[0]);
               if(ArraySize(param4)>=2) end_minute=StringToInteger(param4[1]);
               if(ArraySize(param4)==3) end_seconds=StringToInteger(param4[2]);
            }
            
            if(start_hour<=end_hour){
               start_tm=(datetime)(tm[0]+start_hour*3600+start_minute*60+start_seconds);
               end_tm=(datetime)(tm[0]+end_hour*3600+end_minute*60+end_seconds);
            }else{
               if(dt.hour>=0 && dt.hour<start_hour){
                  start_tm=(datetime)(tm[1]+start_hour*3600+start_minute*60+start_seconds);
                  end_tm=(datetime)(tm[0]+end_hour*3600+end_minute*60+end_seconds);
               }
               if(dt.hour>0 && dt.hour>=start_hour){
                  start_tm=(datetime)(tm[0]+start_hour*3600+start_minute*60+start_seconds);
                  end_tm=(datetime)(tm[0]+24*3600+end_hour*3600+end_minute*60+end_seconds);
               }
            }
            
            if(TimeCurrent()>=start_tm && TimeCurrent()<=end_tm)  return (true);
              
         }
         
      }
      
      return (false);    
  }
  
  void OnTrade(){
      
      if(semafor>0){
          PrintFormat("Открыт ордер %d",semafor);
          semafor=0; //сбросим семафор, операция с ордером завершаена, можно открывать следующий ордер
      }    
  }
 
おそらくバグと思われる)MT5を起動する際、MT4と異なり、サーバーに接続 せずに起動すると、何らかの理由で前回の認証(ログイン/パスワード)が読み込まれず、再度認証が必要となり、この場合、パスワードとログインは保存されない。何が問題なのでしょうか?
 

これは、テクニックが- 同じアカウントで同時に別の利益(それは一日オフ、引用符、エントリ価格、スワップだった - 一致、唯一の利益は一致しない)来ているものです。

ただ、最初の写真では投資用のパスワードで端末にログインして最適化を実行していますが、2枚目の写真では取引用のパスワードでログインしています。また、端末を再起動したり、アップデートしたりしても、すべてが同じままでした。見積書が届いたとき、すべてが正常化されたように思えた

 
notused:

これは、技術が来ているものです - 同じアカウントで同時に異なる利益(それは一日オフ、引用符、エントリ価格、スワップだった - 一致、唯一の利益が一致しない)。

ただ、最初の写真では投資用のパスワードで端末にログインして最適化を実行していますが、2枚目の写真では取引用のパスワードでログインしています。また、端末を再起動したり、アップデートしたりしても、すべてが同じままでした。見積書が届いたとき、すべてが正常化されたように思えた

どうやら、変動利益を計算 するために端末で利用可能な クロスレート が異なっていたようです。
 
Rosh:
どうやら、浮動利益を計算するために 端末で利用できる クロスレート が違っていたようです。
一度は経験したことだが、もう二度とないかもしれない。つまり、まったくクリティカルではないのです。そのため、サービスデスクには手紙を出していません。ただ、損益計算の 手順が完璧でないことは知っておいてほしい(たとえば、なぜクロスレートが違うのか)。
Документация по MQL5: Торговые функции / OrderCalcProfit
Документация по MQL5: Торговые функции / OrderCalcProfit
  • www.mql5.com
Торговые функции / OrderCalcProfit - Документация по MQL5
 

2分ごとにこの「セット」のエラーをTrading Signalで送出します。どうすれば直るのか?

 
または、トレーディングシグナルのエラーはどこに行けばいいのでしょうか?
 
kharti: または、トレーディングシグナルのエラーについてどこに問い合わせればいいのでしょうか?
ServiceDesk(プロフィール内)。
 
antt:

異なる入力パラメータを送信する。シンボル、周期、入力パラメータは同じで、指標も同じです。ターミナルはリソースの消費を最小限に抑えようとするため、この場合、インジケーターの新しいコピーは作成されず、つまり、1つのmql5プログラムが実際に動作します。

リソース消費の最適化については理解し、覚えていますが、おそらくシンボル、期間、入力パラメータと一緒に、我々はまた、指標の略称を 確認する必要がありますか?プログラマーが一意の ショートネームを明確に設定した場合、彼は自分が何をしているかを理解し、このインジケータがすでにチャートに存在していたとしても、別のコピーが必要です。例えば、インジケータには入力データが全くなく、初期段階で全ての初期データを自動計算しますが、別のパラメータを入力しないために、偽のパラメータを入力し、それを記憶することを強制する必要があります。