多通貨対応のインジケータを開発する方法をご存知の方はいらっしゃいますか? - ページ 3

 
4x_Gypsy:

大きなヒントは「でも、どうしたらいいのかわからない」でした。

OPから何の反応もないのは、何か問題があることを示唆しています。私の推測では、OPは理解不足でイライラして、このスレッドを放棄したのだと思います。数年前、私も同じようなことをした時期がありました。なぜなら、誰も私がいかに初心者であるかを理解するのに時間をかけず、絶えず例を投稿し、当時の私の理解を完全に超えた議論をしていたからです。

あなたの視点は正しいかもしれませんが、一方で私は、ドキュメントをざっと見れば簡単に答えが見つかるような質問をたくさん見てきましたし、何度もそのような質問に答えるのは本当に馬鹿らしいことだと感じています。

さらに、ここにはgoogleと検索オプションがあります。もし私が何かをする方法を知らないなら、これが私の次のステップで、自分で問題を解決しようとすることです。

このスレッドのトピックの場合、私は多通貨システムをコーディングする方法を知らないので、私はgoogleに答えるか、すでに存在するコードをここで検索していたことでしょう。

 
gooly:

しかし、その一方で、ドキュメントを見ればすぐに答えが見つかるような質問を何度も何度もしているうちに、自分がバカに思えてきたのです。

さらに、ここにはgoogleと検索オプションがあります。もし私が何かをする方法がわからなければ、これが私の次のステップで、自分で問題を解決しようとすることです。

このスレッドのトピックの場合、私は多通貨システムをコーディングする方法を知らない私は、すでに既存のコードをgoogleやここで検索に答えていただろう。

フィードバックありがとうございました、そしてそれが肯定的であったことを嬉しく思います(笑)

私はこのような状況での私の出方を心配している人に申し訳ありません。私は本当に平和を愛するドラマのないタイプの人間で、納得のいかないことはたいてい無視します。

 

こんにちは、皆さん。

長い間、ここで活動せずに申し訳ありません。私は仕事といくつかのプロジェクトで忙しい旅行していた、しばらくの間、プロジェクトを脇に残していた。

ポストの更新を読んだ後、私は明らかにするためにいくつかのポイントがあります。

  1. 私は誰かが私のためにすべてのものをコード化する必要はありません、ちょうど私に正しい方向を示す必要があり、私は残りの部分を行う。さて...私は今WHRoederの解決策をテストし、私のものを作り、後で結果をここに投稿する予定です。WHRoeder の提案: https://www.mql5.com/en/forum/158938
  2. このトピックを作成する前に、私は同様の投稿を検索しましたが、見つかりませんでした...その後、それを作成します。
  3. 私は応答するのに長い時間がかかる申し訳ありませんが、それは本当に過労だったが、今私は、インジケータを使用して作業を続けています。
  4. 私の貧しい英語のために申し訳ありません! 私の言語はポルトガル語であり、私は英語を投稿するとき、Googleの翻訳を使用する必要があり、それは完璧ではありません。


 
私のテストは以下の通りです。

ただ、ユーザーが自分の資産を知らせることができ、その後、すべてのペアのHigh/Low値を表示します。

もし、選択したペアがアクティブウィンドウと同じであれば、そのペアのレートは正常に更新されます。しかし、他のペアは、インジケータが追加されたときのレートしか表示されず、もう更新されません...。

下の画像にあるように、GBPUSDのウィンドウにインジケータが追加され、GBPUSDのレートはティックごとにうまく更新されています。しかし、EURUSDは更新されず、同じ値のままである。

コピーされた料金


以下、インジケーターのコードです。

//+------------------------------------------------------------------+
//|                                                MultiCurrency.mq4 |
//|                         Copyright 2016, Wemerson Couto Guimarães |
//|                  https://www.mql5.com/pt/users/wemersonrv/seller |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Wemerson Couto Guimarães"
#property link      "https://www.mql5.com/pt/users/wemersonrv/seller"
#property version   "1.00"
#property strict
#property indicator_separate_window

input string UsePairs="EURUSD,GBPUSD"; // Pares separados por vírgula.

