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

 
MakarFX:
手動発注に対応したEAはありますか?
はい、私は手動で保留中の注文を置くか、または単に取引を開くと、Expert Advisorが動作します。
 
SGarnov:
挿入しようとすると、コンパイルできない。コード全体、必要であれば、コンパイルのスクリーンショットを載せます。私のTPはSTOPに対して係数(外部変数)で設定されているのですが、もしかして手動設定にすればEAが追加しやすくなるのでしょうか?

機能

  double GetPointLastLoss(){
            datetime t=0;
            double result=0,p=0,tp=0;
            int i=OrdersHistoryTotal(),magic=0;
         for(int pos=0; pos<i; pos++)
         {
          if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
         {
          if((OrderSymbol()==_Symbol) && (OrderMagicNumber()==magic))
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(t<OrderCloseTime())
                 {t=OrderCloseTime(); p=OrderProfit(); tp=OrderType();
                  if(tp==OP_BUY&&p<0)
                    {
                     result=OrderOpenPrice()-OrderClosePrice();
                    } else {result=0;}
                  if(tp==OP_SELL&&p<0)
                    {
                     result=OrderClosePrice()-OrderOpenPrice();
                    } else {result=0;}
                 }
              }
           }
        }
     }
   return(result);
  }

をグローバルスコープから削除。コンパイルはmagic=0。

magic=0

	          
 
Galim_V:

機能

をグローバルスコープから削除し、コンパイル時にmagic=0を削除します。

削除され、コンパイルエラーはなく、1つだけ警告が列 tp=0 の3行目の関数で、外部変数 int tp=0 のヒアリングでポップアップします。プログラマーが何を嫌がっているのか、よくわからない。すべてのコードが添付され、あなたが修正するのが困難でない場合、真実はどこか近くにあります。

input int takeProfitC = 2;// Коэффициент Take Profit
input int stop_loss = 100;//Уровень Stop Loss
input int stop_count = 2;//Количество Stop Loss
input double lots = 0.01;//Лоты
input int slippage = 30;//Проскальзывание
input int datePeriod = 48;// Время удержания при SL


