複数のEAを同時に実行する - ページ 3

 
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

extern bool CheckOncePerBar=true;
extern double FixedLotSize=1;
extern double SystemStopLoss=150;
extern double TakeProfit=0;
extern int Slippage=5;
extern int MagicNumber=3574;

//Global Variables
int BuyTicket=0;
int SellTicket=0;
double InternalStopLoss=0;
double CalcDigits=0;
double CalcPoint=0;
bool MABuyFanning=false;
bool MASellFanning=false;
int SelectedOrder=0;
bool Closed=false;
int ErrorCode=0;
string ErrLog="a";
double BuyStopLoss=0;
double SellStopLoss=0;
bool NewBar=false;
double ThisBarOpen=0;
double SmallMA=0;
double MediumMA=0;
double LargeMA=0;
int Counter=0;



//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
CalcDigits = MarketInfo(Symbol(),MODE_DIGITS);//MODE_DIGITS is count of digits after decimal point
if(CalcDigits==0) CalcPoint=1;//Dow      
if(CalcDigits==1) CalcPoint=0.1;   
if(CalcDigits==2) CalcPoint=0.01;//Gold & Nymex
if(CalcDigits==3) CalcPoint=0.01;//Yen
if(CalcDigits==4) CalcPoint=0.0001;//Not used
if(CalcDigits==5) CalcPoint=0.0001;//Non-Yen forex
InternalStopLoss=SystemStopLoss*CalcPoint;
   
   return(INIT_SUCCEEDED);
  }
//-----------------------------------------------

void OnTick()
{

   if(CheckOncePerBar)
      {
      if(ThisBarOpen!=Open[0])
         {
         ThisBarOpen=Open[0];
         NewBar=true;
         }
      else NewBar=false;
      }
    else NewBar=true;

if(NewBar)
{


//Reset Moving Averages
SmallMA=iMA(NULL,0,8,0,1,0,0);
MediumMA=iMA(NULL,0,10,0,1,0,0);
LargeMA=iMA(NULL,0,50,0,1,0,0);


   if(SmallMA>MediumMA&&MediumMA>LargeMA) MABuyFanning=true;
   else MABuyFanning=false;
      
   if(SmallMA<MediumMA&&MediumMA<LargeMA) MASellFanning=true; 
   else MASellFanning=false;   



if(BuyTicket==0&&MABuyFanning)
 {
      RefreshRates();
      BuyStopLoss= Bid-InternalStopLoss;
   //   while(IsTradeContextBusy()) Sleep(10);
      BuyTicket=OrderSend(Symbol(),OP_BUY,FixedLotSize,Ask,Slippage,BuyStopLoss,0,"Buy Order",MagicNumber,0,Green);
          if(BuyTicket==-1)
            {
            ErrorCode=GetLastError();
            Alert("Symbol: ",Symbol(),"Error in buy routine: ",ErrorCode);
            ErrLog=StringConcatenate("Bid: ",MarketInfo(Symbol(),MODE_BID)," Ask: ",MarketInfo(Symbol(),MODE_ASK)," Lots: ",FixedLotSize," Stop Loss: ",BuyStopLoss);
            Print(ErrLog);
            //Buy ticket revert to 0 so it can try again in case of slow connection/timeout etc.
            BuyTicket=0;
            } 
 }   


if(SellTicket==0&&MASellFanning)
 {
      RefreshRates();
      SellStopLoss=Ask+InternalStopLoss;
    //  while(IsTradeContextBusy()) Sleep(10);
      SellTicket=OrderSend(Symbol(),OP_SELL,FixedLotSize,Bid,Slippage,SellStopLoss,0,"Sell Order",MagicNumber,0,Red);
          if(SellTicket==-1)
            {
            ErrorCode=GetLastError();
            Alert("Symbol: ",Symbol(),"Error in sell routine: ",ErrorCode);
            ErrLog=StringConcatenate("Bid: ",MarketInfo(Symbol(),MODE_BID)," Ask: ",MarketInfo(Symbol(),MODE_ASK)," Lots: ",FixedLotSize," Stop Loss: ",SellStopLoss);
            Print(ErrLog);
            SellTicket=0;
            } 
  }  

//Exits

         if(BuyTicket!=0)
            {
            if(SmallMA<MediumMA)
            {
            for(Counter=0; Counter<=OrdersTotal()-1;Counter++)
               {
               SelectedOrder=OrderSelect(Counter,SELECT_BY_POS);
               if(OrderMagicNumber()==MagicNumber&&OrderSymbol()==Symbol()&&OrderType()==OP_BUY)
                  {
                 // while(IsTradeContextBusy()) Sleep(10);
                  Closed=OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_BID),Slippage,Red);
                  if(Closed) BuyTicket=0;
                  else Alert("Symbol: ",Symbol()," Ticket: ",BuyTicket," unable to close buy order(s): buy ma convergence close routine");                  
                  }
            Counter--;               
                }
            }
            }

         if(SellTicket!=0)
            {
            if(SmallMA>MediumMA)
            {
            for(Counter=0;Counter<=OrdersTotal()-1;Counter++)
               {
               SelectedOrder = OrderSelect(Counter,SELECT_BY_POS);
               if(OrderMagicNumber()==MagicNumber&&OrderSymbol()==Symbol()&&OrderType()==OP_SELL)
                  {
               //   while(IsTradeContextBusy()) Sleep(10);
                  Closed=OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_ASK),Slippage,Red);
                  if(Closed) SellTicket=0;
                  else Alert("Symbol: ",Symbol()," Ticket: ",SellTicket," unable to close sell order(s): sell ma convergence close routine");                  
                  }
            Counter--;               
                }
            }
            }
}            
return;   
}
 

