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

 
Vitaly Muzichenko:

なるほど、致命的でないミスを示してくれましたね。

機能の仕組み、自分で答えましたね。


テスターでは問題ないです。実際にはこのような仕組みになっています。
ファイル:
yOXZsAXZ-X4.jpg  479 kb
 
Tigerfreerun:
テスターではOKです。それが実際のところ、どうなんでしょう。

この場合、コードを処理して、すべての値をprint(Print(...) )し、エラーが発生する場所を確認する必要があります。

 
Tigerfreerun:
テスターでは問題ないです。それが実際のところ、どうなんでしょう。

今、答えが出ましたね。

トレーディング、自動売買システム、トレーディング戦略のテストに関するフォーラム

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

アレクセイ・ビクトロフ さん 2018.09.06 21:00

考えるべき方向性:利益が0より少ない場合...ソート時のアレイの大きさは?

また、注文が全くない場合の配列の大きさはどうなるのでしょうか?
すべての利益が0より大きくない場合,1次元のソート可能な配列a[][2]のサイズはどうなるか考えてみてください.
 

こんにちは。"Rollover "というEAですが、予定通りには動きません。 マイナスで決済するとロットを2倍にしますが、その後のTPの決済はなぜか前に決済したマイナストレードを戻すことができません。何が問題なのか、アドバイスしてください。メールボックスで質問したいのですが。