int tp = 0;
int tpc = 0;
double tp_price_old = 777;
int stopLossCount = 0;
datetime startOrder = 0;
int pending_ticket = 0;
int lastMagic = 0;
bool isLimitOn = false;
bool isStart = True;
datetime startTime = 0;
bool isFinal = false;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
//
   //OrderSend(Symbol(), OP_SELL, 0.01, 0.76228, 300, 0, 0);
   //OrderSend(Symbol(), OP_SELLSTOP, 0.01, 0.77057, 300, 0, 0);
   //OrderSend(Symbol(), OP_BUYSTOP, 0.01, 0.76928, 300, 0, 0);
   tp = stop_loss * takeProfitC;
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
//--

}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {
//---
//Comment("StopCount: " + stopLossCount + "\n" + "CurrentStopC: " + stop_count);
   for(int i = OrdersTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)) {
         if(OrderSymbol() == Symbol()) {
         int magic = OrderMagicNumber();
            if((OrderType() == OP_BUY || OrderType() == OP_SELL) && OrderOpenTime()) {
               int ticket = OrderTicket();
               if(!findPending(ticket)) {
                  if(OrderSelect(ticket, SELECT_BY_TICKET) && (((TimeCurrent() <= (startTime + datePeriod * 3600))) || isStart)) {
                     if(OrderType() == OP_BUY) {
                        double sl_price = NormalizeDouble(OrderOpenPrice() - Point() * MathMax(stop_loss, MarketInfo(Symbol(), MODE_STOPLEVEL)), Digits);
                        double tp_price = NormalizeDouble((OrderOpenPrice() + Point() * (tp)), Digits);
                        if(!OrderModify(OrderTicket(), OrderOpenPrice(), sl_price, tp_price, OrderExpiration())) {
                           Print("Ошибка модификации ордера:", GetLastError());
                        } else {
                           if(stopLossCount < stop_count && tp_price != tp_price_old){
                              pending_ticket = OrderSend(Symbol(), OP_SELLSTOP, lots, sl_price, slippage, 0, 0, NULL, OrderTicket());
                              lastMagic = ticket;
                              isLimitOn = true;
                              if(isStart){
                                 startTime = TimeCurrent();
                                 isStart = false;
                              }
                              tp_price_old = tp_price;
                              stopLossCount++;                         
                           }
                        }
                     } else if(OrderType() == OP_SELL) {
                        double sl_price = NormalizeDouble(OrderOpenPrice() + Point() * MathMax(stop_loss, MarketInfo(Symbol(), MODE_STOPLEVEL)), Digits);
                        double tp_price = NormalizeDouble((OrderOpenPrice() - Point() * (tp)), Digits);
                        if(!OrderModify(OrderTicket(), OrderOpenPrice(), sl_price, tp_price, OrderExpiration())) {
                           Print("Ошибка модификации ордера:", GetLastError());
                        } else {
                          if(stopLossCount < stop_count && tp_price != tp_price_old){
                              pending_ticket = OrderSend(Symbol(), OP_BUYSTOP, lots, sl_price, slippage, 0, 0, NULL, OrderTicket());
                              lastMagic = ticket;
                              isLimitOn = true;
                              if(isStart){
                                 startTime = TimeCurrent();
                                 isStart = false;
                              }
                              stopLossCount++;
                              tp_price_old = tp_price;  
                          }
                        }
                     }
                  }
               }
         }
         if(startTime > 0 && (TimeCurrent() >= (startTime + datePeriod * 3600))){
            deletePending(lastMagic);
            isFinal = true;
         }
            
         if(lastMagic != 0 && !IsSell() && !IsBuy() && magic == lastMagic) {
            tpc = 0;
            startTime = 0;
            stopLossCount = 0;
            deletePending(lastMagic);
            isStart = true;
            }
         }
     }
   }
   if((startTime > 0 || isFinal) && !IsSell() && !IsBuy()){
            tpc = 0;
            startTime = 0;
            stopLossCount = 0;
            isStart = true;
            isFinal = false;
   }
}
//+----------------------------------------------------------------------------+
//|  Возвращает пункты убытка последнего закрытого ордера в пунктах            |
//+----------------------------------------------------------------------------+
double GetPointLastLoss(){
            datetime t=0;
            double result=0,p=0,tp=0;
            int i=OrdersHistoryTotal(),magic=0;
         for(int pos=0; pos<i; pos++)
         {
          if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
         {
          if((OrderSymbol()==_Symbol) && (OrderMagicNumber()==magic))
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(t<OrderCloseTime())
                 {t=OrderCloseTime(); p=OrderProfit(); tp=OrderType();
                  if(tp==OP_BUY&&p<0)
                    {
                     result=OrderOpenPrice()-OrderClosePrice();
                    } else {result=0;}
                  if(tp==OP_SELL&&p<0)
                    {
                     result=OrderClosePrice()-OrderOpenPrice();
                    } else {result=0;}
                 }
              }
           }
        }
     }
   return(result);
  }                                                                