まだカウンターがあるのか--。

GumRaiのコメント参照https://www.mql5.com/en/forum/151167/page2#954622

 
2つの連続したバーが全く同じ始値を持つことがあると思いますか?
   if(CheckOncePerBar){
      if(ThisBarOpen!=Open[0]){
         ThisBarOpen=Open[0];
         NewBar=true;
         }
      else NewBar=false;
      }
    else NewBar=true;

if(NewBar)
{
   : // doit
常にtimeを使用する
static datetime ThisBarTime = 0;
if(ThisBarTime != Time[0] || !CheckOncePerBar)
{
   ThisBarTime = Time[0];
   : // doit
これはdeinit/initサイクルを処理しません。外部静的変数 - MQL4フォーラム
 

ご投稿ありがとうございます。

時間ではなく、オープンを使ったのは、一度発生したバーのオープンは永久に固定され、変更されることがないからです。同じバーで、ティックが行われた現在のバーのオープンが、ThisBarOpenに格納されているオープンの値と同じかどうかを尋ねているのです。 さらに、Open は Time よりも単純なデータ検索であるのに対し、Time は他の何かを参照したり、ある種の計算をしなければならないかもしれないので、もっと簡単だと思いました。

Re Counter--; MagicNumberとSymbol()の両方が同じであることを最初にチェックする コードなので、他のEAが注文を閉じることができないので、私はそれを変えなかった。

停電でBuyTicketの内容が消えるという指摘は確かに受け止めましたが、私のテストではそのようなことは起こっていませんし、私のコードはまだ非常にゆっくりと動いています。したがって、私はそれが原因である可能性があることを見ることができません。

私の主な疑問は、オープンポジションを持つターミナルのウィンドウからEAを削除するのに長い時間がかかり、オープンポジションのないターミナルから削除するのに全く時間がかからないのはなぜか、ということです。偶然かもしれませんが、4つの窓すべてで?

 
前回も同じ問題がありましたが、実はEAをどのようにコード化するかが問題なのです。多分、あなたのEAはもう一度ゼロから書く必要がある時期なのでしょう。
 

これはあなたの問題に本当に関連しているかわかりませんが、あなたは1つのEAにつき1つの買い、1つの売りに取引を制限していますが、なぜこのようなことをするのでしょうか?

  if(SellTicket!=0)
  {if(SmallMA>MediumMA)
   {for(Counter=0;Counter<=OrdersTotal()-1;Counter++)
    {SelectedOrder = OrderSelect(Counter,SELECT_BY_POS);
     if(OrderMagicNumber()==MagicNumber&&OrderSymbol()==Symbol()&&OrderType()==OP_SELL)
     {Closed=OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_ASK),Slippage,Red);
      if(Closed) SellTicket=0;
      else Alert("Symbol: ",Symbol()," Ticket: ",SellTicket," unable to close sell order(s): sell ma convergence close routine");                  
     }
    Counter--;               
}}}} 