extern string TimeStart    = "04:00";  //Время начала контрольного периода
extern string TimeEnd      = "09:00";  //Время окончания контрольного периода
extern string TimeCloseOrder = "23:30";//Время в которое происходит закрытие всех ордеров
extern double LOT          = 0.1;
extern int    Magic        = 777;
extern double K_martin     = 2;
extern bool   No_Loss      = true;
int slippage = 3;
double marga,Lot,SL,TP;
int tip,Orders,tipOrders,TradeDey;
//-------------------------------------------------------------------+
int init()
{
   if (Digits==5 || Digits==3) slippage = 30;
}
int start()
{
   datetime Time_Start      = StrToTime(StringConcatenate(Day(),".",Month(),".",Year()," ",TimeStart,     ":00"));
   datetime Time_End        = StrToTime(StringConcatenate(Day(),".",Month(),".",Year()," ",TimeEnd,       ":00"));
   datetime Time_CloseOrder = StrToTime(StringConcatenate(Day(),".",Month(),".",Year()," ",TimeCloseOrder,":00"));

   if (Time_CloseOrder>Time_End) if (CurTime()>=Time_CloseOrder) CLOSEORDERS();

   int tip;
   if (Orders>OrdersTotal()) tip=CloseOrder();
   Orders=OrdersTotal();

   if (ORDERS(0)==0 && tip==0 && (CurTime()<Time_CloseOrder || Time_CloseOrder<=Time_End) && TradeDey!=TimeDay(CurTime()))
   {
      int BarStart = iBarShift(NULL,0,Time_Start,false);
      int BarEnd   = iBarShift(NULL,0,Time_End  ,false);
      double Max_Price=iHigh(NULL,0,iHighest(NULL,0,MODE_HIGH,BarStart-BarEnd,BarEnd));
      double Min_Price=iLow (NULL,0,iLowest (NULL,0,MODE_LOW, BarStart-BarEnd,BarEnd));
   
      if (TimeCurrent()>Time_End && ObjectFind("bar0"+Time_End)==-1)
      {
         ObjectCreate("bar0"+Time_End, OBJ_RECTANGLE, 0, 0,0, 0,0);
         ObjectSet   ("bar0"+Time_End, OBJPROP_STYLE, STYLE_SOLID);
         ObjectSet   ("bar0"+Time_End, OBJPROP_COLOR, Blue);
         ObjectSet   ("bar0"+Time_End, OBJPROP_BACK,  true);
         ObjectSet   ("bar0"+Time_End, OBJPROP_TIME1 ,Time_Start);
         ObjectSet   ("bar0"+Time_End, OBJPROP_PRICE1,Max_Price);
         ObjectSet   ("bar0"+Time_End, OBJPROP_TIME2 ,Time_End);
         ObjectSet   ("bar0"+Time_End, OBJPROP_PRICE2,Min_Price);
      }
      
      if (Bid>Max_Price) OrderSend(Symbol(),OP_BUY,LOT,Bid,slippage,Min_Price,
         NormalizeDouble(Ask + Max_Price-Min_Price,Digits),"BreakdownLevel",Magic,Blue);
      if (Bid<Min_Price) OrderSend(Symbol(),OP_SELL,LOT,Bid,slippage,Max_Price,
         NormalizeDouble(Bid - Max_Price+Min_Price,Digits),"BreakdownLevel",Magic,Blue);
      return;
   }
   if (No_Loss) No_Loss();
   if (tip==1 && TradeDey!=TimeDay(CurTime()))
   {
      Lot=Lot*K_martin;
      if (tipOrders==0) OrderSend(Symbol(),OP_SELL,Lot,Bid,slippage,SL,TP,"Nevalyashka",Magic,Blue);
      if (tipOrders==1) OrderSend(Symbol(),OP_BUY ,Lot,Ask,slippage,SL,TP,"Nevalyashka",Magic,Blue);
   }
   return(0);
}
//-------------------------------------------------------------------+
int CloseOrder()
{
   string txt;
   double loss;
   int i=OrdersHistoryTotal()-1;
   if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==true)
   {                                     
      if (OrderSymbol()==Symbol() && Magic==OrderMagicNumber())
      {
         tipOrders=OrderType();
         Lot=OrderLots();
         loss = MathAbs(OrderProfit()/MarketInfo(Symbol(),MODE_TICKVALUE)/Lot/K_martin);
         if (tipOrders==0)
         {
            TP=NormalizeDouble(Bid - loss*Point,Digits);
            SL=NormalizeDouble(Ask + loss*Point,Digits);
         }
         if (tipOrders==1)
         {
            SL=NormalizeDouble(Bid - loss*Point,Digits);
            TP=NormalizeDouble(Ask + loss*Point,Digits);
         }
         if (OrderClosePrice()==OrderTakeProfit() || OrderProfit()>=0) TradeDey=TimeDay(CurTime());
         if (OrderClosePrice()==OrderStopLoss()) return(1);
      }
   }  
   return(0);
}
//+-----------------------------------------------------------------+
int ORDERS(int tip)
{
   int N_Sell,N_Buy;
   for (int i=0; i<OrdersTotal(); i++)
   {                                               
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
      {
         if (OrderSymbol()==Symbol() && Magic==OrderMagicNumber())
         {
            if (OrderType()==OP_BUY ) N_Buy++;
            if (OrderType()==OP_SELL) N_Sell++;
         }
      }   
   }
if (tip== 0) return(N_Buy+N_Sell);
if (tip== 1) return(N_Buy);
if (tip==-1) return(N_Sell);
}                  
//-------------------------------------------------------------------+
void No_Loss()
{
   int tip;
   double TP,OOP;
   for (int i=OrdersTotal()-1; i>=0; i--) 
   {
      if (OrderSelect(i, SELECT_BY_POS)==true)
      {
         tip = OrderType();
         if (tip<2 && OrderSymbol()==Symbol())
         {
            if (OrderMagicNumber()!=Magic) continue;
            TP = OrderTakeProfit();
            OOP = OrderOpenPrice();
            if (tip==0) //Bay               
            {  
               if (OrderStopLoss()>OrderOpenPrice()+Ask-Bid) return;
               if ((TP-OOP)/2+OOP<=Bid)
               OrderModify(OrderTicket(),OOP,NormalizeDouble(OOP+Ask-Bid,Digits),TP,0,White);
            }                                         
            if (tip==1) //Sell               
            {                                         
               if (OrderStopLoss()<OrderOpenPrice()-Ask+Bid) return;
               if (OOP-(OOP-TP)/2>=Ask)
               OrderModify(OrderTicket(),OOP,NormalizeDouble(OOP-Ask+Bid,Digits),TP,0,White);
            } 
         }
      }
   }
}
//------------------------------------------------------------------+
void CLOSEORDERS()
{
   bool error;
   int err;
   while (true)
   {  error=true;
      for (int i=OrdersTotal()-1; i>=0; i--)
      {                                               
         if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
         {
            if (OrderSymbol()!=Symbol()||Magic!=OrderMagicNumber()) continue;
            if (OrderType()==OP_BUY)
               error=OrderClose(OrderTicket(),OrderLots(),Bid,3,CLR_NONE);
            if (OrderType()==OP_SELL)
               error=OrderClose(OrderTicket(),OrderLots(),Ask,3,CLR_NONE);
         }   
      }
      if (!error) {err++;Sleep(2000);RefreshRates();}
      if (error || err >5) return;
   }
}
//-------------------------------------------------------------------+
 