//+------------------------------------------------------------------+
bool findPending(int ticket) {
   for(int i = OrdersTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)) {
         if(OrderMagicNumber() == ticket) {
            return true;
         }
      }
   }

   for(int i = OrdersHistoryTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
         if(OrderMagicNumber() == ticket) {
            return true;
         }
      }
   }
   return false;
}
//+------------------------------------------------------------------+
void deletePending(int magic) {
   for(int i = OrdersTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)) {
         if(OrderMagicNumber() == magic) {
            if(OrderType() != OP_BUY && OrderType() != OP_SELL) {
               if(!OrderDelete(OrderTicket())) {
                  Print("Ошибка удаления отложеного одера: ", GetLastError());
               }
            }
            break;
         }
      }
   }
}
//+------------------------------------------------------------------+
bool IsSell()
{
   int count = 0;
   for (int trade = OrdersTotal () -1; trade >= 0; trade--)
   {
      if (OrderSelect (trade, SELECT_BY_POS, MODE_TRADES) 
          && OrderSymbol() == Symbol()
          && OrderType() == OP_SELL)
      {
         count++;
      }
      
   }
   if (count == 0)
      return false;
   else
      return true;
}
//+------------------------------------------------------------------+
bool IsBuy()
{
   int count = 0;
   for (int trade = OrdersTotal () -1; trade >= 0; trade--)
   {
      if (OrderSelect (trade, SELECT_BY_POS, MODE_TRADES) 
          && OrderSymbol() == Symbol()
          && OrderType() == OP_BUY)
      {
         count++;
      }
      
   }
   if (count == 0)
      return false;
   else
      return true;
}
 
SGarnov:

削除され、コンパイルエラーはなく、1つだけ警告が列 tp=0 の関数の3行目で、外部変数 int tp=0 のヒアリングでポップアップします。プログラマーが何を嫌がっているのか、よくわからない。すべてのコードが添付され、あなたが修正するのが困難でない場合、真実はどこか近くにあります。

このように見えます。

//+------------------------------------------------------------------+
//|                                                   SGarnov.v2.mq4 |
//|                                           Copyright 2020, DrMak. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, DrMak."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//--- input parameters
input int      T_Profit = 2;     // Коэффициент Take Profit
input int      S_Loss   = 100;   // Уровень Stop Loss
input double   O_Lots   = 0.01;  //Лоты
input int      Input4;
input int      Input5;
input int      Input6;

double sl_price,tp_price,t_profit,s_loss;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- 
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   t_profit = S_Loss*T_Profit;
   s_loss   = MathMax(S_Loss, MarketInfo(Symbol(), MODE_STOPLEVEL));
   // Проверяем наличие ордеров BUY
   if(CountOrders(_Symbol, 0)>0)
     {
      // Проверяем последний закрытый ордер SELL на наличие убытка в пунктах
      if(GetPointLastLoss(1)>0)
        {
         // Если убыток есть, то добавляем пункты убытка
         sl_price = NormalizeDouble(Point() * s_loss, Digits);
         tp_price = NormalizeDouble(GetPointLastLoss(1)+Point() * t_profit, Digits);
         ModifyOrder(_Symbol, sl_price, tp_price);
        }
      else
        {
         // Если убытка нет
         sl_price = NormalizeDouble(Point() * s_loss, Digits);
         tp_price = NormalizeDouble(Point() * t_profit, Digits);
         ModifyOrder(_Symbol, sl_price, tp_price);
        }
     }
   // Проверяем наличие ордеров SELL
   if(CountOrders(_Symbol, 1)>0)
     {
      // Проверяем последний закрытый ордер BUY на наличие убытка в пунктах
      if(GetPointLastLoss(0)>0)
        {
         // Если убыток есть, то добавляем пункты убытка
         sl_price = NormalizeDouble(Point() * s_loss, Digits);
         tp_price = NormalizeDouble(GetPointLastLoss(0)+Point() * t_profit, Digits);
         ModifyOrder(_Symbol, sl_price, tp_price);
        }
      else
        {
         // Если убытка нет
         sl_price = NormalizeDouble(Point() * s_loss, Digits);
         tp_price = NormalizeDouble(Point() * t_profit, Digits);
         ModifyOrder(_Symbol, sl_price, tp_price);
        }
     }
  }