あなたはすでにここにチケット番号を持っています。

SellTicket=OrderSend(Symbol(),OP_SELL,FixedLotSize,Bid,Slippage,SellStopLoss,0,"Sell Order",MagicNumber,0,Red);

これを静的な int にすると、オーダープールを探し回ることなく、そのチケット番号で明示的にオーダーをクローズすることができます。

Closed=OrderClose(SellTicket,OrderLots(),MarketInfo(Symbol(),MODE_ASK),Slippage,Red);
 
Sneck55:

ご投稿ありがとうございます。


Re Counter--; MagicNumberとSymbol()の両方が同じであることを最初にチェックするコードなので、他のEAが注文を閉じることができないので、変更しませんでした。


私の主な疑問は、オープンポジションを持つターミナルのウィンドウからEAを削除するのになぜこんなに時間がかかり、オープンポジションのないターミナルから削除するのに全く時間がかからなかったのかということです。偶然の一致かもしれませんが、4つのウィンドウすべてですか?


ループがどのように機能するか理解していますか?

if(BuyTicket!=0)
            {
            if(SmallMA<MediumMA)
            {
            for(Counter=0; Counter<=OrdersTotal()-1;Counter++)
               {
               SelectedOrder=OrderSelect(Counter,SELECT_BY_POS);
               if(OrderMagicNumber()==MagicNumber&&OrderSymbol()==Symbol()&&OrderType()==OP_BUY)
                  {
                 // while(IsTradeContextBusy()) Sleep(10);
                  Closed=OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_BID),Slippage,Red);
                  if(Closed) BuyTicket=0;
                  else Alert("Symbol: ",Symbol()," Ticket: ",BuyTicket," unable to close buy order(s): buy ma convergence close routine");                  
                  }
            Counter--;               
                }
            }
            }

3つの注文が開いているとします。

最初の実行で、counter=0、つまりインデックス0を持つ注文が選択されます。

ループの最後に、カウンターを1減らし、カウンター== -1。

ループが再び実行される前に、for関数の 一部としてcounterが1だけ増加します。つまり、counter==0となります。

というわけで、次のループではまたcounter==0になります!!というように、延々とループが続きます。

このように、命令インデックス0をチェックし続ける無限ループにはまり込んでしまいます。

なぜなら、OrdersTotal - 1 は -1 になり、0 は <= -1 ではないからです。

 
GumRajさん、本当にありがとうございます!私の問題を解決してくれました。今は問題なく動作しています。MQL4でコードを書くのは初めてなので、勉強中です。forループがどのように機能するのか混乱していました。
 
Sneck55: GumRaj - あなたは私の問題を解決してくれました!これで問題なく使えます。
どのように解決したのですか?もしカウントダウンしていないなら、まだ問題があります(3)- 複数の注文または複数のEAがあるまで隠しておいてください
 
プールで起こることと一致するように、注文をクローズした場合はデクリメントする必要がありますが、注文をクローズしなかった場合はそうではありません。もし、注文をクローズせずにデクリメントすると、無限ループに陥ります。