事前計算された - ページ 4

 
Alexey Viktorov:

開発者は、インジケータ・バッファの初期化の問題に注意を払うべきかもしれませんね。なぜ、MT4ではそのような問題がないのですか?もしかして、完全な理解ではないのでは?問題は、EACHでチャートからインジケータを取った後にバッファの初期化を義務付けた後も、全てのバッファにゴミが入っているわけではなく、そこから取り出せないことです...。

個人的には、松葉杖は嫌いではありませんが、この松葉杖があまり複雑でなく、プラスの効果がある場合に限ります。しかし、ファイルに書き込んでから読むというのは、粗末な松葉づえだ。

全てのバッファではなく、いくつかのバッファでチャートからインジケータを削除した後...」とありますが、どのように想像されますか?チャートからインジケータを削除した後、そのインジケータのバッファに どのようにアクセスすることができますか?

では、具体的に問題点を探ってみましょう。コード+やったこと+得たもの...という標準セットが必要です。

 
Karputov Vladimir:

全てのバッファではなく、いくつかのバッファでチャートからインジケータを削除した後...」とありますが、どのように想像されますか?チャートからインジケータを削除した後、どのような方法でそのインジケータ・バッファに アクセスすることができますか?

では、具体的に問題点を探ってみましょう。コード+やったこと+得たもの...という標準セットが必要です。

純粋な仮定:現在のバッファアクセス中に、前のバッファが占有していた同じメモリ領域に入り込んでいる可能性があります。

Alexeyは、再起動時(端末のon/offスイッチ)にもバッファのデータを残したいのか、prev_calculated = 0の時(先にprev_calculated > 0の場合)だけ残したいのか、会話に入っていないのですが、キックしないでください。

 
Karputov Vladimir:

全てのバッファではなく、いくつかのバッファでチャートからインジケータを削除した後...」とありますが、どのように想像されますか?チャートからインジケータを削除した後、どのような方法でそのインジケータ・バッファに アクセスすることができますか?

では、具体的に問題点を探ってみましょう。コード+やったこと+得たもの...という標準セットが必要です。

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

/********************************************************************\
|                                               BalansEquityTest.mq5 |
|                                                           Viktorov |
|                                                  v4forex@yandex.ru |
\********************************************************************/

#property copyright "Viktorov"
#property link      "v4forex@yandex.ru"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers   6
#property indicator_plots     3
#property indicator_type1     DRAW_COLOR_LINE
#property indicator_color1    clrGold, clrGreen, clrRed
#property indicator_width1    2
#property indicator_label1    "Balance"
#property indicator_type2     DRAW_HISTOGRAM2
#property indicator_color2    clrCrimson
#property indicator_width2    2
#property indicator_label2    "EquityMin"
#property indicator_type3     DRAW_HISTOGRAM2
#property indicator_color3    clrDarkViolet
#property indicator_width3    2
#property indicator_label3    "EquityMax"

double balance[];
double clrBalance[];
double equityMaxB[];
double equityMinB[];
double equityMax[];
double equityMin[];

double maxEquity, minEquity;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0, balance, INDICATOR_DATA);
   SetIndexBuffer(1, clrBalance, INDICATOR_COLOR_INDEX);
   SetIndexBuffer(2, equityMin, INDICATOR_DATA);
   SetIndexBuffer(3, equityMinB, INDICATOR_DATA);
   SetIndexBuffer(4, equityMax, INDICATOR_DATA);
   SetIndexBuffer(5, equityMaxB, INDICATOR_DATA);
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);
   PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0.0);
   PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, 0.0);
   PlotIndexSetDouble(4, PLOT_EMPTY_VALUE, 0.0);
   ArrayInitialize(balance, 0.0);    // принудительная
   ArrayInitialize(equityMax, 0.0);  // инициализация
   ArrayInitialize(equityMaxB, 0.0); // всех
   ArrayInitialize(equityMin, 0.0);  // буферов
   ArrayInitialize(equityMinB, 0.0); // индикатора
   ArraySetAsSeries(balance, true);    // все
   ArraySetAsSeries(clrBalance, true); // буферы
   ArraySetAsSeries(equityMax, true);  // индикатора
   ArraySetAsSeries(equityMaxB, true); // имеют
   ArraySetAsSeries(equityMin, true);  // флаг
   ArraySetAsSeries(equityMinB, true); // AS_SERIES
   IndicatorSetInteger(INDICATOR_DIGITS, 2);
   IndicatorSetString(INDICATOR_SHORTNAME, "Show Money");
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
if(prev_calculated == 0)
  return(rates_total);

  double bal = AccountInfoDouble(ACCOUNT_BALANCE);
  double equity = AccountInfoDouble(ACCOUNT_EQUITY);
  if(rates_total > prev_calculated)
   {
    minEquity = 0;
    maxEquity = 0;
   }
   minEquity = fmin((minEquity == 0 ? AccountInfoDouble(ACCOUNT_BALANCE) : minEquity), equity);
    maxEquity = fmax(maxEquity, equity);
    balance[0] = AccountInfoDouble(ACCOUNT_BALANCE);
    clrBalance[0] = 0.0;
    equityMinB[0] = balance[0];
    equityMin[0] = minEquity;
    equityMaxB[0] = balance[0];
    equityMax[0] = maxEquity;
    if(balance[0] > balance[1])
     clrBalance[0] = 1.0;
    if(balance[0] < balance[1])
     clrBalance[0] = 2.0;
    Comment(PositionsTotal());
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

もう少ししたら動画をアップします、その時は晴れていることでしょう。以前より指先でわかりやすく説明できるようになりました。


ビデオをダウンロードし、解凍していただければと思います。

残念ながら、チャートから外して付けたという事実は記録されていませんが、インジケーターがあり、そして消え、またある、という事実があります。削除して付け直すだけです。

インジケータを再装着した後のデータウィンドウに注意してください。バッファを強制的に初期化しても、そこには空間の残骸が残っています。

ファイル:
00.zip  2614 kb
 
Alexey Viktorov:

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

チャートを1つだけ開いておき、そこにインジケータを置いたり外したりする実験が必要です。そして、端末とOSの情報(端末のログタブ)が必要です。
 
Karputov Vladimir:
1つだけチャートを開いておいて、その上でインジケータを適用したり削除したりする実験をしてみたいのです。そして、端末とOSの情報(端末の「ログ」タブ)が必要です。

1枚のチャートがどう関係するのか?インジケータが1つのチャートにしかないのは物足りない?


を追加しました。

OSがインジケーターの動作に影響を与えることはないと思いますが、システムおよび端末に関する情報を以下に示します。

2016.10.16 20:56:34.904 Terminal        D:\MetaTrader 5\MetaTrader 5
2016.10.16 20:56:34.904 Terminal        Windows 7 Home Premium (x64 based PC), IE 11.00, UAC, AMD FX-4170 Quad-Core Processor , RAM: 10531 / 12255 Mb, HDD: 55167 / 244198 Mb, GMT+03:00
2016.10.16 20:56:34.904 Terminal        MetaTrader 5 build 1455 started (MetaQuotes Software Corp.)
 
Alexey Viktorov:
1枚のチャートがどう関係するのか?インジケータが1つのチャートにしかないのは、十分ではないでしょうか?
  1. 問題を絞り込んでいるところです。
  2. そのような問題はありません。私の構成です。
    2016.10.18 19:09:34.239 Terminal        MetaTrader 5 x64 build 1455 started (MetaQuotes Software Corp.)
    2016.10.18 19:09:34.266 Terminal        Windows 10 Pro (x64 based PC), IE 11.00, UAC, Intel Core i3-3120 M  @ 2.50 GHz, RAM: 3638 / 8077 Mb, HDD: 39824 / 233310 Mb, GMT+02:00
    2016.10.18 19:09:34.266 Terminal        C:\Users\KVN\AppData\Roaming\MetaQuotes\Terminal\038 C9E8FAFF9EA373522ECC6D5159962

 

それで...という状況が生まれつつあります。このコードを追加してください。

  {
//---
   if(prev_calculated==0)
     {
      Print("prev_calculated==0");

      return(rates_total);
     }

   double bal=AccountInfoDouble(ACCOUNT_BALANCE);
 
Karputov Vladimir:
  1. 問題を絞り込んでいます。
  2. この問題はないんです。私の構成です。
    2016.10.18 19:09:34.239 Terminal        MetaTrader 5 x64 build 1455 started (MetaQuotes Software Corp.)
    2016.10.18 19:09:34.266 Terminal        Windows 10 Pro (x64 based PC), IE 11.00, UAC, Intel Core i3-3120 M  @ 2.50 GHz, RAM: 3638 / 8077 Mb, HDD: 39824 / 233310 Mb, GMT+02:00
    2016.10.18 19:09:34.266 Terminal        C:\Users\KVN\AppData\Roaming\MetaQuotes\Terminal\038 C9E8FAFF9EA373522ECC6D5159962

実行を開始したが、インジケータを起動すると1つのバッファにほぼ全部の履歴にペストの数字がある。

インジケータを外し、しばらくして戻すとバッファが空になっている。

後日、取り外しと入れ直しを繰り返す予定です。

 

予備的な結論

1.インジケータは、OnInit()におけるインジケータ・アレイの初期 化に依存することはできません。

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
...
   ArrayInitialize(balance, 0.0);    // принудительная
   ArrayInitialize(equityMax, 0.0);  // инициализация
   ArrayInitialize(equityMaxB, 0.0); // всех
   ArrayInitialize(equityMin, 0.0);  // буферов
   ArrayInitialize(equityMinB, 0.0); // индикатора

...
//---
   return(INIT_SUCCEEDED);
  }

2.インジケータでは、OnCalculate() で配列全体または変更された要素のみを通過させることが義務付けられています。

 
Karputov Vladimir:

それで...という状況が生まれつつあります。このようなコードを追加します。

  {
//---
   if(prev_calculated==0)
     {
      Print("prev_calculated==0");

      return(rates_total);
     }

   double bal=AccountInfoDouble(ACCOUNT_BALANCE);

このように追加されました

Print("prev_calculated = ", prev_calculated);