//+--------------------------------------------------------------------------------------------------------------------+
//| Подсчет ордеров по типу                                                                                            |
//+--------------------------------------------------------------------------------------------------------------------+
//|  0 - ордера типа BUY          1 - ордера типа SELL                                                                 |
//|  2 - ордера типа BUYLIMIT     3 - ордера типа SELLLIMIT                                                            |
//|  4 - ордера типа BUYSTOP      5 - ордера типа SELLSTOP                                                             |
//|  6 - ордера типа Balance     -1 - Все типы ордеров                                                                 |
//+--------------------------------------------------------------------------------------------------------------------+
int CountOrders(string symb="", int or_ty=-1) 
  {
   int cnt=0;
   if(symb=="0") symb=_Symbol;
   for(int pos=OrdersTotal()-1;pos>=0;pos--)
     {
      if(OrderSelect(pos,SELECT_BY_POS)==true)
        {
         if(OrderSymbol()==symb || symb=="")
           {
            if(or_ty<0 || or_ty==OrderType()) cnt++;
           }
        }
     }
   return(cnt);
  }
//+----------------------------------------------------------------------------+
//| Модификация ордера                                                         |
//+----------------------------------------------------------------------------+
//|    sl - ценовой уровень стопа                                              |
//|    tp - ценовой уровень тейка                                              |
//+----------------------------------------------------------------------------+
void ModifyOrder(string symb="", double sl=0, double tp=0)
  {
   if(symb=="0") symb=_Symbol;
   for(int pos=OrdersTotal()-1;pos>=0;pos--)
     {
      if(OrderSelect(pos,SELECT_BY_POS)==true)
        {
         if(OrderSymbol()==symb || symb=="")
           {
            if(OrderStopLoss()==0)
              {
               if(OrderType()==OP_BUY)
                 {
                  if(OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()-sl_price, OrderOpenPrice()+tp_price, OrderExpiration()))
                    {Print("Ордер модифицирован");}
                  else
                    {Print("Ошибка модификации ордера:", GetLastError());}
                 }
               if(OrderType()==OP_SELL)
                 {
                  if(OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()+sl_price, OrderOpenPrice()-tp_price, OrderExpiration()))
                    {Print("Ордер модифицирован");}
                  else
                    {Print("Ошибка модификации ордера:", GetLastError());}
                 }
              }
           }
        }
     }
  }
//+----------------------------------------------------------------------------+
//|  Возвращает пункты убытка последнего закрытого ордера в пунктах            |
//|  0 - последний ордер BUY                                                   |
//|  1 - последний ордер SELL                                                  |
//+----------------------------------------------------------------------------+
double GetPointLastLoss( int or_ty=-1)
  {
   datetime t=0;
   double result=0,p=0;
   int i=OrdersHistoryTotal();
   for(int pos=0; pos<i; pos++)
     {
      if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
        {
         if((OrderSymbol()==_Symbol))
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(t<OrderCloseTime())
                 {t=OrderCloseTime(); p=OrderProfit(); or_ty=OrderType();
                  if(or_ty==OP_BUY&&p<0)
                    {
                     result=OrderOpenPrice()-OrderClosePrice();
                    } else {result=0;}
                  if(or_ty==OP_SELL&&p<0)
                    {
                     result=OrderClosePrice()-OrderOpenPrice();
                    } else {result=0;}
                 }
              }
           }
        }
     }
   return(result);
  }
//+------------------------------------------------------------------+

あなたの場合、魔法は全く必要ありません。

 
MakarFX:

それくらいがちょうどいい。

あなたの場合、魔法はまったく必要ありません。

ありがとうございます、テストしてみます、ご報告します。私のものと同じように、新しいテイクに(トリガーがかかったら)ストップを追加するような仕組みだといいのですが。

外部パラメータInput4; 5; 6は何のために必要なのでしょうか?

 
SGarnov:
ありがとうございます、テストして報告します。私のものと同じように、新しいテイクにストップ(トリガーされた場合)を追加するような仕組みだといいのですが。

ここには修正しかありません。注文の削除や取り消しはできません。

EAが何をすべきかを書いていただければ、お手伝いできることがあると思います。

 
SGarnov:

外部パラメータInput4; 5; 6は何のために必要なのでしょうか?

削除するのを忘れていました
 
MakarFX:

EAが何をすべきかを書いていただければ、お手伝いできることがあると思います。

