MQL4、MQL5に関する初心者からの質問、アルゴリズムやコードに関するヘルプ、ディスカッションなど。 - ページ 256

 
Alexey Viktorov:

自分のメモリーチップの話です。:)))

そんな些細なことは、コードを書くときに簡単に再確認し、明確にし、必要に応じて実行し、また忘れるということをしないことです。

なるほど! :)
 
Artyom Trishkin:
よく、トロール機能やブレークイーブン機能を求める人がいることに気づきました。この関数に渡された価格チャート(МАшашкаや放物線など)に線を引く指標の値に応じて、ブレイクイーブンレベルのストップやトレーリングストップ位置を描画する関数をスケッチしてみました。

#property strict // в самое начало кода вашей программы (если нету там ещё)


// Функцию - за пределы остальных функций программы
//+------------------------------------------------------------------+
//| Трейлинг по значению + перенос стопа на уровень безубытка        |
//+------------------------------------------------------------------+
void TrailingByLevel(string symbol_name,           // Имя символа
                     int magic_number,             // Magic ордера
                     double level_of_trail,        // Уровень, на который ставим стоп (например МА или Parabolic SAR)
                     int trailing_start,           // Профит в пунктах для старта трала
                     int trailing_step,            // Шаг трала в пунктах
                     int trailing_stop,            // Отступ стоплосс от уровня МА или SAR в пунктах
                     int profit_for_breakeven=15,  // Профит в пунктах для переноса стопа в безубыток
                     int breakeven_level=5,        // Уровень безубытка в пунктах
                     bool use_trail=true,          // Флаг использования трала
                     bool use_breakeven=false      // Флаг использования безубытка
                     )
   {
   int lv=StopLevel(symbol_name)+1;                // Получаем значение Stop Level по символу + 1 пункт (из отдельной функции)
   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) {
            int    digits=(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS);
            double point=(SymbolInfoDouble(symbol_name,SYMBOL_POINT));
            double pb=SymbolInfoDouble(symbol_name,SYMBOL_BID);
            double profit=pb-OrderOpenPrice();                    // Профит позиции в цене (без комиссий и свопов)
            //--- безубыток
            if(use_breakeven) {
               //--- если профит в цене больше заданного
               if(profit>=profit_for_breakeven*point) {
                  int err=ERR_NO_ERROR;
                  double sl=NormalizeDouble(OrderOpenPrice()+breakeven_level*point,digits);
                  if(pb-lv*point>sl && OrderStopLoss()<sl) {
                     // Сюда вписываем свою функцию модификации. Можно конечно и стандартной обойтись:
                     // OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),OrderExpiration(),clrModify); ...
                     // ... но в ней не предусмотрены проверки кодов возврата торгового сервера и их обработка
                     //ModifyOrder(-1,sl,-1,err);
                     }
                  if(err==ERR_MARKET_CLOSED) return;
                  }
               }
            //--- трал
            if(use_trail) {
               //--- если профит в пунктах больше заданного, или изначально задан меньше ноля
               if(profit>=trailing_start*point || trailing_start==EMPTY) {
                  int err=ERR_NO_ERROR;
                  double sl=NormalizeDouble(level_of_trail-trailing_stop*point,digits);  // вычисляем новый уровень стоплосс по значению, переданному в функцию
                  //--- Если новое значение СЛ не ближе Stop Level и если новое положение СЛ больше старого+шаг СЛ, то модифицируем стоп позиции
                  if(pb-lv*point>sl && OrderStopLoss()+trailing_step*point<sl) {
                     // Сюда вписываем свою функцию модификации. Можно конечно и стандартной обойтись:
                     // OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),OrderExpiration(),clrModify); ...
                     // ... но в ней не предусмотрены проверки кодов возврата торгового сервера и их обработка
                     //ModifyOrder(-1,sl,-1,err);
                     }
                  if(err==ERR_MARKET_CLOSED) return;
                  }
               }
            }

         //--- Продажи
         if(OrderType()==OP_SELL) {
            int    digits=(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS);
            double point=(SymbolInfoDouble(symbol_name,SYMBOL_POINT));
            double pa=SymbolInfoDouble(symbol_name,SYMBOL_ASK);
            double profit=OrderOpenPrice()-pa;                    // Профит позиции в цене (без комиссий и свопов)
            //--- безубыток
            if(use_breakeven) {
               //--- если профит в цене больше заданного
               if(profit>=profit_for_breakeven*point) {
                  int err=ERR_NO_ERROR;
                  double sl=NormalizeDouble(OrderOpenPrice()-breakeven_level*point,digits);
                  if(pa+lv*point<sl && (OrderStopLoss()>sl || OrderStopLoss()==0)) {
                     // Сюда вписываем свою функцию модификации. Можно конечно и стандартной обойтись:
                     // OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),OrderExpiration(),clrModify); ...
                     // ... но в ней не предусмотрены проверки кодов возврата торгового сервера и их обработка
                     //ModifyOrder(-1,sl,-1,err);
                     }
                  if(err==ERR_MARKET_CLOSED) break;
                  }
               }
            //--- трал
            if(use_trail) {
               //--- если профит в пунктах больше заданного, или изначально задан меньше ноля
               if(profit>=trailing_start*point || trailing_start==EMPTY) {
                  int err=ERR_NO_ERROR;
                  double sl=NormalizeDouble(level_of_trail+trailing_stop*point,digits);  // вычисляем новый уровень стоплосс по значению, переданному в функцию
                  //--- Если новое значение СЛ не ближе Stop Level и если новое положение СЛ больше старого+шаг СЛ, то модифицируем стоп позиции
                  if(pa+lv*point<sl && (OrderStopLoss()-trailing_step*point>sl || OrderStopLoss()==0)) {
                     // Сюда вписываем свою функцию модификации. Можно конечно и стандартной обойтись:
                     // OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),OrderExpiration(),clrModify); ...
                     // ... но в ней не предусмотрены проверки кодов возврата торгового сервера и их обработка
                     //ModifyOrder(-1,sl,-1,err);
                     }
                  if(err==ERR_MARKET_CLOSED) break;
                  }
               }
            }
         }
      }
}
//+------------------------------------------------------------------+
int StopLevel(string symbol_name) {
   int sp=(int)SymbolInfoInteger(symbol_name,SYMBOL_SPREAD);
   int lv=(int)SymbolInfoInteger(symbol_name,SYMBOL_TRADE_STOPS_LEVEL);
   return((lv==0)?sp*2:lv);
   }