Tigerfreerun:
この機能が具体的に何をするものなのか、よく理解できていません。しかし、筆者も言っているように、その本来の目的は、シンボル間の負け注文を儲かる注文でカバーすることである。機能の修正と理解のため、ご協力をお願いします。
void MaxMinProfit()
{
int i, N, MaxTic, MinTic;
double   MinProf=0, MaxProf=0, OP, g, a[][2];
string MinSym, MaxSym;
ArrayResize(a, 0);
 
for (i=OrdersTotal()-1; i>=0; i--) 
  {    
   if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) 
    { 
     if (OrderType()==OP_SELL ||  OrderType()==OP_BUY )
      {
       OP = NormalizeDouble(OrderProfit()+OrderSwap()+OrderCommission(),2);
       
      if (MinProf>OP) 
      {
       
          MinProf=OP;
          MinTic=OrderTicket();
          MinSym=OrderSymbol();
          
         }
         
      if (OP>0) 
      {
       
          N++;
            ArrayResize(a, N);
            a[N-1][0]=OP;
            a[N-1][1]=OrderTicket();
          
         }
         
         }
         }
         
         }
         
      ArraySort(a, WHOLE_ARRAY, 0, MODE_DESCEND);//MODE_ASCEND);
      
      for (i=0; i<Level; i++) 
       {
     
     g+=a[i][0];
     //int ti=a[i-2][1];
     }
         
         
     
     if(MinProf <0 && (g+MinProf)>=ProcMax)
      {
       for (i=0; i<Level; i++) 
       {
       if (OrderSelect(a[i][1], SELECT_BY_TICKET, MODE_TRADES))
        {
        //Alert(a[i][1]);
         if (OrderType()== OP_BUY)
         {
          OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(),MODE_BID), Slip, CLR_NONE);
          }
          if (OrderType()== OP_SELL)
           {
           OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(),MODE_ASK), Slip, CLR_NONE);
           }
          }
         }
          
          
          
          if (OrderSelect(MinTic, SELECT_BY_TICKET, MODE_TRADES))
        {
         if (OrderType()== OP_BUY)
         {
          OrderClose(MinTic, OrderLots(), MarketInfo(OrderSymbol(),MODE_BID), Slip, CLR_NONE);
          }
          if (OrderType()== OP_SELL)
           {
          OrderClose(MinTic, OrderLots(), MarketInfo(OrderSymbol(),MODE_ASK), Slip, CLR_NONE);
           }
          }}       
return;
}

この関数が何をするものなのか、あなたは理解していないし、理解したくもない。使うんですね。自分で選んだのだから。何のために使うのかを理解せずに、どうやって使うんだ。

どこからどんな理由でエラーが出ているのか、先ほどお伝えしました。

もうひとつ、明確にしておきたいことがあります。

配列が宣言されている。緑色で表示されています。1次元の長さが0である。青字の線がはっきりしない。配列のサイズをリセットしたい場合は, ArrayFree() がありますが,宣言したばかりの動的配列の長さはゼロなので,この関数も意味がありません.

2.注文がない場合、赤色で表示されているコードは実行されません。したがって、配列のサイズはゼロのままです。

3.配列の並べ替えは、1目盛りごとに行われます。コードから導かれる。そして、空のポケットには何が仕分けられるのでしょうか?ウズラの卵2個でなければ......?


そして、これがエラー文面です...。なんて言ったらいいんだろう。開発者は、誰かが空の配列をソートしようとすることを予見していなかったのです。そのために特別なメッセージを考えてくれたわけではありません。

ArrayFree - Операции с массивами - Справочник MQL4
ArrayFree - Операции с массивами - Справочник MQL4
  • docs.mql4.com
При написании скриптов и индикаторов необходимость в использовании функции ArrayFree() может возникнуть не часто: так как при завершении работы скрипта вся использованная память сразу же освобождается, а в пользовательских индикаторах основная работа с массивами представляет собою доступ к индикаторным буферам, размеры которых автоматически...
 
Alexey Viktorov:

この関数が何をするものなのか、あなたは理解していないし、理解したくもない。使うんですね。自分で選んだのだから。何のために使うのかを理解せずに、どうやって使うんだ。

どこからどんな理由でエラーが出ているのか、先ほどお伝えしました。

もうひとつ、明確にしておきたいことがあります。

1. 配列が宣言される。コード内では緑色でハイライトされています。1次元の長さが0である。青で囲った線がはっきりしない。配列のサイズをリセット したい場合は、 ArrayFree() がありますが、今宣言した動的配列は長さがゼロなので、この関数も無意味です。

2.注文がない場合、赤色で表示されているコードは実行されません。したがって、配列のサイズはゼロのままです。

3.配列の並べ替えは、1目盛りごとに行われます。コードから導かれる。そして、空のポケットには何が仕分けられるのでしょうか?ウズラの卵2個でなければ......?


そして、これがエラー文面です...。なんて言ったらいいんだろう。開発者は、誰かが空の配列をソートしようとすることを予見していなかったのです。そのために特別なメッセージを考えてくれたわけではありません。

アレクセイ、君は間違っている。ArrayFree() は、メモリが不要になったときに配列からメモリを解放する役割を果たしますが、これは非常に稀なことであり、今回のケースでも確実に不要です。