買い保留注文を出す - EA が動作している - 保留注文がトリガーされる - EA がこれを「見て」、このオープンオーダーにストップロスを置く。

ストップロス(外部パラメータは設定にて設定)。

テイクプロフィット(外部パラメータは1対2などの比率で設定されて います。)

ストップロス水準で売り注文を 保留。

想定されるシナリオ

バリエーション1。

A) 価格が武井に達した場合、Expert Advisorはストップロスと保留中の売り注文を削除します。

バリエーション2。

B) ストップロスが発動し、EAが「履歴に残った」場合。

売り注文が発注され、Expert Advisorはこの注文を再ポジショニングします。

ストップロス(外部パラメータは設定にて設定)。

テイクプロフィット+履歴からトリガーしたストップロス

ストップロス水準で 買い注文を保留する。

価格がテイクに達すると、Expert Advisorはストップロスと保留中の買い注文を削除します。

また、その逆で、売り注文を保留している状態で作業を開始した場合。

そして、アドバイザーは外部パラメータであるストップロス番号(私の場合、それは2です、それは変形2が3回繰り返され、アドバイザーは将来的に動作を停止し、すべての保留中の注文を削除することを意味します、最初のストップは考慮に入れられません)でその動作を停止するまで動作します。

もしtakeiに到達せず、variant 2が繰り返された場合、takeiに2つのストップが追加され、以降、設定された外部パラメータ"Stop Loss count" に依存することになります。


私が載せたコードは、私が説明した問題(テイクに追加する必要があります1ストップまたは2ストップの履歴に表示されません)を除いて、当然のように動作します。

こんな感じ。

 
SGarnov:

保留中の買い注文を入れ、EAが動作し、保留中の注文がトリガーされ、EAがこれを「見て」、このオープンオーダーにストップロスを配置します。

ストップロス(外部パラメータは設定にて設定)。

テイクプロフィット(外部パラメータは1対2などの比率で設定されて います。)

ストップロス水準で売り注文を 保留。

想定されるシナリオ

バリエーション1。

A) 価格が武井に達した場合、Expert Advisorはストップロスと保留中の売り注文を削除します。

バリエーション2。

B) ストップロスが発動し、EAが「履歴に残った」場合。

売り注文が発注され、Expert Advisorはこの注文を再ポジショニングします。

ストップロス(設定で外部パラメータを設定)

テイクプロフィット+履歴からトリガーしたストップロス

ストップロス水準で 買い注文を保留する。

価格がテイクに達すると、Expert Advisorはストップロスと保留中の買い注文を削除します。

また、その逆で、売り注文を保留している状態で作業を開始した場合。

そして、アドバイザーは外部パラメータであるストップロス番号(私の場合、それは2です、それは変形2が3回繰り返され、アドバイザーは将来的に動作を停止し、すべての保留中の注文を削除することを意味します、最初のストップは考慮に入れられません)でその動作を停止するまで動作します。

もしtakeiに到達せず、variant 2が繰り返された場合、takeiに2つのストップが追加され、以降、設定された外部パラメータ"Stop Loss count" に依存することになります。


私が載せたコードは、私が説明した問題(テイクに追加する必要があります1ストップまたは2ストップの履歴に表示されません)を除いて、当然のように動作します。

こんな感じです。

"ストップロスの数" - 連続で、または現在の日について?

 
MakarFX:

"ストップロスの数" - 連続で、または現在の日について?

通貨ペアの連続したストップ数。

履歴を分析するために、Expert Advisorは最初に注文をIDでラベル付けしますが、履歴の中でそれらを見つけることはできません、私はOrderMagikNumber()がそれらを検索することを考えました。多分、異なる通貨ペアからの履歴停止で、EAがそれらを「見る」のを止めるという事実のため?

またソースを貼るのか?彼がやるべきことは、「履歴からストップトレードを検索し、新たに置いたテイクに追加させる」ことを修正するだけです。