//+------------------------------------------------------------------+
一般的に、何かあれば - 尋ねてください。あるいは正しい。

私のEAを改良するのを手伝ってくれませんか?ストップをかけるEAがあるのですが、ストップロスをドラッグする方法がわかりません。全く理解できないので、専門家の力を貸してほしい。

 

配列の要素の 重さを決定する関数が必要です。ある要素に近い(より近い)他の要素の数が多ければ多いほど、その重みは大きくなる。もしかしたら、すでにそのような機能があるのかもしれません。サンプルに含まれる元素の濃度で重さを決めるようなもの。ありがとうございます。

 

こんにちは!MQL4テスターで、なぜ1回だけ反復して停止するのかがわかりません?TimeCurrent() が更新されない?アップデートの方法を教えてください。ティック単位ではなく、毎秒、あるいは毎秒5回、EAを動作させたい。

  int start()                                     // Спец. функция start
  {
    while(!IsStopped())
     {
      RefreshRates();
      if(RefreshRates()==true||MyTimer(1))
        {
         код советника
        }  
     }
    return(0);
  }


bool MyTimer(int Delay) //функция для работы советника по заданому интервалу времени, а не по тикам
{
  RefreshRates();
  static datetime Time1, Time2;
  bool Result = False;
  
  if(MathMod(TimeSeconds(TimeCurrent()), Delay) == 0.0)
  {
    Time1 = TimeCurrent();
    if(Time1 != Time2)
    {  
      Time2 = Time1;
      Result = True;
    }
  }
  return(Result);
}
 
Jenya77769:

こんにちは!MQL4テスターで、なぜ1回だけ反復して停止するのかが分かりません?TimeCurrent()が更新されない?アップデートの方法を教えてください。多通貨EAはティックで動作するのではなく、毎秒、もしくは毎秒5回動作することが必要です。

このEAはどのように実行するのですか? つまり、エキスパートディレクトリからですか?

start()関数(旧名称、現代版OnTick)は、1ティック ごとに実行されます、つまり、ティックの終了後に実行されるべきものです。そして、それをループさせているのですか?

 
Maxim Kuznetsov:

これはアドバイザーとして、あるいはエキスパートディレクトリから実行しているのですか?

EAのstart()関数(旧名称、現代版OnTick)は1ティック ごとに実行される、つまりティックが終了した時点で終了するはずです。そして、それをループさせているのですか?

このチュートリアルでは、ループした "start "関数を使用した例が紹介されており、許可されています。

https://book.mql4.com/ru/special/index

О сложных программах - Учебник по MQL4
О сложных программах - Учебник по MQL4
  • book.mql4.com
О сложных программах - Учебник по MQL4
 
Jenya77769: この教科書では、これは許可されており、ループした開始関数の例もあります。

もちろん、ループさせることも可能です。しかし、次のTICまでには手放すことが望ましい。さもなければ、TICは失われます。必要ですか?

 
LRA:

ループさせることは、もちろん可能です。しかし、次のTICまでにはリリースすることが望ましい。さもなければ、TICは失われます。必要なのか?


新しいティック情報は、エンドレスループの中でRefreshRates(); を使って取得することができます。

 
Jenya77769: 新しいティックに関する情報は、無限ループの中でRefreshRates(); 関数を使用して取得することができます。

RefreshRates(); 関数は、チェックするだけ です。データが更新された場合、true を返す。while(!RefreshRates(); - tickを待つ) ということができます。

 
LRA:

RefreshRates(); 関数は、 チェックするだけ です。データが更新された場合、true を返す。while(!RefreshRates()); - 刻み目を待つという 方法があります。

リフレッシュ(人を混乱させない)し、更新が成功したか失敗したかのフラグを返します。

SymbolInfoDouble()、SymbolInfoTick()でデータを受信する場合は、なくても大丈夫です。