初心者の方からの質問 MQL5 MT5 MetaTrader 5 - ページ 1340

 
まあ、結局のところ、このスクリプトは
void OnStart()
  {
   int Target=6;       //Количество тайм-фреймов
   int Counter_UP=0;   //Счетчик нахождения цены над МА
   int Counter_DOWN=0;
   int MA = 200;       //Период МА
   double bufer_MA[];  //Буфер для хендла
   ENUM_TIMEFRAMES frame1[10];  //Битная маска тайм-фреймов
//___________________int битная маска ENUM  Массив таймфреймов__________________________________________
   frame1[1]=1;
   frame1[2]=5;
   frame1[3]=15;
   frame1[4]=30;
   frame1[5]=16385;
   frame1[6]=16388;
   frame1[7]=16408;
   frame1[8]=32769;
   frame1[9]=49153;
//____________________________________________________________________________________________________________

   int KollSymbols = SymbolsTotal(true);  //Колл. символов в маркет вотч
   Alert("Колл.Инстр = ",KollSymbols);
//---
   int MA200;  //Переменная для хендла
   for(int i=0; i<KollSymbols; i++) //Перебераем все символы из маркет вотч
     {
      string symbol = SymbolName(i,true);  //Выбираем имя символа из маркет вотч
     // Alert("symbol = ",symbol,"i= ",i);
      for(int I=1; I<=Target; I++)  //Перебераем таймфреймы
        {
         MA200 = iMA(symbol,frame1[I],MA,0,MODE_EMA,PRICE_MEDIAN);  //хендл на выбранном тайме
         CopyBuffer(MA200,0,TimeCurrent(),5,bufer_MA); // заполнение масива bufer_MA хендлом MA200 выбранного тайма

         ArraySetAsSeries(bufer_MA,true);  //Разворачиваем массив как в тайм-серии

         //Alert("Символ - ",symbol,"i= ",i);
         // Alert("Simbol = ",symbol," bufer_MA[1] = ",bufer_MA[1]);
         if(iClose(symbol,frame1[I],1) > bufer_MA[1])  //Если цена 1 баре, на выбранном символе и тайме, БОЛЬШЕ цены скользяхи на 1 баре
           {
            //Alert("iClose= ",iClose(symbol,frame1[I],1), " bufer_MA[1]= ",bufer_MA[1]);
            Counter_UP++;
            if(Counter_UP==Target)
               Alert("Инструмент для наблюдения в покупки - ",symbol);

            ArrayFree(bufer_MA);      //Очистка буфера индикатора
         
           }
         else
           {
            ArrayFree(bufer_MA);      //Очистка буфера индикатора
           }
         IndicatorRelease(MA200); //Удаление хендла
        }
      Counter_UP=0;
      Counter_DOWN=0;
     }
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+

正常に動作しています。 そして、22の楽器のリストです。 5分くらいかかりますが、配列へのハンドルの書き込みにほとんどの時間を費やしているのが不思議です。 プロファイリング結果


Question: ハンドルから配列に5つの値をコピーするのに、なぜこんなに時間がかかるのでしょうか。コピー作業はリストの22の商品に対して132回行われ、273の商品に対しては1632回のコピーが必要で、ハードディスクのすべての商品に対して履歴をロードする必要があります。

 
Fast235 #:

ハンドルの作成と削除について

というのが気になります。

それは私がやっていることです、上のコードを見てください、質問もありますよ))

 
Kira27 #:
そこで、判明したのが、このスクリプト

は正常に動作し、22個のツールのリストも5分程度で処理できます。 しかし、これは奇妙なことで、ほとんどの時間を配列へのハンドルの書き込みに費やしています。 プロファイリング結果


Question: ハンドルから配列への5つの値のコピーになぜこんなに時間がかかるのでしょうか?

私の記憶違いでなければ

引用符がダウンロードされていれば、遅くなることはなく、正常に動作しているようです。最初の起動がとても長いのですが、どうやら引用符をダウンロードしているようです。

//+------------------------------------------------------------------+
void OnStart()
  {
   int Target = 6;     //Количество тайм-фреймов
   int Counter_UP = 0; //Счетчик нахождения цены над МА
   int Counter_DOWN = 0;
   int MA = 200;       //Период МА
   double bufer_MA[];  //Буфер для хендла
   int MA200[][9];  //Переменная для хендла
   string symbol[];

   ENUM_TIMEFRAMES frame1[9];  //Битная маска тайм-фреймов
//___________________int битная маска ENUM  Массив таймфреймов__________________________________________
   frame1[0] = 1;
   frame1[1] = 5;
   frame1[2] = 15;
   frame1[3] = 30;
   frame1[4] = 16385;
   frame1[5] = 16388;
   frame1[6] = 16408;
   frame1[7] = 32769;
   frame1[8] = 49153;
//____________________________________________________________________________________________________________

   int KollSymbols = SymbolsTotal(true);  //Колл. символов в маркет вотч
   Print("Колл.Инстр = ", KollSymbols);
   int res = 0;
   for(int i = 0; i < KollSymbols; i++)
     {
      for(int I = 0; I < 9; I++) //Перебераем таймфреймы
        {
         ArrayResize(MA200, i + 1);
         ArrayResize(symbol, i + 1);
         symbol[i] = SymbolName(i, true); //Выбираем имя символа из маркет вотч
         MA200[i][I] = iMA(symbol[i], frame1[I], MA, 0, MODE_EMA, PRICE_MEDIAN); //хендл на выбранном тайме
         if(MA200[i][I] == INVALID_HANDLE)
            PrintFormat("Инвалид хэндл, символ %s, тайм %d", symbol[i], frame1[I]);
         res++;
        }
     }
   Print("Создано хэндлов = " + (string)res);

//---
   for(int i = 0; i < KollSymbols; i++)
     {
      for(int I = 0; I < 9; I++) //Перебераем таймфреймы
        {
         int size = CopyBuffer(MA200[i][I], 0, 1, 1, bufer_MA); // заполнение масива bufer_MA хендлом MA200 выбранного тайма
         PrintFormat("Скопировано %d, символ %s, тайм %d", size, symbol[i], frame1[I]);
         if(size > 0)
            if(iClose(symbol[i], frame1[I], 1) > bufer_MA[0]) //Если цена 1 баре, на выбранном символе и тайме, БОЛЬШЕ цены скользяхи на 1 баре
              {
               Counter_UP++;
              }
        }
     }
   Print("Counter_UP = " + (string)Counter_UP);
  }
