CAxis *xAxis = graphic.XAxis(); // получаем ось X xAxis.AutoScale(false); // отключаем автомасштабирование xAxis.Min(0); // указываем минимальное значение по X xAxis.Max(10); // указываем максимальное значение по X xAxis.DefaultStep(1); // указываем шаг по X
curve=graphic.CurveAdd(arrX, arrY, CURVE_LINES, "Close"); CAxis *xAxis = graphic.XAxis(); // получаем ось X xAxis.AutoScale(false); // отключаем автомасштабирование xAxis.Min(arrX[size-1]); // указываем минимальное значение по X xAxis.Max(arrX[0]); // указываем максимальное значение по X xAxis.DefaultStep(10*(arrX[0]-arrX[size-1])/size); // указываем шаг по X xAxis.MaxLabels((arrX[0]-arrX[size-1])/xAxis.DefaultStep()+1); // число значений по оси MaxLabels должно быть больше чем (Max-Min)/DefaultStep
ロマン・コノペルコ
2つ目の問題、あるいはヒントを教えてください。
Closeの価格でラインを作ろうとしています。Xではそれに応じて、時間の配列を渡しています。しかし、問題はカーブを作成する際に、勝手に間隔を追加してしまうことです。つまり、時間を均一にして、データのない場所を追加するのです。
つまり、CURVE_TIMESERIESという別のタイプのカーブを作成する必要があることは理解できましたが、それは自動的にステップを見つけ、 Xポイント間にギャップを追加してはいけません。
これは、Xを渡さずにカーブを作成した方法と似ています - そして、すべての値は均等に行く、すべては純粋に配列Xのサイズに縛られています(m_xmax = m_size-1; m_xmin = 0.0; )。
ロマン・コノペルコ
2つ目の問題、あるいはヒントを教えてください。
Closeの価格でラインを作成しようとしています。Xではそれに応じて、時間の配列を渡しています。しかし、問題はカーブを作成する際に、間隔を追加してしまうことです。つまり、時間を均一にして、データのない場所を追加するのです。
つまり、CURVE_TIMESERIESという別のタイプのカーブを作成する必要があることは理解できましたが、それは自動的にステップを見つけ、 Xポイント間にギャップを追加してはいけません。
これは、Xを渡さずに曲線作成を行った方法と類似しています - そして、すべての値が均等になり、すべてが純粋に配列Xのサイズに拘束されます (m_xmax = m_size-1; m_xmin = 0.0; ).
両軸のステップを内蔵アルゴリズムで自動計算します。私の理解では、最大、最小、ステップを自分で設定したいのですね。そのためには、軸のスケーリングをマニュアルモードに切り替えるとよいでしょう。
xAxis.AutoScale(false); // отключаем автомасштабирование
xAxis.Min(0); // указываем минимальное значение по X
xAxis.Max(10); // указываем максимальное значение по X
xAxis.DefaultStep(1); // указываем шаг по X
もう一つ考慮すべきことは、MaxLabels 軸の値の最大許容数で、これは (Max-Min)/DefaultStep よりも大きくなければならず、さもなければステップが変更されます。
両軸のステップを内蔵アルゴリズムで自動計算します。私が理解する限り、最大、最小、ステップを自分で設定したいのですね。そのために、軸のスケーリングをマニュアルモードに切り替えることができます
maxLabels軸も考慮する必要があり、(Max-Min)/DefaultStepより大きくなければなりません、さもなければステップが変更されます。
そう、それは何かというと。
しかし、説明したように、あなたのスケールは均一です。
どう転んでも、Xスケールで、ピクセル単位で座標を狙ってるんでしょ。
まあ、時系列では無理なんですけどね。
取得するものを見る
//+------------------------------------------------------------------+
void OnStart()
{
MqlRates rates[];
CopyRates(Symbol(), Period(), 0, 100, rates);
ArraySetAsSeries(rates, true);
int size=ArraySize(rates);
double arrY[], arrX[];
ArrayResize(arrX, size); ArrayResize(arrY, size);
for(int i=0; i<size; ++i) { arrX[i]=(double)rates[i].time; arrY[i]=rates[i].close; }
CGraphic graphic;
graphic.Create(0, "Rates", 0, 30, 30, 1600, 300);
CCurve* curve=NULL;
//curve=graphic.CurveAdd(arrY, CURVE_LINES, "Close");
curve=graphic.CurveAdd(arrX, arrY, CURVE_LINES, "Close");
CAxis *xAxis = graphic.XAxis(); // получаем ось X
xAxis.AutoScale(false); // отключаем автомасштабирование
xAxis.Min(arrX[size-1]); // указываем минимальное значение по X
xAxis.Max(arrX[0]); // указываем максимальное значение по X
xAxis.DefaultStep(10*(arrX[0]-arrX[size-1])/size); // указываем шаг по X
xAxis.MaxLabels((arrX[0]-arrX[size-1])/xAxis.DefaultStep()+1); // число значений по оси MaxLabels должно быть больше чем (Max-Min)/DefaultStep
curve.Visible(true);
graphic.Redraw();
graphic.Update();
}
で時間を渡さないと、このような動作になります。
作図が正しい
//+------------------------------------------------------------------+
void OnStart()
{
MqlRates rates[];
CopyRates(Symbol(), Period(), 0, 100, rates);
ArraySetAsSeries(rates, true);
int size=ArraySize(rates);
double arrY[];
ArrayResize(arrY, size); ArraySetAsSeries(arrY, size);
for(int i=0; i<size; ++i) arrY[i]=rates[i].close;
CGraphic graphic;
graphic.Create(0, "Rates", 0, 30, 30, 1600, 300);
CCurve* curve=NULL;
curve=graphic.CurveAdd(arrY, CURVE_LINES, "Close");
curve.Visible(true);
graphic.Redraw();
graphic.Update();
}
そう、何かを得たのです。
でも、説明したように、あなたのスケールはフラットなんです。
どのように回しても、Xで拡大縮小し、ピクセル単位で座標を目指します。
まあー時系列でプロットする場合は無理でしょうけど。
取得するものを見る
軸の出力形式を変更する機能は、ほとんどの場合、実装されると思いますが、具体的にどのような形になるかは、まだはっきり言えません。
例の「土日」ですが、これは直線を形成していますね。あなたの例を検証するために、私はそれを修正し、配列のファイルへの書き込みを追加しました。
//+------------------------------------------------------------------+
void OnStart()
{
MqlRates rates[];
CopyRates(Symbol(),Period(),0,100,rates);
ArraySetAsSeries(rates,true);
int size=ArraySize(rates);
double arrY[],arrX[];
datetime arrTime[];
ArrayResize(arrX,size);
ArrayResize(arrY,size);
ArrayResize(arrTime,size);
int handle=FileOpen("result.txt",FILE_WRITE|FILE_TXT);
for(int i=0; i<size;++i)
{
arrTime[i]=rates[i].time;
arrX[i]=(double)rates[i].time;
arrY[i]=rates[i].close;
string str=TimeToString(arrTime[i])+"\t"+DoubleToString(arrY[i],3)+"\n";
FileWriteString(handle,str);
}
FileClose(handle);
CGraphic graphic;
graphic.Create(0,"Rates",0,30,30,1080,380);
CCurve *curve=graphic.CurveAdd(arrX,arrY,CURVE_LINES,"Close");
double min = arrX[ArrayMinimum(arrX)];
double max = arrX[ArrayMaximum(arrX)];
double step=(max-min)/10;
CAxis *xAxis = graphic.XAxis(); // получаем ось X
xAxis.AutoScale(false); // отключаем автомасштабирование
xAxis.Min(min); // указываем минимальное значение по X
xAxis.Max(max); // указываем максимальное значение по X
xAxis.DefaultStep(step); // указываем шаг по X
curve.Visible(true);
graphic.Redraw();
graphic.Update();
}
そしてOpenOfficeでプロットした。
このグラフも直線を含んでいるので、データ(配列X、Y)に埋め込まれている。コメント#24に あるようなグラフを作るには、入力データを手動で編集する必要があります(例えば、週末を削除する)。
軸の出力形式を変更する機能は実装されそうですが、具体的にどのような形で実装されるかは、はっきり言えません。
朗報です、ありがとうございます。
先ほども言いましたが、正式なビルドを待つ必要はなく、ここにテスト用のクラスを投稿してください。朗報です、ありがとうございます。
先ほども言いましたが、ビルドオフィスを待たずに、ここにテスト用のクラスを置くことができます。{
AXIS_TYPE_DOUBLE,
AXIS_TYPE_DATETIME,
AXIS_TYPE_CUSTOM,
};
念のため、添付ファイルにはライブラリの全ファイルを入れておきました。
servicedeskへのメッセージについてですが、確かにX配列には土日がありません。だから、データを修正する必要があるとは正しく言っていないのです。
しかし、AXIS_TYPE_CUSTOMを使用することで、問題を解決することができます。
double arrX[];
double arrY[];
//---
string TimeFirmat(double x)
{
return(TimeToString((datetime)arrX[ArraySize(arrX)-(int)x-1]));
}
//+------------------------------------------------------------------+
void OnStart()
{
MqlRates rates[];
CopyRates(Symbol(),Period(),0,100,rates);
ArraySetAsSeries(rates,true);
int size=ArraySize(rates);
ArrayResize(arrX,size);
ArrayResize(arrY,size);
for(int i=0; i<size;++i)
{
arrX[i]=(double)rates[i].time;
arrY[i]=rates[i].close;
}
CGraphic graphic;
graphic.Create(0,"Rates",0,30,30,780,380);
CCurve *curve=graphic.CurveAdd(arrY,CURVE_LINES,"Close");
CAxis *xAxis=graphic.XAxis(); // получаем ось X
xAxis.AutoScale(false);
xAxis.Type(AXIS_TYPE_CUSTOM);
xAxis.ValuesFunctionFormat(TimeFirmat);
xAxis.DefaultStep(20.0);
curve.Visible(true);
graphic.Redraw();
graphic.Update();
}
//+------------------------------------------------------------------+
結果
しかし、AXIS_TYPE_CUSTOMを使用するだけで問題を解決することができます。
Graphic.mqhのファイルをざっと見てみました。
すべての機能を仮想化 しないままにしておくことにしたのでしょうか?
OKです。
せめて ***Plot 関数 (HistogramPlot, LinesPlot, etc.) を仮想 にできないでしょうか?
その「デザイン」能力が十分でないため(塗りつぶし時のグラデーションやレンダリング時の多色化)。
Graphic.mqhのファイルをざっと見てみました。
すべての機能を仮想化 しないままにしておくことにしたのでしょうか?
OKです。
せめて ***Plot 関数 (HistogramPlot, LinesPlot, etc.) を仮想 にできないでしょうか?
その「デザイン」能力が十分でないため(塗りつぶし時のグラデーションやレンダリング時の多色化)。