ZeroMemory(a), ArrayInitialize(a,xxx) は配列をゼロにするために使われ、ArrayResize(a,xxx) は1次元でサイズを変更するために使われるべきものである。

しかし、この修正はあなたの推論に影響を与えず、正しいものです。

 
Artyom Trishkin:

アレクセイ、それは正しくない。ArrayFree() は、この配列が不要になったときに配列からメモリを解放するために使用されますが、これは非常にまれなケースで、間違いなくこのケースではありません。

ZeroMemory(a), ArrayInitialize(a,xxx) は配列をゼロにするために使われ、ArrayResize(a,xxx) は1次元でサイズを変更するために使われるべきものである。

しかし、この修正はあなたの推論には影響しません、正しいのです。

ドキュメントによると

ArrayFree .

は,任意の動的配列のバッファを解放し,0次元のサイズを0に設定する。

私の表現が足りず、誤解されたのかもしれませんね。
 
Alexey Viktorov:

ドキュメントによると

私の表現が足りず、誤解されたのかもしれませんね。

そして、さらにその奥。


備考

スクリプトとインジケータでは、スクリプトの動作停止後、使用したメモリはすべて直ちに解放されるため、ArrayFree()関数の使用はあまり必要ありません。カスタムインジケータでは、配列を使用するほとんどの操作は、クライアント端末の実行サブシステムによって自動的に管理されているインジケータバッファにアクセスすることです。

プログラムが複雑な動的条件下でメモリを独立して管理する必要がある場合、ArrayFree()関数により、不要な動的配列が占有しているメモリを明示的かつ即座に解放することができるようになります。


任意の動的配列のバッファを解放 し,0次元のサイズを0に設定 します.

わかりましたか?後編を 読んで、最初の-重要な-部分を見逃したのですか?配列に割り当てられたメモリーを解放します。それは...消えた...。配列に割り当てられたメモリ領域は解放され、他のデータで占有できるようになります。なぜ、関数を再実行するたびに、この配列にメモリを再割り当てしなければならないのでしょうか?あなたはそれを解放することになっています。必要なのは、サイズを変更する - ArrayResize()、または配列をゼロにする - ArrayInitialize()、ZeroMemory() です。また、配列のためのメモリ空間は解放されず、プログラムが終了するまでこの配列のために確保されたままとなります。

 
Artyom Trishkin:

そして、さらにその奥。


備考

スクリプトやインジケータでArrayFree()関数を使用する必要はあまりありません。カスタムインジケータでは、配列を使用するほとんどの操作は、クライアント端末の実行サブシステムによって自動的に管理されるインジケータバッファにアクセスすることです。

プログラムが複雑な動的条件下でメモリを独立して管理する必要がある場合、ArrayFree()関数により、不要な動的配列が占有しているメモリを明示的かつ即座に解放することができます。


任意の動的配列のバッファを解放 し,0次元のサイズを0に する

わかりましたか?後編を 読んで、肝心の 前編を見逃したんでしょ?配列に割り当てられていたメモリを解放します。それだけだ...消えた...。アレイに割り当てられたメモリ領域は解放され、さらに他のデータで占有することができます。なぜ、関数を再実行するたびに、この配列にメモリを再割り当てしなければならないのでしょうか?あなたはそれを解放することになっています。必要なのは、サイズを変更する - ArrayResize()、または配列をゼロにする - ArrayInitialize()、ZeroMemory() です。また、配列のためのメモリ空間は解放されず、プログラムが終了するまでこの配列のために確保されたままとなります。

よし...また、ローカル配列が関数の呼び出しごとに、あるいは最もありえないことですが、ティックごとに宣言されているとしたら......。しかし、配列のメモリは、配列が定義されるたびに確保されます。そうでしょう?また、メモリが解放されるかどうかは関係なく、メモリはその都度確保されているのですが...。

私の主旨は、「それはやめたほうがいいのでは...」ということです。で、もしそうするならば、ArrayFree() を通して行うのがよいでしょう。

ここで興味深いのは、関数が呼び出されるたびにローカル配列が宣言されると、それに対応して毎回メモリが確保されることだ。また、その際、どのようなアドレスが使われるのでしょうか?最初に配列を宣言するときと同じか、何が使われるのか?

 
Denis Danilov:

こんにちは。"Rollover "というEAですが、予定通りには動きません。 マイナスで決済するとロットを2倍にしますが、その後のTPの決済はなぜか前に決済したマイナストレードを戻すことができません。何が問題なのか、アドバイスしてください。コメントいただいた方々に、あらかじめお礼を申し上げます。

初回ロットより早めに倍率を確認するようにしましょう。クロージングを時間差で見る。