//+------------------------------------------------------------------+
 
Kira27 #:

このスクリプトのポイントは、Market Watchの各商品を1分から4Hまでのタイムフレームで見ていくことです。

もしそういうことをするならば、配列を作り、そこに過去のデータを格納し、現在のデータを更新していくことになります。これにより、重いサイクルやCopyBufferを回避することができます。何もかもが飛んでしまうのです。

 
Aleksandr Slavskii #:

私の記憶違いでなければ

見積書がダウンロードされれば、遅くなることはなく、問題なく動作しているようです。最初の起動にとても時間がかかるのは、見積もりをダウンロードしているのでしょう。

ご意見とバージョンアップをありがとうございます、試してみます)!ただ、プログラムを終了する前にハンドルを削除しないのか、プログラム終了後に自動的に削除されますが、タスクマネージャーによるとメモリが解放されないのが不思議です。

 
Aleksei Stepanenko #:

もしそういうことをするならば、配列を作り、そこに過去のデータを格納し、現在のデータを更新していくことになります。これにより、重いループやCopyBufferを回避することができます。何もかもが飛んでしまうのです。

ありがとうございます!私も考えてみます)

 
Kira27 #:

あなたのフィードバックとあなたのバージョンをありがとう、私はそれで実験します)!私はあなたがプログラムを終了する前にハンドルを削除しない理由だけ理解していない? または彼らはタスクマネージャで判断すると、RAMが解放されていないものの、プログラムの終了時に自動的に削除されています。

インジケーターハンドルは、スクリプト終了後、一定時間経過すると自動的に削除されるという話をどこかで読みました。でも、正確ではありません。

 
ごあいさつMQL5でEAをテスト した矢印の上にマウスを置くと、ポップアップウィンドウに統計情報を出力 する方法を教えてください。
 

こんにちは

端末にリニアレグレッションツールが 搭載されている

同じチャンネルをグラフィカルなオブジェクトで描画するスクリプトがある

しかし、中心線だけが正しく描かれ、偏差線は中心線から誤った距離で描かれている

偏差値の正しい計算方法を知っている人がいれば教えてください。

あるいは、既成のソリューションがあるのかもしれません。

ありがとうございました

 

こんにちは。

AMarketsブローカーでテストしたところ、暗号通貨のOrderSend関数が 動作しない理由を教えてください。暗号に関するトレーディングアドバイザーを規制で禁止しているものは見つかりませんでした。それとも、私のコードにエラーがあるのでしょうか? GetLastErrorは、エラー4756を表示します。

#property copyright "qwerty"
#property link      "qwerty@list.ru"
#property version   "1.00"
//-----------------
//-----------------
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
//-----------------
//-----------------
CPositionInfo  aPosition;
CTrade         aTrade;
CSymbolInfo    aSymbol;
CAccountInfo   aAccount;
//-----------------
//-----------------

int      Slippage      = 3000;
//---
//---------------------------------
//------пробные переменные
double LotsCrypto = 0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   if(!aSymbol.Name(Symbol()))
      return(INIT_FAILED);
   RefreshRates();
//---устанавливаем допустимое проскальзывание
   aTrade.SetDeviationInPoints(Slippage);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  RefreshRates();
   LotsCrypto = 0.1;
   if(OpenSellPosition(aSymbol.Name(), LotsCrypto, NULL, Slippage, ORDER_FILLING_RETURN))
      Print("Ура");  
   Comment("Symbol.Name = " + string(aSymbol.Name()) + "\n" +
           "Ask = " +  string(aSymbol.Ask()) + "\n"+
           "GetLastError = " +  string(GetLastError()) + "\n"+
           "LotsCrypto = " +  string(LotsCrypto));

}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+ Обновление котировок                                             +
//+------------------------------------------------------------------+
bool RefreshRates()
  {
   if(!aSymbol.RefreshRates())
     {
      Print("Не удалось обновить котировки валютной пары!");
      return(false);
     }
   if(aSymbol.Ask() == 0 || aSymbol.Bid() == 0)
      return(false);
   return(true);
  }

//+------------------------------------------------------------------+
bool OpenSellPosition(string symbol, double volume, string comment="", ulong deviation=1000, ENUM_ORDER_TYPE_FILLING filling=ORDER_FILLING_FOK)
  {
   MqlTradeRequest Request;
   MqlTradeResult Results;
   ZeroMemory(Request);
   ZeroMemory(Results);
   Request.price=SymbolInfoDouble(_Symbol,SYMBOL_BID);
   Request.action=TRADE_ACTION_DEAL;
   Request.type=ORDER_TYPE_SELL;
   Request.symbol=symbol;
   Request.volume=volume;
   Request.deviation=deviation;
   Request.comment=comment;
   Request.type_filling=filling;
   bool res=false;
   res=OrderSend(Request,Results);
   if(res)
     {
      if(Results.deal>0)
         return(true);
      else
         return(false);
     }
   return(false);
  }
//+------------------------------------------------------------------+
理由: