初心者の方からの質問 MQL5 MT5 MetaTrader 5 - ページ 919 1...912913914915916917918919920921922923924925926...1504 新しいコメント Igor Makanu 2018.09.04 22:04 #9181 Artyom Trishkin:指標の計算は、最初から最後まで(直近の過去データから直近の現在データまで)です。これは、時系列でいうところのインデックス化の表れです。そのため、配列はそれに応じてインデックスを付けなければなりませんが、それがあなたの持っているものです。 どうしたんですか?MQL4からMQL5に移植したのと同じように動作しますが、ArraySetAsSeries()のためにコードが醜いことがわかりましたので、質問させて いただきました。 以下は、両方のコードです。 MT5用のインジケーターの書き方を教えてください。- 私のコードはいい加減なんです!フルストップ))) ZSZはMT5用のインジケータの書き方を覚えておらず、座ってヘルプを使って40分で書き直したが、結果は......。imho、イマイチ((! ファイル: PTL.mq4 8 kb PTL.mq5 13 kb Artyom Trishkin 2018.09.04 22:20 #9182 Igor Makanu:しかし、ArraySetAsSeries()のためにコードが醜いことがわかりましたので、私は質問 しました。 以下は、両方のコードです。 MT5用のインジケーターの書き方を教えてください。- 私のコードはいい加減なんです!フルストップ)))ループを反転させるときは、必ず配列を時系列にする必要があります。そうしないと、ループ内のバッファのインデックスと必要なデータのインデックスが一致しません。インジケータバッファの配列のループインデックスは先頭から最後へ、open[], high[], low[], close[] などでは最後から先頭へ移動します。あるいは、ループを逆にして、配列の open[], high[], low[], close[] と残りをバッファのインデックス付けと一致させることもできますが、これはより複雑です。 寓話でわかりやすくしてほしいなら、こんな寓話があります。 あなたは線路の前に立って、2台の電車を見ています。一方向に進むか、両方左から右に進むか(ArraySetAsSeries(array,true)-1本目、限界から0へのループ-2本目)です。 あるいは互いに向かっていく - (ArraySetAsSeries(array,false) - 右から左へ - 第一列車、そして限界から0へのループ - 左から右へ - 第二列車) そして、そうです:私はコードに目を通しませんでした - ダウンロード、保存(フォーラムからすでに多くの不要なコードがあります)、それらを互いに比較することを望んでいません...。 メッセージの中に、1番目と2番目のコードを入れておけば、一度に何が何番目なのかが分かるので楽なんですけどね。 Igor Makanu 2018.09.04 22:28 #9183 Artyom Trishkin:あるいは、ループを反転させて、配列 open[]、high[]、low[]、close[]などのインデックスに 合わせるか、どちらが難しいでしょう。今日は一晩中リバースしてました、我慢の限界です(((^^;) 私が問題を理解する限りでは - MT5では、インジケータ・バッファに割り当てられた配列は、デフォルトで左から右へのインデックスが付けられています。 - MT5の時系列でOnCalculate()から利用できるopen[], high[], low[], close[] は常に右から左へのインデックスで渡されます。 - すなわち、ステップ 1 と 2 に基づいて、ヒストリーの終わりからゼロバーまでの指標を計算するために a) またはバッファ配列のインデックスを再指定する。 b) あるいは,配列の要素を左から右へ再計算し,別のループで右から左へ再計算するループを作成する. for(i=limit;i>=0;i--) { BufBarsBuffer1[limit - i] = open[i]; ... } 選択肢a) - 私のソースでは実装されている,選択肢b) - 余分な計算をする意味がわからない。 のソースになります。 MT5です。 //+------------------------------------------------------------------+ //| Perfect_Trend_Lines.mq5 | //| IgorM | //| | //+------------------------------------------------------------------+ #property version "1.00" #property indicator_chart_window #property indicator_buffers 9 #property indicator_plots 5 //--- plot BufBars #property indicator_label1 "BufBars" #property indicator_type1 DRAW_COLOR_BARS #property indicator_color1 clrRed,clrAqua,clrNONE #property indicator_style1 STYLE_SOLID #property indicator_width1 3 //--- plot BufASELL #property indicator_label2 "BufASELL" #property indicator_type2 DRAW_ARROW #property indicator_color2 clrBlue #property indicator_style2 STYLE_SOLID #property indicator_width2 5 //--- plot BufABUY #property indicator_label3 "BufABUY" #property indicator_type3 DRAW_ARROW #property indicator_color3 clrRed #property indicator_style3 STYLE_SOLID #property indicator_width3 5 //--- plot BufLSELL #property indicator_label4 "BufLSELL" #property indicator_type4 DRAW_LINE #property indicator_color4 clrBlue #property indicator_style4 STYLE_SOLID #property indicator_width4 2 //--- plot BufLBUY #property indicator_label5 "BufLBUY" #property indicator_type5 DRAW_LINE #property indicator_color5 clrRed #property indicator_style5 STYLE_SOLID #property indicator_width5 2 //--- input parameters input int SlowLength = 7; //Slow length input int SlowPipDisplace = 0; //Slow pip displace input int FastLength = 3; //Fast length input int FastPipDisplace = 0; //Fast pip displace //--- indicator buffers double BufBarsBuffer1[]; double BufBarsBuffer2[]; double BufBarsBuffer3[]; double BufBarsBuffer4[]; double BufBarsColors[]; double BufASELLBuffer[]; double BufABUYBuffer[]; double BufLSELLBuffer[]; double BufLBUYBuffer[]; static int trend=0; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,BufBarsBuffer1,INDICATOR_DATA); SetIndexBuffer(1,BufBarsBuffer2,INDICATOR_DATA); SetIndexBuffer(2,BufBarsBuffer3,INDICATOR_DATA); SetIndexBuffer(3,BufBarsBuffer4,INDICATOR_DATA); SetIndexBuffer(4,BufBarsColors,INDICATOR_COLOR_INDEX); SetIndexBuffer(5,BufASELLBuffer,INDICATOR_DATA); SetIndexBuffer(6,BufABUYBuffer,INDICATOR_DATA); SetIndexBuffer(7,BufLSELLBuffer,INDICATOR_DATA); SetIndexBuffer(8,BufLBUYBuffer,INDICATOR_DATA); for(int i=0;i<9;i++) { PlotIndexSetInteger(i,PLOT_DRAW_BEGIN,FastLength+1); PlotIndexSetDouble(i,PLOT_EMPTY_VALUE,0.0); } ArraySetAsSeries(BufBarsBuffer1,true); ArraySetAsSeries(BufBarsBuffer2,true); ArraySetAsSeries(BufBarsBuffer3,true); ArraySetAsSeries(BufBarsBuffer4,true); ArraySetAsSeries(BufBarsColors,true); ArraySetAsSeries(BufABUYBuffer,true); ArraySetAsSeries(BufASELLBuffer,true); ArraySetAsSeries(BufLBUYBuffer,true); ArraySetAsSeries(BufLSELLBuffer,true); //--- setting a code from the Wingdings charset as the property of PLOT_ARROW PlotIndexSetInteger(1,PLOT_ARROW,234); PlotIndexSetInteger(2,PLOT_ARROW,233); PlotIndexSetInteger(1,PLOT_ARROW_SHIFT,-20); PlotIndexSetInteger(2,PLOT_ARROW_SHIFT,20); trend=0; //--- 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[]) { //--- int i,limit; double thigh1,tlow1,thigh2,tlow2,trendUp,trendDn; ArraySetAsSeries(open,true); ArraySetAsSeries(high,true); ArraySetAsSeries(low,true); ArraySetAsSeries(close,true); if(prev_calculated==0) { limit=rates_total-1; BufLSELLBuffer[limit]=high[limit]; BufLBUYBuffer[limit]=low[limit]; limit--; } else limit=rates_total-prev_calculated+1; for(i=limit;i>=0;i--) { thigh1= high[iHighest(NULL,0,MODE_HIGH,SlowLength,i)]+SlowPipDisplace * _Point; tlow1 = low[iLowest(NULL,0,MODE_LOW,SlowLength,i)]-SlowPipDisplace * _Point; thigh2= high[iHighest(NULL,0,MODE_HIGH,FastLength,i)]+FastPipDisplace * _Point; tlow2 = low[iLowest(NULL,0,MODE_LOW,FastLength,i)]-FastPipDisplace * _Point; if(close[i]>BufLBUYBuffer[i+1]) trendUp=tlow1; else trendUp=thigh1; if(close[i]>BufLSELLBuffer[i+1]) trendDn=tlow2; else trendDn=thigh2; BufLSELLBuffer[i]= trendDn; BufLBUYBuffer[i] = trendUp; BufBarsBuffer1[i] = 0.0; BufBarsBuffer2[i] = 0.0; BufBarsBuffer3[i] = 0.0; BufBarsBuffer4[i] = 0.0; BufBarsColors[i] = 2; if(close[i]<trendUp && close[i]<trendDn) { BufBarsBuffer1[i] = open[i]; BufBarsBuffer2[i] = high[i]; BufBarsBuffer3[i] = low[i]; BufBarsBuffer4[i] = close[i]; BufBarsColors[i] = 0; } if(close[i]>trendUp && close[i]>trendDn) { BufBarsBuffer1[i] = open[i]; BufBarsBuffer2[i] = high[i]; BufBarsBuffer3[i] = low[i]; BufBarsBuffer4[i] = close[i]; BufBarsColors[i] = 1; } if(close[i]>trendUp && close[i]>trendDn && trend!=1) { BufABUYBuffer[i]=trendDn; BufASELLBuffer[i]=0.0; trend=1; } if(close[i]<trendUp && close[i]<trendDn && trend!=2) { BufASELLBuffer[i]=trendUp; BufABUYBuffer[i]=0.0; trend=2; } } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+MT4です。 //+------------------------------------------------------------------+ //| PerfecTrend Lines.mq4 | //| Copyright © 2005-2007, MetaQuotes Software Corp. | //+------------------------------------------------------------------+ #property copyright "Copyright © 2007, MetaQuotes Software Corp." #property indicator_chart_window #property indicator_buffers 6 #property indicator_color1 Red #property indicator_color2 Blue #property indicator_color3 Red #property indicator_color4 Aqua #property indicator_color5 Blue #property indicator_color6 Red extern int SlowLength = 7; // Slow length extern int SlowPipDisplace = 0; // Slow pip displace extern int FastLength = 3; // Fast length extern int FastPipDisplace = 0; // Fast pip displace double Buf_NTLine1[],Buf_NTLine2[],Buf_NTBar1[],Buf_NTBar2[],Buf_NTSig1[],Buf_NTSig2[]; static int trend=0; //+------------------------------------------------------------------+ int init() { IndicatorBuffers(6); IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)); SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,2); SetIndexBuffer(0,Buf_NTLine1); SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,2); SetIndexBuffer(1,Buf_NTLine2); SetIndexStyle(2,DRAW_HISTOGRAM,STYLE_SOLID,2); SetIndexBuffer(2,Buf_NTBar1); SetIndexStyle(3,DRAW_HISTOGRAM,STYLE_SOLID,2); SetIndexBuffer(3,Buf_NTBar2); SetIndexStyle(4,DRAW_ARROW,STYLE_DASH,3); SetIndexArrow(4,108); SetIndexBuffer(4,Buf_NTSig1); SetIndexStyle(5,DRAW_ARROW,STYLE_DASH,3); SetIndexArrow(5,108); SetIndexBuffer(5,Buf_NTSig2); IndicatorShortName("NeuroTrend"); SetIndexLabel(0,"NTLine1"); SetIndexLabel(1,"NTLine2"); SetIndexLabel(2,"NTBar1"); SetIndexLabel(3,"NTBar2"); SetIndexLabel(4,"NTSig1"); SetIndexLabel(5,"NTSig2"); SetIndexDrawBegin(0,FastLength+1); SetIndexDrawBegin(1,FastLength+1); SetIndexDrawBegin(2,FastLength+1); SetIndexDrawBegin(3,FastLength+1); SetIndexDrawBegin(4,FastLength+1); SetIndexDrawBegin(5,FastLength+1); trend=0; return (0); } //+------------------------------------------------------------------+ int deinit() { return (0); } //+------------------------------------------------------------------+ int start() { int i,limit; double thigh1,tlow1,thigh2,tlow2,trendA,trendB,trendUP,trendDN; if(Bars <= FastLength) return (0); if(IndicatorCounted()==0) limit=Bars-1; if(IndicatorCounted()>0) limit=Bars-IndicatorCounted()-1; for(i=limit;i>=0;i--) { thigh1= High[iHighest(NULL,0,MODE_HIGH,SlowLength,i)]+SlowPipDisplace * Point; tlow1 = Low[iLowest(NULL,0,MODE_LOW,SlowLength,i)]-SlowPipDisplace * Point; thigh2= High[iHighest(NULL,0,MODE_HIGH,FastLength,i)]+FastPipDisplace * Point; tlow2 = Low[iLowest(NULL,0,MODE_LOW,FastLength,i)]-FastPipDisplace * Point; if(Close[i] > Buf_NTLine1[i+1]) trendA = tlow1; else trendA = thigh1; if(Close[i] > Buf_NTLine2[i+1]) trendB = tlow2; else trendB = thigh2; Buf_NTLine1[i] = trendA; Buf_NTLine2[i] = trendB; trendUP = 0.0; trendDN = 0.0; if(Close[i] < trendA && Close[i] < trendB) { trendUP = High[i]; trendDN = Low[i]; } if(Close[i] > trendA && Close[i] > trendB) { trendUP = Low[i]; trendDN = High[i];} Buf_NTBar1[i] = trendUP; Buf_NTBar2[i] = trendDN; if(Close[i] > trendB && Close[i] > trendA && trend != 1) { Buf_NTSig1[i] = trendB; Buf_NTSig2[i] = EMPTY_VALUE; trend = 1; } if(Close[i] < trendB && Close[i] < trendA && trend != 2) { Buf_NTSig2[i] = trendB; Buf_NTSig1[i] = EMPTY_VALUE; trend = 2; } } return (0); } //+------------------------------------------------------------------+ Artyom Trishkin 2018.09.04 22:36 #9184 Igor Makanu:今夜は徹夜でポチポチしてましたが、我慢の限界です(((^^;) 私が理解する限りでは、この問題は - MT5では、インジケータ・バッファに割り当てられた配列は、デフォルトで左から右へのインデックスが付けられています。 - MT5の時系列でOnCalculate()から利用できるopen[], high[], low[], close[] は常に右から左へのインデックスで渡されます。 - すなわち、ステップ 1 と 2 に基づいて、ヒストリーの終わりからゼロバーまでの指標を計算するために a) またはバッファ配列のインデックスを再指定する。 b) あるいは,配列の要素を左から右へ再計算し,別のループで右から左へ再計算するループを作成する. つまり、私の質問に対する美しい解決策はないのでしょうか? 変形a) - 私のソースでは実装されています、変形b) - 余分な計算をする意味がわかりません。すべての配列は右から左へのインデックスを持つ。したがって、左から右へのループ(左から右、つまり限界から0まで)に完全に準拠するためには、使用するすべての配列を必要なインデックスに 設定する必要があります:バッファは OnInit()で、使用するタイムサーバはOnCalculate()で設定します。 あるいは、0からリミットまでのサイクルを行う。これは、mql4からmql5への移植の際に、必ずしも容易ではない。 したがって、この場合は ArraySetAsSeries() オプションの方がよいでしょう。 Igor Makanu 2018.09.04 22:48 #9185 Artyom Trishkin:すべての配列は右から左へのインデックスを持つ。したがって、左から右へのループに完全に準拠するために(そしてそれは限界から0まで左から右にある)、使用されるすべての配列を必要なインデックスに 設定する必要があります:バッファは OnInit()で、使用するタイムサーバ - OnCalculate()でです。 あるいは、0からリミットまでのサイクルを行う必要があり、mql4をmql5に移植した場合、必ずしも容易ではありません。 そのため、この場合はArraySetAsSeries()メソッドの方が効果的です。見て、あなたのコードからすべてのArraySetAsSeries() を削除し( 最初の行のInit()と OnCalculate()のトップで)、ループを 修正してください。 for(i=0;i<limit;i++)理屈では全部合うはずなのに、違う!チャートの形が違う!これが解せない。 ファイル: 1.jpg 747 kb Artyom Trishkin 2018.09.04 22:57 #9186 Igor Makanu:見て、私は私のコードからすべてのArraySetAsSeries() を削除し(最初の 行のInit()と OnCalculate()の中で)、ループを修正 した。 for(i=0;i<limit;i++)理屈では全部合うはずなのに、違うんです!チャートの形が違っていて、そこがわからないんです。もっと複雑なんです。論理を変えなければならないのです。ループを反転させるだけではダメなんです。 小さな例を挙げますと、コードの中に Buf_NTLine1[i+1]) 配列のインデックスが 異なる場合、i+1インデックスはどこに行くのでしょうか? しかも、たくさんあるんです。IHighest() - 開始と番号。どこからがある指標で、どこからが別の指標なのか。 などなど・・・。 Igor Makanu 2018.09.04 23:09 #9187 Artyom Trishkin: とたくさんあります。IHighest() - 開始と終了の数...片方のインデックスともう片方のインデックスはどこから始まるのでしょうか?oh man!その通り!よくやった!!そう、そこが厄介なんだ!!(笑)。 ああ...MT5では多くの違いがあり、プログラマーの頭の中には多くのチェックと様々な注意事項が......。 少し前に見たときは、MT5ではInit() で全てが正しく初期化 されるとは限らないというメッセージがあり、タイムフレームの準備が出来ていなくてもInit()が終了して しまうことがあるようです。 私は昨日バグを見た:MT5でこの指標は、タイムフレームを切り替える場合、時には指標のバッファが 空にならないことがあります - それは古い値がOnCalculate()で指標の配列の各要素に特定の値を割り当てない場合は残っているようだ、私はInit()でArrayInitialize(アレンジ、0.0)を置くことを 試みた - それはあまりにも、その後ではない動作します...。 私が正しく理解している限りでは - MT5で、Init() の初期化時に、インジケータのバッファが自動的に初期化されない?(MT4ではバッファに何も残っていなかったと記憶しています) - MT5のInit() において、ヒストリがロードされていない場合、バッファアレイのサイズが不明である可能性があります。 Artyom Trishkin 2018.09.05 00:18 #9188 Igor Makanu:ちくしょう! そうだ! よくやった! そう、それが楽しいんだ!!!! ああ...MT5ではいろいろな違いがあって、プログラマーがチェックしたり、いろいろな注意点があるんです...。 少し前にこのメッセージを見たとき、MT5ではInit() で全てが正しく初期化さ れるとは限らないようで、タイムフレームの準備が出来ていなくてもInit()が終了して しまうことがあるようです。 私は昨日バグを見た:MT5でこの指標は、タイムフレームを切り替える場合、時には指標のバッファが 空にならないことがあります - それは古い値がOnCalculate()で指標の配列の各要素に特定の値を割り当てない場合は残っているようだ、私はInit()でArrayInitialize(アレンジ、0.0)を置くことを 試みた - それはあまりにも、その後ではない動作します...。 私が正しく理解している限りでは - MT5で、Init() の初期化時に、インジケータのバッファが自動的に初期化されない?(MT4ではバッファに何も残っていなかったと記憶しています) - MT5のInit() において、ヒストリがロードされていない場合、バッファアレイのサイズが不明である可能性があります。//+------------------------------------------------------------------+ //| PerfecTrend Lines.mq5 | //| Copyright 2018, MetaQuotes Software Corp. | //| https://mql5.com/ru/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2018, MetaQuotes Software Corp." #property link "https://mql5.com/ru/users/artmedia70" #property version "1.00" #property indicator_chart_window #property indicator_buffers 9 #property indicator_plots 5 //--- plot Top #property indicator_label1 "Top" #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot Bottom #property indicator_label2 "Bottom" #property indicator_type2 DRAW_LINE #property indicator_color2 clrBlue #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- plot Candles #property indicator_label3 "Open;High;Low;Close" #property indicator_type3 DRAW_COLOR_CANDLES #property indicator_color3 clrDodgerBlue,clrOrangeRed,clrDarkGray #property indicator_style3 STYLE_SOLID #property indicator_width3 1 //--- plot ArrowUP #property indicator_label4 "ArrowUP" #property indicator_type4 DRAW_ARROW #property indicator_color4 clrRed #property indicator_style4 STYLE_SOLID #property indicator_width4 1 //--- plot ArrowDN #property indicator_label5 "ArrowDN" #property indicator_type5 DRAW_ARROW #property indicator_color5 clrBlue #property indicator_style5 STYLE_SOLID #property indicator_width5 1 //--- input parameters input uint InpPeriodSlow = 7; // Slow length input uint InpDistanceSlow = 0; // Slow pip displace input uint InpPeriodFast = 3; // Fast length input uint InpDistanceFast = 0; // Fast pip displace //--- indicator buffers double BufferTop[]; double BufferBottom[]; double BufferCandlesOpen[]; double BufferCandlesHigh[]; double BufferCandlesLow[]; double BufferCandlesClose[]; double BufferColors[]; double BufferArrowUP[]; double BufferArrowDN[]; //--- global variables int period_slow; int period_fast; int period_max; double distance_slow; double distance_fast; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- set global variables period_fast=int(InpPeriodFast<1 ? 1 : InpPeriodFast); period_slow=int(InpPeriodSlow<1 ? 1 : InpPeriodSlow); period_max=fmax(period_fast,period_slow); distance_fast=InpDistanceFast*Point(); distance_slow=InpDistanceSlow*Point(); //--- indicator buffers mapping SetIndexBuffer(0,BufferTop,INDICATOR_DATA); SetIndexBuffer(1,BufferBottom,INDICATOR_DATA); SetIndexBuffer(2,BufferCandlesOpen,INDICATOR_DATA); SetIndexBuffer(3,BufferCandlesHigh,INDICATOR_DATA); SetIndexBuffer(4,BufferCandlesLow,INDICATOR_DATA); SetIndexBuffer(5,BufferCandlesClose,INDICATOR_DATA); SetIndexBuffer(6,BufferColors,INDICATOR_COLOR_INDEX); SetIndexBuffer(7,BufferArrowUP,INDICATOR_DATA); SetIndexBuffer(8,BufferArrowDN,INDICATOR_DATA); //--- setting a code from the Wingdings charset as the property of PLOT_ARROW PlotIndexSetInteger(3,PLOT_ARROW,108); PlotIndexSetInteger(4,PLOT_ARROW,108); //--- setting indicator parameters IndicatorSetString(INDICATOR_SHORTNAME,"NeuroTrend"); IndicatorSetInteger(INDICATOR_DIGITS,Digits()); //--- setting buffer arrays as timeseries ArraySetAsSeries(BufferTop,true); ArraySetAsSeries(BufferBottom,true); ArraySetAsSeries(BufferCandlesOpen,true); ArraySetAsSeries(BufferCandlesHigh,true); ArraySetAsSeries(BufferCandlesLow,true); ArraySetAsSeries(BufferCandlesClose,true); ArraySetAsSeries(BufferColors,true); ArraySetAsSeries(BufferArrowUP,true); ArraySetAsSeries(BufferArrowDN,true); //--- 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[]) { //--- Установка массивов буферов как таймсерий ArraySetAsSeries(open,true); ArraySetAsSeries(high,true); ArraySetAsSeries(low,true); ArraySetAsSeries(close,true); //--- Проверка и расчёт количества просчитываемых баров if(rates_total<fmax(period_max,4)) return 0; int limit=rates_total-prev_calculated; if(limit>1) { limit=rates_total-period_max-1; ArrayInitialize(BufferTop,EMPTY_VALUE); ArrayInitialize(BufferBottom,EMPTY_VALUE); ArrayInitialize(BufferCandlesOpen,EMPTY_VALUE); ArrayInitialize(BufferCandlesHigh,EMPTY_VALUE); ArrayInitialize(BufferCandlesLow,EMPTY_VALUE); ArrayInitialize(BufferCandlesClose,EMPTY_VALUE); ArrayInitialize(BufferArrowUP,EMPTY_VALUE); ArrayInitialize(BufferArrowDN,EMPTY_VALUE); } //--- for(int i=limit; i>=0 && !IsStopped(); i--) { int bhs=Highest(period_slow,i); int bls=Lowest(period_slow,i); int bhf=Highest(period_fast,i); int blf=Lowest(period_fast,i); if(bhs==WRONG_VALUE || bls==WRONG_VALUE || bhf==WRONG_VALUE || blf==WRONG_VALUE) continue; double thigh1=high[bhs]+distance_slow; double tlow1=low[bls]-distance_slow; double thigh2=high[bhf]+distance_fast; double tlow2=low[blf]-distance_fast; double trendA=(close[i]>BufferTop[i+1] ? tlow1 : thigh1); double trendB=(close[i]>BufferBottom[i+1] ? tlow2 : thigh2); BufferTop[i]=trendA; BufferBottom[i]=trendB; double trendUP=0; double trendDN=0; BufferCandlesOpen[i]=open[i]; BufferCandlesHigh[i]=high[i]; BufferCandlesLow[i]=low[i]; BufferCandlesClose[i]=close[i]; BufferColors[i]=2; if(close[i]<trendA && close[i]<trendB) { BufferColors[i]=1; trendUP=high[i]; trendDN=low[i]; } else if(close[i]>trendA && close[i]>trendB) { BufferColors[i]=0; trendUP=low[i]; trendDN=high[i]; } else { BufferCandlesOpen[i]=EMPTY_VALUE; BufferCandlesHigh[i]=EMPTY_VALUE; BufferCandlesLow[i]=EMPTY_VALUE; BufferCandlesClose[i]=EMPTY_VALUE; } static int trend=0; BufferArrowUP[i]=BufferArrowDN[i]=EMPTY_VALUE; if(close[i]>trendB && close[i]>trendA && trend!=1) { BufferArrowDN[i]=trendB; BufferArrowUP[i]=EMPTY_VALUE; trend=1; } if(close[i]<trendB && close[i]<trendA && trend!=2) { BufferArrowUP[i]=trendB; BufferArrowDN[i]=EMPTY_VALUE; trend=2; } } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| Возвращает индекс максимального значения таймсерии High | //+------------------------------------------------------------------+ int Highest(const int count,const int start,const bool as_series=true) { double array[]; ArraySetAsSeries(array,as_series); return(CopyHigh(NULL,PERIOD_CURRENT,start,count,array)==count ? ArrayMaximum(array)+start : WRONG_VALUE); } //+------------------------------------------------------------------+ //| Возвращает индекс минимального значения таймсерии Low | //+------------------------------------------------------------------+ int Lowest(const int count,const int start,const bool as_series=true) { double array[]; ArraySetAsSeries(array,as_series); return(CopyLow(NULL,PERIOD_CURRENT,start,count,array)==count ? ArrayMinimum(array)+start : WRONG_VALUE); } //+------------------------------------------------------------------+ 理屈はよくわからなかった。 Artyom Trishkin 2018.09.05 00:35 #9189 Artyom Trishkin: 理屈はよくわからなかった。これは正しい方法です。エントリーポイントを最大/最小価格に置くのではなく、始値で 置くのが良いのです。 //+------------------------------------------------------------------+ //| PerfecTrend Lines.mq5 | //| Copyright 2018, MetaQuotes Software Corp. | //| https://mql5.com/ru/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2018, MetaQuotes Software Corp." #property link "https://mql5.com/ru/users/artmedia70" #property version "1.00" #property indicator_chart_window #property indicator_buffers 9 #property indicator_plots 5 //--- plot Top #property indicator_label1 "Top" #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot Bottom #property indicator_label2 "Bottom" #property indicator_type2 DRAW_LINE #property indicator_color2 clrBlue #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- plot Candles #property indicator_label3 "Open;High;Low;Close" #property indicator_type3 DRAW_COLOR_CANDLES #property indicator_color3 clrDodgerBlue,clrOrangeRed,clrDarkGray #property indicator_style3 STYLE_SOLID #property indicator_width3 1 //--- plot ArrowUP #property indicator_label4 "ArrowUP" #property indicator_type4 DRAW_ARROW #property indicator_color4 clrRed #property indicator_style4 STYLE_SOLID #property indicator_width4 1 //--- plot ArrowDN #property indicator_label5 "ArrowDN" #property indicator_type5 DRAW_ARROW #property indicator_color5 clrBlue #property indicator_style5 STYLE_SOLID #property indicator_width5 1 //--- input parameters input uint InpPeriodSlow = 7; // Slow length input uint InpDistanceSlow = 0; // Slow pip displace input uint InpPeriodFast = 3; // Fast length input uint InpDistanceFast = 0; // Fast pip displace //--- indicator buffers double BufferTop[]; double BufferBottom[]; double BufferCandlesOpen[]; double BufferCandlesHigh[]; double BufferCandlesLow[]; double BufferCandlesClose[]; double BufferColors[]; double BufferArrowUP[]; double BufferArrowDN[]; //--- global variables int period_slow; int period_fast; int period_max; double distance_slow; double distance_fast; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- set global variables period_fast=int(InpPeriodFast<1 ? 1 : InpPeriodFast); period_slow=int(InpPeriodSlow<1 ? 1 : InpPeriodSlow); period_max=fmax(period_fast,period_slow); distance_fast=InpDistanceFast*Point(); distance_slow=InpDistanceSlow*Point(); //--- indicator buffers mapping SetIndexBuffer(0,BufferTop,INDICATOR_DATA); SetIndexBuffer(1,BufferBottom,INDICATOR_DATA); SetIndexBuffer(2,BufferCandlesOpen,INDICATOR_DATA); SetIndexBuffer(3,BufferCandlesHigh,INDICATOR_DATA); SetIndexBuffer(4,BufferCandlesLow,INDICATOR_DATA); SetIndexBuffer(5,BufferCandlesClose,INDICATOR_DATA); SetIndexBuffer(6,BufferColors,INDICATOR_COLOR_INDEX); SetIndexBuffer(7,BufferArrowUP,INDICATOR_DATA); SetIndexBuffer(8,BufferArrowDN,INDICATOR_DATA); //--- setting a code from the Wingdings charset as the property of PLOT_ARROW PlotIndexSetInteger(3,PLOT_ARROW,108); PlotIndexSetInteger(4,PLOT_ARROW,108); //--- setting indicator parameters IndicatorSetString(INDICATOR_SHORTNAME,"NeuroTrend"); IndicatorSetInteger(INDICATOR_DIGITS,Digits()); //--- setting buffer arrays as timeseries ArraySetAsSeries(BufferTop,true); ArraySetAsSeries(BufferBottom,true); ArraySetAsSeries(BufferCandlesOpen,true); ArraySetAsSeries(BufferCandlesHigh,true); ArraySetAsSeries(BufferCandlesLow,true); ArraySetAsSeries(BufferCandlesClose,true); ArraySetAsSeries(BufferColors,true); ArraySetAsSeries(BufferArrowUP,true); ArraySetAsSeries(BufferArrowDN,true); //--- 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[]) { //--- Установка массивов буферов как таймсерий ArraySetAsSeries(open,true); ArraySetAsSeries(high,true); ArraySetAsSeries(low,true); ArraySetAsSeries(close,true); //--- Проверка и расчёт количества просчитываемых баров if(rates_total<fmax(period_max,4)) return 0; int limit=rates_total-prev_calculated; if(limit>1) { limit=rates_total-period_max-1; ArrayInitialize(BufferTop,EMPTY_VALUE); ArrayInitialize(BufferBottom,EMPTY_VALUE); ArrayInitialize(BufferCandlesOpen,EMPTY_VALUE); ArrayInitialize(BufferCandlesHigh,EMPTY_VALUE); ArrayInitialize(BufferCandlesLow,EMPTY_VALUE); ArrayInitialize(BufferCandlesClose,EMPTY_VALUE); ArrayInitialize(BufferArrowUP,EMPTY_VALUE); ArrayInitialize(BufferArrowDN,EMPTY_VALUE); } //--- for(int i=limit; i>=0 && !IsStopped(); i--) { int bhs=Highest(period_slow,i); int bls=Lowest(period_slow,i); int bhf=Highest(period_fast,i); int blf=Lowest(period_fast,i); if(bhs==WRONG_VALUE || bls==WRONG_VALUE || bhf==WRONG_VALUE || blf==WRONG_VALUE) continue; double thigh1=high[bhs]+distance_slow; double tlow1=low[bls]-distance_slow; double thigh2=high[bhf]+distance_fast; double tlow2=low[blf]-distance_fast; double trendA=(close[i]>BufferTop[i+1] ? tlow1 : thigh1); double trendB=(close[i]>BufferBottom[i+1] ? tlow2 : thigh2); BufferTop[i]=trendA; BufferBottom[i]=trendB; BufferCandlesOpen[i]=open[i]; BufferCandlesHigh[i]=high[i]; BufferCandlesLow[i]=low[i]; BufferCandlesClose[i]=close[i]; BufferColors[i]=2; if(close[i]<trendA && close[i]<trendB) BufferColors[i]=1; else if(close[i]>trendA && close[i]>trendB) BufferColors[i]=0; else { BufferCandlesOpen[i]=EMPTY_VALUE; BufferCandlesHigh[i]=EMPTY_VALUE; BufferCandlesLow[i]=EMPTY_VALUE; BufferCandlesClose[i]=EMPTY_VALUE; } static int trend=0; BufferArrowUP[i]=BufferArrowDN[i]=EMPTY_VALUE; if(close[i]>trendB && close[i]>trendA && trend!=1) { BufferArrowDN[i]=open[i]; BufferArrowUP[i]=EMPTY_VALUE; trend=1; } if(close[i]<trendB && close[i]<trendA && trend!=2) { BufferArrowUP[i]=open[i]; BufferArrowDN[i]=EMPTY_VALUE; trend=2; } } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| Возвращает индекс максимального значения таймсерии High | //+------------------------------------------------------------------+ int Highest(const int count,const int start,const bool as_series=true) { double array[]; ArraySetAsSeries(array,as_series); return(CopyHigh(NULL,PERIOD_CURRENT,start,count,array)==count ? ArrayMaximum(array)+start : WRONG_VALUE); } //+------------------------------------------------------------------+ //| Возвращает индекс минимального значения таймсерии Low | //+------------------------------------------------------------------+ int Lowest(const int count,const int start,const bool as_series=true) { double array[]; ArraySetAsSeries(array,as_series); return(CopyLow(NULL,PERIOD_CURRENT,start,count,array)==count ? ArrayMinimum(array)+start : WRONG_VALUE); } //+------------------------------------------------------------------+ また、線は削除すべきです。何のために線があるのでしょうか?止めを刺すだけなら? Juer 2018.09.06 09:36 #9190 型なし宣言 インクルードファイルをコンパイルしても、エラーにならないのですが。このインクルードファイルをインクルードしたメインプログラムファイルをコンパイルすると、タイプエラーのない宣言が表示されます。インクルードファイルで宣言されたオブジェクトが表示されない protected CSomeClass *object.インクルードファイルには、#include "SomeClass.mqh "ディレクティブを記述しています。そして、メインファイルでは、インクルードされたファイルのクラスのオブジェクトが 作成され、いずれかのメソッドが呼び出されます。 1...912913914915916917918919920921922923924925926...1504 新しいコメント 取引の機会を逃しています。 無料取引アプリ 8千を超えるシグナルをコピー 金融ニュースで金融マーケットを探索 新規登録 ログイン スペースを含まないラテン文字 このメールにパスワードが送信されます エラーが発生しました Googleでログイン WebサイトポリシーおよびMQL5.COM利用規約に同意します。 新規登録 MQL5.com WebサイトへのログインにCookieの使用を許可します。 ログインするには、ブラウザで必要な設定を有効にしてください。 ログイン/パスワードをお忘れですか? Googleでログイン
指標の計算は、最初から最後まで(直近の過去データから直近の現在データまで)です。これは、時系列でいうところのインデックス化の表れです。そのため、配列はそれに応じてインデックスを付けなければなりませんが、それがあなたの持っているものです。
どうしたんですか?
MQL4からMQL5に移植したのと同じように動作しますが、ArraySetAsSeries()のためにコードが醜いことがわかりましたので、質問させて いただきました。
以下は、両方のコードです。
MT5用のインジケーターの書き方を教えてください。- 私のコードはいい加減なんです!フルストップ)))
ZSZはMT5用のインジケータの書き方を覚えておらず、座ってヘルプを使って40分で書き直したが、結果は......。imho、イマイチ((!
しかし、ArraySetAsSeries()のためにコードが醜いことがわかりましたので、私は質問 しました。
以下は、両方のコードです。
MT5用のインジケーターの書き方を教えてください。- 私のコードはいい加減なんです!フルストップ)))
ループを反転させるときは、必ず配列を時系列にする必要があります。そうしないと、ループ内のバッファのインデックスと必要なデータのインデックスが一致しません。インジケータバッファの配列のループインデックスは先頭から最後へ、open[], high[], low[], close[] などでは最後から先頭へ移動します。あるいは、ループを逆にして、配列の open[], high[], low[], close[] と残りをバッファのインデックス付けと一致させることもできますが、これはより複雑です。
寓話でわかりやすくしてほしいなら、こんな寓話があります。
あなたは線路の前に立って、2台の電車を見ています。一方向に進むか、両方左から右に進むか(ArraySetAsSeries(array,true)-1本目、限界から0へのループ-2本目)です。
あるいは互いに向かっていく - (ArraySetAsSeries(array,false) - 右から左へ - 第一列車、そして限界から0へのループ - 左から右へ - 第二列車)
そして、そうです:私はコードに目を通しませんでした - ダウンロード、保存(フォーラムからすでに多くの不要なコードがあります)、それらを互いに比較することを望んでいません...。
メッセージの中に、1番目と2番目のコードを入れておけば、一度に何が何番目なのかが分かるので楽なんですけどね。
あるいは、ループを反転させて、配列 open[]、high[]、low[]、close[]などのインデックスに 合わせるか、どちらが難しいでしょう。
今日は一晩中リバースしてました、我慢の限界です(((^^;)
私が問題を理解する限りでは
- MT5では、インジケータ・バッファに割り当てられた配列は、デフォルトで左から右へのインデックスが付けられています。
- MT5の時系列でOnCalculate()から利用できるopen[], high[], low[], close[] は常に右から左へのインデックスで渡されます。
- すなわち、ステップ 1 と 2 に基づいて、ヒストリーの終わりからゼロバーまでの指標を計算するために
a) またはバッファ配列のインデックスを再指定する。
b) あるいは,配列の要素を左から右へ再計算し,別のループで右から左へ再計算するループを作成する.
選択肢a) - 私のソースでは実装されている,選択肢b) - 余分な計算をする意味がわからない。
のソースになります。
MT5です。
MT4です。
今夜は徹夜でポチポチしてましたが、我慢の限界です(((^^;)
私が理解する限りでは、この問題は
- MT5では、インジケータ・バッファに割り当てられた配列は、デフォルトで左から右へのインデックスが付けられています。
- MT5の時系列でOnCalculate()から利用できるopen[], high[], low[], close[] は常に右から左へのインデックスで渡されます。
- すなわち、ステップ 1 と 2 に基づいて、ヒストリーの終わりからゼロバーまでの指標を計算するために
a) またはバッファ配列のインデックスを再指定する。
b) あるいは,配列の要素を左から右へ再計算し,別のループで右から左へ再計算するループを作成する.
つまり、私の質問に対する美しい解決策はないのでしょうか? 変形a) - 私のソースでは実装されています、変形b) - 余分な計算をする意味がわかりません。
すべての配列は右から左へのインデックスを持つ。したがって、左から右へのループ(左から右、つまり限界から0まで)に完全に準拠するためには、使用するすべての配列を必要なインデックスに 設定する必要があります:バッファは OnInit()で、使用するタイムサーバはOnCalculate()で設定します。
あるいは、0からリミットまでのサイクルを行う。これは、mql4からmql5への移植の際に、必ずしも容易ではない。
したがって、この場合は ArraySetAsSeries() オプションの方がよいでしょう。
すべての配列は右から左へのインデックスを持つ。したがって、左から右へのループに完全に準拠するために(そしてそれは限界から0まで左から右にある)、使用されるすべての配列を必要なインデックスに 設定する必要があります:バッファは OnInit()で、使用するタイムサーバ - OnCalculate()でです。
あるいは、0からリミットまでのサイクルを行う必要があり、mql4をmql5に移植した場合、必ずしも容易ではありません。
そのため、この場合はArraySetAsSeries()メソッドの方が効果的です。
見て、あなたのコードからすべてのArraySetAsSeries() を削除し( 最初の行のInit()と OnCalculate()のトップで)、ループを 修正してください。
for(i=0;i<limit;i++)
理屈では全部合うはずなのに、違う!チャートの形が違う!これが解せない。
見て、私は私のコードからすべてのArraySetAsSeries() を削除し(最初の 行のInit()と OnCalculate()の中で)、ループを修正 した。
for(i=0;i<limit;i++)
理屈では全部合うはずなのに、違うんです!チャートの形が違っていて、そこがわからないんです。
もっと複雑なんです。論理を変えなければならないのです。ループを反転させるだけではダメなんです。
小さな例を挙げますと、コードの中に
Buf_NTLine1[i+1])
配列のインデックスが 異なる場合、i+1インデックスはどこに行くのでしょうか?
しかも、たくさんあるんです。IHighest() - 開始と番号。どこからがある指標で、どこからが別の指標なのか。
などなど・・・。
とたくさんあります。IHighest() - 開始と終了の数...片方のインデックスともう片方のインデックスはどこから始まるのでしょうか?
oh man!その通り!よくやった!!そう、そこが厄介なんだ!!(笑)。
ああ...MT5では多くの違いがあり、プログラマーの頭の中には多くのチェックと様々な注意事項が......。
少し前に見たときは、MT5ではInit() で全てが正しく初期化 されるとは限らないというメッセージがあり、タイムフレームの準備が出来ていなくてもInit()が終了して しまうことがあるようです。
私は昨日バグを見た:MT5でこの指標は、タイムフレームを切り替える場合、時には指標のバッファが 空にならないことがあります - それは古い値がOnCalculate()で指標の配列の各要素に特定の値を割り当てない場合は残っているようだ、私はInit()でArrayInitialize(アレンジ、0.0)を置くことを 試みた - それはあまりにも、その後ではない動作します...。
私が正しく理解している限りでは
- MT5で、Init() の初期化時に、インジケータのバッファが自動的に初期化されない?(MT4ではバッファに何も残っていなかったと記憶しています)
- MT5のInit() において、ヒストリがロードされていない場合、バッファアレイのサイズが不明である可能性があります。
ちくしょう! そうだ! よくやった! そう、それが楽しいんだ!!!!
ああ...MT5ではいろいろな違いがあって、プログラマーがチェックしたり、いろいろな注意点があるんです...。
少し前にこのメッセージを見たとき、MT5ではInit() で全てが正しく初期化さ れるとは限らないようで、タイムフレームの準備が出来ていなくてもInit()が終了して しまうことがあるようです。
私は昨日バグを見た:MT5でこの指標は、タイムフレームを切り替える場合、時には指標のバッファが 空にならないことがあります - それは古い値がOnCalculate()で指標の配列の各要素に特定の値を割り当てない場合は残っているようだ、私はInit()でArrayInitialize(アレンジ、0.0)を置くことを 試みた - それはあまりにも、その後ではない動作します...。
私が正しく理解している限りでは
- MT5で、Init() の初期化時に、インジケータのバッファが自動的に初期化されない?(MT4ではバッファに何も残っていなかったと記憶しています)
- MT5のInit() において、ヒストリがロードされていない場合、バッファアレイのサイズが不明である可能性があります。
理屈はよくわからなかった。
理屈はよくわからなかった。
これは正しい方法です。エントリーポイントを最大/最小価格に置くのではなく、始値で 置くのが良いのです。
また、線は削除すべきです。何のために線があるのでしょうか?止めを刺すだけなら?
型なし宣言
インクルードファイルをコンパイルしても、エラーにならないのですが。このインクルードファイルをインクルードしたメインプログラムファイルをコンパイルすると、タイプエラーのない宣言が表示されます。インクルードファイルで宣言されたオブジェクトが表示されない protected CSomeClass *object.インクルードファイルには、#include "SomeClass.mqh "ディレクティブを記述しています。そして、メインファイルでは、インクルードされたファイルのクラスのオブジェクトが 作成され、いずれかのメソッドが呼び出されます。