struct pair_struct{
   string symbol;
   MqlRates rates[];
};
pair_struct pairs[];
bool initial;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){
   int i=0, j=0, c;
   string _pairs[], msg="";
   bool pairok=false;
   initial = true;
   ENUM_INIT_RETCODE result = INIT_SUCCEEDED;
   
   StringSplit(UsePairs, StringGetCharacter(",",0), _pairs);
   
   for( i=0; i< ArraySize(_pairs); i++){
      pairok=false;
      
      for( j=0; j<SymbolsTotal(true); j++){
         if( SymbolName(j, true) == _pairs[i]){
            pairok=true;
            break;
         }
      }
      if( pairok ){
         c=ArraySize(pairs);
         ArrayResize(pairs, c+1);
         pairs[c].symbol = _pairs[i];
      }else{
         msg += _pairs[i] + ", ";
      }
   }
   if( msg != "" ){
      string invalids = ArraySize(pairs)== 1?"Invalid Pair: ": "Invalid Pairs: ";
      msg = invalids +  StringSubstr(msg,0,StringLen(msg)-2) + ". Please Check!";
      Alert(msg);
      result = INIT_PARAMETERS_INCORRECT;
   }else{
      for(i=0; i<ArraySize(pairs); i++){
         ArrayCopyRates( pairs[i].rates, pairs[i].symbol, PERIOD_CURRENT );
      }
   }   
   
   return(result);

}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){
   
   Comment("");
   
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {

   int i=0;
   if( initial ){
      for( i=0; i<ArraySize(pairs); i++){
         if(pairs[i].rates[0].time == 0) return(rates_total);
      }
      initial=false;
   }
   
   string log="";
   
   for(i=0; i<ArraySize(pairs); i++){
      log += "\nPair: " + pairs[i].symbol + 
             " - High: "+ DoubleToStr(pairs[i].rates[0].high, Digits()) + 
             " - Low: "+ DoubleToStr(pairs[i].rates[0].low, Digits());
   }

   Comment( "\n\n*** Pair Rates***\n" + log );
   return(rates_total);
   
}
//+------------------------------------------------------------------+

 
RefreshRates() を使ってみましたが、やはり同じ結果でした。同じウィンドウのペアだけが動作し、他のペアは更新されません。
 
wemersonrv:
RefreshRates() を使ってみましたが、やはり同じ結果でした...同じウィンドウのペアだけが動作し、他のペアは更新されません。

RefreshRates() は、MqlRatesの データとは関係ありません。WHRoederの サンプルコードは、Pre-600のビルドでのみ有効です。最新のビルドでは、ArrayCopyRates() の戻りコード、エラーコード、Rates配列のサイズ、WHRoederの 指摘したtime属性の有効性など、私の投稿で述べた様々な 点を確認する必要があります。

PS!もし、英語で困っているのなら、私にPMを送ってください。私はポルトガル人です(ポルトガル)。

 

こんにちは、皆さん。

OnCalculate関数に レートの "再コピー "を入れてテストしてみました。動作しているように見え、エラーも返さない。

私はこれが私が必要とするものを行うための最良の方法であるかどうかはわからないが、どうやらそれは動作しており、エラーなしで動作しています。


   int i=0;
   if( initial ){
      for( i=0; i<ArraySize(pairs); i++){
         if(pairs[i].rates[0].time == 0) return(rates_total);
      }
      initial=false;
   }

   // My change to recopy rates every tick by adding a loop at starting of OnCalculate() to do this
   // AS FMIC says, ArrayCopyRates needs the array without content, 
   // then before recopy, free the array.
   for(i=0; i<ArraySize(pairs); i++){
      ArrayFree(pairs[i].rates);
      ArrayCopyRates(pairs[i].rates, pairs[i].symbol, PERIOD_CURRENT);
   }
 
wemersonrv: テストでは、OnCalculate関数にレートの「再コピー」を含めました...最初にすべての反復でペアの配列を解放し、次にレートを再びコピーするループを追加することによって。動作しているようで、エラーは出ていません。
  1. ドキュメントに 記載されている通りです。
    他のチャートからデータ(シンボル名やタイムフレームが現在のものと異なる)を要求した場合、対応するチャートがクライアント端末で開かれていない可能性があり、必要なデータはサーバーから要求する必要があります。この場合、変数 last_error にエラー ERR_HISTORY_WILL_UPDATED (4066 - request history data are under updating) が格納され、再度リクエストする 必要があります。
    そしてここで 検証
    ArrayCopyRates は履歴が全くない場合、エラーを返します (ERR_NO_HISTORY_DATA = 4073。ダウンロードが完了するまで繰り返される呼び出しも失敗します)。履歴はあるが最新でない場合、ArrayCopyRates は有効なものを返し、さらに `_LastError` に ERR_HISTORY_WILL_UPDATED (= 4066.) を設定します。
  2. リターンコードをテストして、必要ならスリープして再試行してください。関数の戻り値とは何ですか?どのように使用するのですか?-MQL4フォーラムと MQL4プログラムにおける一般的なエラーとその回避方法 - MQL4 Articles
 

このスレッドを見ている人たちに、最新情報をお知らせします

彼は英語が苦手で、私たちはポルトガル語を話すので、私はPMでOPのコードの修正を手伝っています。テストでは、"ArrayCopyRates() "関数で起こっている別の "おかしい "ことに気づきました。EAでMqlRates 配列を"ArrayCopyRates() "で使用する場合、データ配列は常に現在の状態を報告する仮想のものであり、データは常に新鮮である。

しかし、Indicatorの場合はそうではないようです。配列は仮想的なコピーではなく、「ArrayCopyRates()」が呼ばれた瞬間に設定された静的なコピーになっています。シンボルがチャートシンボルと異なる場合、データが更新されない。チャートと同じシンボルであれば、配列のデータは「ライブ」で期待通りに更新されますが、別のシンボルの場合は静的コピーとなります。

したがって、これをインディケータで動作させるには、OnCalculate()イベントを呼び出すたびに、新しいデータが必要であれば、"ArrayCopyRates()"関数を呼び出す必要があります。

 

皆さん、こんにちは。

  • FMIC、応援 ありがとうございます
  • WHRoeder さん、こちらこそありがとうございます...あなたはいつも私たちみんなの味方です
  • フォーラムメンバーの皆さん、このスレッドで発生した議論に感謝します。とても興味深かったです。

これは、私が後で行うのと(ほぼ)同じことですが、違いは、私はArrayCopyRatesの前にArrayFreeを実行することです...そして私は、あなたが私を助けた検証を行いません。

FMICが助けてくれた最終的なコードはこちらです。インジケーターのコードで正常に動作しています..:

input string UsePairs="NZDCAD,EURUSD,GBPUSD,USDJPY"; // pairs separated by commas
struct pair_struct{
   string symbol;
   MqlRates rates[];
   bool valid;
};
pair_struct pairs[];
bool initial;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){
   
   int i=0, j=0, c;
   string _pairs[], msg="";
   bool pairok=false;
   initial = true;
   ENUM_INIT_RETCODE result = INIT_SUCCEEDED;
   
   StringSplit(UsePairs, StringGetCharacter(",",0), _pairs);
   
   for( i=0; i< ArraySize(_pairs); i++){
      pairok=false;
      
      for( j=0; j<SymbolsTotal(true); j++){
         if( SymbolName(j, true) == _pairs[i] ){
            pairok=true;
            break;
         }
      }
      if( pairok ){
         c=ArraySize(pairs);
         ArrayResize(pairs, c+1);
         pairs[c].symbol = _pairs[i];
         pairs[c].valid = false;
      }else{
         msg += _pairs[i] + ", ";
      }
   }
   if( msg != "" ){
      string invalids = ArraySize(pairs)== 1?"Invalid Pair: ": "Invalid Pairs: ";
      msg = invalids +  StringSubstr(msg,0,StringLen(msg)-2) + ". Please Check!";
      Alert(msg);
      result = INIT_PARAMETERS_INCORRECT;
   }
   return(result);

}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){
   
   Comment("");
   
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {

   InitializeRates();
   
   int i=0;
   string log="";
   for(i=0; i<ArraySize(pairs); i++){
      log += "\nPar: " + pairs[i].symbol;
      if( pairs[i].valid ){
         log += " - Time: "+ TimeToString( pairs[i].rates[0].time ) + 
                " - Open: "+ DoubleToString( pairs[i].rates[0].open, (int)MarketInfo( pairs[i].symbol, MODE_DIGITS ) ) +
                " - Close: "+ DoubleToString( pairs[i].rates[0].close, (int)MarketInfo( pairs[i].symbol, MODE_DIGITS ) ) +
                " - High: "+ DoubleToString( pairs[i].rates[0].high, (int)MarketInfo( pairs[i].symbol, MODE_DIGITS ) ) +
                " - Low: "+ DoubleToString( pairs[i].rates[0].low, (int)MarketInfo( pairs[i].symbol, MODE_DIGITS ) );
      }else{
         log += " - Currently not valid!";
      }
   }

   Comment( "\n\n*** Pair Rates***\n" + log );
   return(rates_total);
   
}
//+------------------------------------------------------------------+

void InitializeRates(){
 
   for( int i=0; i<ArraySize( pairs ); i++ ){
      pairs[i].valid = false;
      ResetLastError();
      if( ArrayCopyRates(pairs[i].rates, pairs[i].symbol, PERIOD_CURRENT) > 0 ){
         if( _LastError == 0 ){
            if( ArraySize(pairs[i].rates) > 0 ){
               if( pairs[i].rates[0].time > 0 )
                  pairs[i].valid = true;
            }
         }
      }
   }

}