MQL5 および MQL4 の選択およびナビゲーション ユーティリティ: チャートへのデータの追加
イントロダクション
これまでの記事でさまざまなことを行ってきました。(MQL5 および MQL4 の選択およびナビゲーション ユーティリティ: パターンの自動検索を追加し、検出されたシンボルを表示する方法、 MQL5 および MQL4 の選択およびナビゲーション ユーティリティ: "ホームワーク" タブを追加し、グラフィカル オブジェクトを保存する方法、開発中のMQL5 および MQL4 のシンボル選択およびナビゲーション・ユーティリティーなどです。 しかし、まだ高品質のデイトレードには十分ではありません. この記事では、適切な相場参入/決済ポイントを見つけるための新しい機能を追加します。
各機能の項目については、別のセクションで説明します。 まず、目標を決定します。 例えば:次に、プロジェクトに同じ機能を実装する場合に備えて、関数またはコードを分析します。
今日のトレンドが昨日のトレンドと異なるシンボルを非表示にする
Input: 今日のトレンド !=機能のトレンドなら隠す
Area:並べ替え設定
多くのデイトレーダーは、今日のトレンドが昨日と同じである株式をトレードすることを勧めています。 シンプルに言えば、株価が昨日上昇した場合、今日は上昇するはずです。
次の関数を使用すると、このようなシンボルを並べ替えることができます。
/* 今日のトレンドが昨日のトレンドと等しくない場合は true を返す symname - 使用済みシンボル名 */ bool check_no_trend(string symname){ MqlRates rates2[]; ArraySetAsSeries(rates2, true); if(CopyRates(symname, PERIOD_D1, 0, 2, rates2)==2){ if( rates2[0].close>rates2[0].open && rates2[1].close>rates2[1].open ){ return false; } if( rates2[0].close<rates2[0].open && rates2[1].close<rates2[1].open ){ return false; } } return true; }
セッション開始の表示
Input:1 日の開始を表示する
Area:チャートの設定
トレードセッションの開始は、株式相場が開く時間(株式について話している場合)、例えば、米国の株式相場なら午後4時30分、ヨーロッパとロシアなら午前10:00です。 FXの場合は、真夜中をトレードセッションの開始時間とみなしましょう。
M5のような小さい時間枠では、現在のセッションの開始を定義するのが難しい場合があります。 よってシンボルの現在のトレード日が始まっている足を見ることができるように設定を追加します。
セッション開始を表示する関数:
/* チャートに 1 日の開始を表示 currChart - チャートID day - 日番号 (0 - 現在) */ void showNdays(long currChart, int day){ MqlRates rates[]; ArraySetAsSeries(rates, true); if(CopyRates(ChartSymbol(currChart), PERIOD_D1, day, 1, rates)>0){ ObjectCreate(currChart, exprefix+"_Nday", OBJ_VLINE, 0, rates[0].time, 0); ObjectSetInteger(currChart,exprefix+"_Nday",OBJPROP_STYLE,STYLE_DOT); ObjectSetInteger(currChart,exprefix+"_Nday",OBJPROP_RAY,true); ObjectSetInteger(currChart,exprefix+"_Nday",OBJPROP_SELECTABLE,false); ObjectSetInteger(currChart,exprefix+"_Nday",OBJPROP_BACK,true); } }
チャート上では、これは垂直の赤い線のように見えます。
同様の関数はMetaTraderに既に存在します。 さらに、直近のセッションの始まりだけでなく、各セッションの一般的な開始も確認できます。 これを行うには、チャートのプロパティの"期間区切りシンボル"ボックスをオンにします。 実際には、特定の時間枠では、この関数は冗長であり、チャートが乱雑になり、分析において不快になります。 サンプルです。
昨日と前日の安値と高値を表示
Input:昨日の安値と高値を表示し、一昨日の安値と高値を表示します
Area:チャートの設定
デイトレードの場合、昨日と一昨日の高値と安値は、多くの場合、サポートとレジスタンスレベルとして使用します。 価格はしばしば下落し、昨日または前日の高値とリバウンドに当たります。 個人的な経験によると、70%の確率で、価格はそのような高値/安値をブレイクしません。
したがって、これらのレベルは無視されるべきではありません。
次の関数は、選択した日の安値と高値を表示するために使用します。
/* 指定した日の安値と高値をチャートに表示する currChart - チャートのID day - 表示された日インデックス */ void showHOBeforeDay(long currChart, int day=1){ MqlRates rates[]; ArraySetAsSeries(rates, true); color curColor=clrAquamarine; switch(day){ case 2: curColor=clrOlive; break; } if(CopyRates(ChartSymbol(currChart), PERIOD_D1, day, 1, rates)>0){ ObjectCreate(currChart, exprefix+"_beforeday_high_line"+(string) day, OBJ_HLINE, 0, 0, rates[0].high); ObjectSetInteger(currChart,exprefix+"_beforeday_high_line"+(string) day,OBJPROP_COLOR,curColor); ObjectSetInteger(currChart,exprefix+"_beforeday_high_line"+(string) day,OBJPROP_SELECTABLE,false); ObjectSetInteger(currChart,exprefix+"_beforeday_high_line"+(string) day,OBJPROP_BACK,true); ObjectCreate(currChart, exprefix+"_beforeday_low_line"+(string) day, OBJ_HLINE, 0, 0, rates[0].low); ObjectSetInteger(currChart,exprefix+"_beforeday_low_line"+(string) day,OBJPROP_COLOR,curColor); ObjectSetInteger(currChart,exprefix+"_beforeday_low_line"+(string) day,OBJPROP_SELECTABLE,false); ObjectSetInteger(currChart,exprefix+"_beforeday_low_line"+(string) day,OBJPROP_BACK,true); } }
前日の安値と高値は明るい水平線で表示され、一昨日はグリーン線として表示されます。
最も近いラウンド価格を表示する
Input:最も近いのラウンド価格を表示する(period < 1 day)
Area:チャートの設定
ラウンド価格は、別の形の自然なサポート/レジスタンスレベルです。 .00または.50で終わるような価格です。 多くのトレーダーは、ラウンドレベルの近くにトレードのオーダーを置きます。
.25 と .75. レベルはラウンドと見なされることもありますが、信頼性が低いため、チャートを乱雑にしないように深追いしません。
ラウンド価格を照会するには、次の関数を使用します。
/* 現在の価格に最も近い 3 つのラウンド レベルを表示します。 currChart - チャートID */ void showRoundPrice(long currChart){ string name=ChartSymbol(currChart); int tmpPrice; MqlRates rates[]; ArraySetAsSeries(rates, true); if(CopyRates(name, PERIOD_D1, 0, 1, rates)==1){ switch((int) SymbolInfoInteger(name, SYMBOL_DIGITS)){ case 0: break; case 2: case 3: case 5: tmpPrice=(int) rates[0].close; ObjectCreate(currChart, exprefix+"_round_line_00_0", OBJ_HLINE, 0, 0, (double) tmpPrice-1 ); ObjectSetInteger(currChart,exprefix+"_round_line_00_0",OBJPROP_COLOR,clrCadetBlue); ObjectSetInteger(currChart,exprefix+"_round_line_00_0",OBJPROP_STYLE, STYLE_DASH); ObjectSetInteger(currChart,exprefix+"_round_line_00_0",OBJPROP_SELECTABLE,false); ObjectSetInteger(currChart,exprefix+"_round_line_00_0",OBJPROP_BACK,true); ObjectCreate(currChart, exprefix+"_round_line_05_0", OBJ_HLINE, 0, 0, (double) tmpPrice-0.5 ); ObjectSetInteger(currChart,exprefix+"_round_line_05_0",OBJPROP_COLOR,clrCadetBlue); ObjectSetInteger(currChart,exprefix+"_round_line_05_0",OBJPROP_STYLE, STYLE_DASH); ObjectSetInteger(currChart,exprefix+"_round_line_05_0",OBJPROP_SELECTABLE,false); ObjectSetInteger(currChart,exprefix+"_round_line_05_0",OBJPROP_BACK,true); ObjectCreate(currChart, exprefix+"_round_line_00_1", OBJ_HLINE, 0, 0, (double) tmpPrice ); ObjectSetInteger(currChart,exprefix+"_round_line_00_1",OBJPROP_COLOR,clrCadetBlue); ObjectSetInteger(currChart,exprefix+"_round_line_00_1",OBJPROP_STYLE, STYLE_DASH); ObjectSetInteger(currChart,exprefix+"_round_line_00_1",OBJPROP_SELECTABLE,false); ObjectSetInteger(currChart,exprefix+"_round_line_00_1",OBJPROP_BACK,true); ObjectCreate(currChart, exprefix+"_round_line_05_1", OBJ_HLINE, 0, 0, (double) tmpPrice+0.5 ); ObjectSetInteger(currChart,exprefix+"_round_line_05_1",OBJPROP_COLOR,clrCadetBlue); ObjectSetInteger(currChart,exprefix+"_round_line_05_1",OBJPROP_STYLE, STYLE_DASH); ObjectSetInteger(currChart,exprefix+"_round_line_05_1",OBJPROP_SELECTABLE,false); ObjectSetInteger(currChart,exprefix+"_round_line_05_1",OBJPROP_BACK,true); ObjectCreate(currChart, exprefix+"_round_line_00_2", OBJ_HLINE, 0, 0, (double) tmpPrice+1 ); ObjectSetInteger(currChart,exprefix+"_round_line_00_2",OBJPROP_COLOR,clrCadetBlue); ObjectSetInteger(currChart,exprefix+"_round_line_00_2",OBJPROP_STYLE, STYLE_DASH); ObjectSetInteger(currChart,exprefix+"_round_line_00_2",OBJPROP_SELECTABLE,false); ObjectSetInteger(currChart,exprefix+"_round_line_00_2",OBJPROP_BACK,true); ObjectCreate(currChart, exprefix+"_round_line_05_2", OBJ_HLINE, 0, 0, (double) tmpPrice+1.5 ); ObjectSetInteger(currChart,exprefix+"_round_line_05_2",OBJPROP_COLOR,clrCadetBlue); ObjectSetInteger(currChart,exprefix+"_round_line_05_2",OBJPROP_STYLE, STYLE_DASH); ObjectSetInteger(currChart,exprefix+"_round_line_05_2",OBJPROP_SELECTABLE,false); ObjectSetInteger(currChart,exprefix+"_round_line_05_2",OBJPROP_BACK,true); break; } } }
チャート上では、ラウンドレベルが破線の水平線で表示されます。
時間足の終わりを表示
Input parameter:表示時間クローズ(period < 1hour)
Area:チャートの設定
自然なサポート/レジスタンスレベルの主題から続けて、また、終了時刻レベルを言及することができます。 時間足の終値は、実際のトレードではなかなか気づきにくいですが、より小さな時間枠ではサポート/レジスタンスレベルであることあります。 いずれにしても、少なくとも過去 4 時間で、このパラメータを表示する関数を実装してみましょう。
チャート上の時間終了を強調表示する関数:
/* チャート上の直近の 4 時間を閉じる表示 currChart - チャートID */ void showCloseHour(long currChart){ MqlDateTime tmpTime; int tmpOffset=0; MqlRates rates[]; ArraySetAsSeries(rates, true); if(CopyRates(ChartSymbol(currChart), PERIOD_M30, 0, 9, rates)>0){ tmpOffset=0; TimeToStruct(rates[tmpOffset].time, tmpTime); if(tmpTime.min!=0){ tmpOffset++; } ObjectCreate(currChart, exprefix+"_hour_0", OBJ_VLINE, 0, rates[tmpOffset].time, 0); ObjectSetInteger(currChart,exprefix+"_hour_0",OBJPROP_SELECTABLE,false); ObjectSetInteger(currChart,exprefix+"_hour_0",OBJPROP_STYLE,STYLE_DOT); ObjectSetInteger(currChart,exprefix+"_hour_0",OBJPROP_RAY,true); ObjectSetInteger(currChart,exprefix+"_hour_0",OBJPROP_COLOR,clrYellow); ObjectSetInteger(currChart,exprefix+"_hour_0",OBJPROP_BACK,true); tmpOffset++; TimeToStruct(rates[tmpOffset].time, tmpTime); if(tmpTime.min!=0){ tmpOffset++; } ObjectCreate(currChart, exprefix+"_hour_1", OBJ_VLINE, 0, rates[tmpOffset].time, 0); ObjectSetInteger(currChart,exprefix+"_hour_1",OBJPROP_SELECTABLE,false); ObjectSetInteger(currChart,exprefix+"_hour_1",OBJPROP_STYLE,STYLE_DOT); ObjectSetInteger(currChart,exprefix+"_hour_1",OBJPROP_RAY,true); ObjectSetInteger(currChart,exprefix+"_hour_1",OBJPROP_COLOR,clrYellow); ObjectSetInteger(currChart,exprefix+"_hour_1",OBJPROP_BACK,true); tmpOffset++; TimeToStruct(rates[tmpOffset].time, tmpTime); if(tmpTime.min!=0){ tmpOffset++; } ObjectCreate(currChart, exprefix+"_hour_2", OBJ_VLINE, 0, rates[tmpOffset].time, 0); ObjectSetInteger(currChart,exprefix+"_hour_2",OBJPROP_SELECTABLE,false); ObjectSetInteger(currChart,exprefix+"_hour_2",OBJPROP_STYLE,STYLE_DOT); ObjectSetInteger(currChart,exprefix+"_hour_2",OBJPROP_RAY,true); ObjectSetInteger(currChart,exprefix+"_hour_2",OBJPROP_COLOR,clrYellow); ObjectSetInteger(currChart,exprefix+"_hour_2",OBJPROP_BACK,true); tmpOffset++; TimeToStruct(rates[tmpOffset].time, tmpTime); if(tmpTime.min!=0){ tmpOffset++; } ObjectCreate(currChart, exprefix+"_hour_3", OBJ_VLINE, 0, rates[tmpOffset].time, 0); ObjectSetInteger(currChart,exprefix+"_hour_3",OBJPROP_SELECTABLE,false); ObjectSetInteger(currChart,exprefix+"_hour_3",OBJPROP_STYLE,STYLE_DOT); ObjectSetInteger(currChart,exprefix+"_hour_3",OBJPROP_RAY,true); ObjectSetInteger(currChart,exprefix+"_hour_3",OBJPROP_COLOR,clrYellow); ObjectSetInteger(currChart,exprefix+"_hour_3",OBJPROP_BACK,true); } }
チャート上では、過去 4 時間の終わりは垂直黄色の線で表示されます。
年間の最大価格と最小価格を表示する
Input:年間の最大/最小価格を表示
Area:チャートの設定
年間の最大価格と最安値もトレーダーの間で人気があります。 チャートにも表示します。
次の関数は、1 年の中にある極端な価格を表示するために使用します。
/* チャートに昨年の最大価格と最安値を表示します。 currChart - チャートID。 */ void showMaxPrice(long currChart){ MqlRates rates[]; ArraySetAsSeries(rates, true); if(CopyRates(ChartSymbol(currChart), PERIOD_MN1, 0, 12, rates)==12){ double maxPrice=0; double minPrice=0; for(int j=0; j<12; j++){ if( maxPrice==0 || maxPrice<rates[j].high ){ maxPrice=rates[j].high; } if( minPrice==0 || minPrice>rates[j].low ){ minPrice=rates[j].low; } } ObjectCreate(currChart, exprefix+"_maxprice_line", OBJ_HLINE, 0, 0, maxPrice); ObjectSetInteger(currChart,exprefix+"_maxprice_line",OBJPROP_COLOR,clrMagenta); ObjectSetInteger(currChart,exprefix+"_maxprice_line",OBJPROP_SELECTABLE,false); ObjectSetInteger(currChart,exprefix+"_maxprice_line",OBJPROP_BACK,true); ObjectCreate(currChart, exprefix+"_minprice_line", OBJ_HLINE, 0, 0, minPrice); ObjectSetInteger(currChart,exprefix+"_minprice_line",OBJPROP_COLOR,clrMagenta); ObjectSetInteger(currChart,exprefix+"_minprice_line",OBJPROP_SELECTABLE,false); ObjectSetInteger(currChart,exprefix+"_minprice_line",OBJPROP_BACK,true); } }
過去 12 か月間の最大価格と最小価格は、紫色の水平線で表示されます。
チャートを開くときにスプレッドを表示する
Input:チャートを開くときにスプレッドを表示する
Area:チャートの設定
小さなストップロスを使用する場合、現在のシンボルスプレッドは、トレードに参入するための決定的な要因の一つです。 したがって、チャートを開く時に知ることが重要です。 では、チャートにデータを追加してみましょう。
チャートが開かれた瞬間にのみスプレッドを表示します。 これは、瞬間的に変更される可能性があります。 スプレッドレベルはリアルタイムでは表示されません。 シンボルの現在のスプレッド範囲を評価するためにのみ使用します。
次の短い関数は、スプレッドを返します。
/* 指定したシンボルの現在のスプレッドを持つ文字列を返します。 symname - シンボル名 */ string getmespread_symbol(string symname){ double curSpread=SymbolInfoDouble(symname, SYMBOL_ASK)-SymbolInfoDouble(symname, SYMBOL_BID); return "Spread: "+(string) DoubleToString(curSpread, (int) SymbolInfoInteger(symname, SYMBOL_DIGITS))+" "+SymbolInfoString(symname, SYMBOL_CURRENCY_PROFIT)+" ("+DoubleToString(curSpread/SymbolInfoDouble(symname, SYMBOL_POINT), 0)+" p)"; }
このスプレッドは、他の追加データの中で開いているチャートへのコメントで表示されます。
名前の付いているテンプレートをチャートに適用する
Input:名前の付いているテンプレートをチャートに適用
Area:チャートの設定
MetaTraderでは、テンプレートを使用することにより、前の設定、EA、およびいろいろ数値設定したパラメータのインジケータをすばやく適用することができます。
ただし、"すばやく" は少し緩い概念です。 チャートにテンプレートを適用するには、チャートのコンテキスト メニューで[テンプレート]/"テンプレート名"を選択します。 しかし、インジケータ(例えば移動平均)が意思決定を行う際に使用していて、しかも1日あたり数百のツールを操作している場合はどうでしょうか。 ひとつひとつそれぞれをクリックする必要があるでしょうか。
各チャートにセットしたインジケータのテンプレートを自動的に適用する方がはるかに簡単です。 では、この関数を実装してみましょう。
チャートにテンプレートを適用するには、MQL5 と MQL4 の両方で動作するChartApplyTemplateコマンドを使用します。
ChartApplyTemplate(curChartID[ArraySize(curChartID)-1], allApplyTemplate+".tpl");
ゲルチクのATRを表示する
Input:ゲルチクのATRを表示する
Area:チャートの設定
ATR は、一定期間内の平均日次シンボルの移動であり、シンボルの移動範囲を決定する際に重要なパラメータです。 これはさまざまな目的に使用します。
例えば、デイトレードの際にエントリーする価値があるかどうかを判断するのに役立ちます。 100ポイントの値動きをつかみ取りたい場合、もしシンボルの1日の平均移動範囲が50ポイントだったら、利益を取れる可能性は小さく、エントリーしない方が賢明です。
また、シンボルが既に日のATRの80%以上を片方にオーバーしている場合、同じ方向にトレードを行うのは意味がなく、逆方向にのみエントリーするべきだと考えられています。
ゲルチクのATRは、異常な足だけが考慮されるという観点から、従来のATRとは異なります。 異常な足は、平均的な足よりも2倍大きいか0.3より小さいものです。
ATR は通常、5日間または 3 日間で計算されます。
次の関数は、Gerchik の ATR を表示します。
/* 指定したシンボルの Gerchik の ATR を含む文字列を返します。 symname - シンボル名 */ string getmeatr_symbol(string symname){ string msg=""; MqlRates rates[]; ArraySetAsSeries(rates, true); double atr=0; double pre_atr=0; int curDigits=(int) SymbolInfoInteger(symname, SYMBOL_DIGITS); string currencyS=SymbolInfoString(symname, SYMBOL_CURRENCY_PROFIT); int count=0; int copied=CopyRates(symname, PERIOD_D1, 0, 8, rates); if(copied>1){ for(int j=1; j<copied; j++){ pre_atr+=rates[j].high-rates[j].low; } pre_atr/=(copied-1); } if(pre_atr>0){ for(int j=1; j<copied; j++){ if( rates[j].high-rates[j].low > pre_atr*2 ) continue; if( rates[j].high-rates[j].low < pre_atr*0.3 ) continue; if( ++count > 5 ){ break; } atr+=rates[j].high-rates[j].low; } if( count > 5 ){ count=5; } atr= NormalizeDouble(atr/count, curDigits ); } if(atr>0){ StringAdd(msg, "ATR: "+(string) DoubleToString(atr, curDigits)+" "+currencyS+", today: "+DoubleToString(rates[0].high-rates[0].low, curDigits)+" "+currencyS+" ("+(string) (int) (((rates[0].high-rates[0].low)/atr)*100) +"%)"); } return msg; }
このユーティリティは、前のセクションで説明したスプレッドのように、ATR をチャートコメントに表示します。 ATR は前のスクリーンショットで見ることができます。
ガイドシンボルの方向の表示
Input:#Nの方向を表示する
Area:追加データの表示
すでにこの記事で述べたことから判断すると、デイトレードは、心に留めておくべきことがたくさんあるので、複雑な試みです。 結局のところ、これがすべてではありません。
多くのトレーダーは、エントリーする前に、いわゆるガイドシンボルの現在の方向を見ることをお勧めします。
たとえば、米国株式相場でトレードする場合は、次のステップに従う必要があります。
- 米国の主要指数、少なくともダウ・ジョーンズまたはSP500です。;
- 残りの国のインデックスは中国、ヨーロッパ、日本です。;
- 様々な市場セグメントのリーディングカンパニー:銀行セクターのJPモルガン、テクノロジーのアップル、エネルギーのエクソンモービル、IBM、その他です。
また、石油、金、米ドルの相場を追跡することができます。
すべてのガイドシンボルが一方向に移動する場合に最適です。 お察しのように、片方のシンボルのみトレードすることが賢明です。
異なるブローカーは同じツールの異なる名前を持つ可能性があるため、監視するツールをプログラムで指定することは不可能です。 しかし、文字列型の受信パラメータを追加して、ユーザーがブローカーによって名前が付けられたシンボルのティッカーを設定できるようにすることができます。 このユーティリティには、7 つのパラメータがあります。
次の関数は、指定したシンボルの方向を返します。
/* 指定したシンボルで価格移動方向の文字列を返します。 symname - シンボル名 show - シンボル名ラベルを文字列に表示する場合 */ string getmeinfo_symbol(string symname, bool show=true){ MqlRates rates2[]; ArraySetAsSeries(rates2, true); string msg=""; if(CopyRates(symname, PERIOD_D1, 0, 1, rates2)>0){ if(show){ StringAdd(msg, (string) symname+": "); } StringAdd(msg, "D1 "); if( rates2[0].close > rates2[0].open ){ StringAdd(msg, "+"+DoubleToString(((rates2[0].close-rates2[0].open)/rates2[0].close)*100, 2) +"% (+"+DoubleToString(rates2[0].close-rates2[0].open, (int) SymbolInfoInteger(symname, SYMBOL_DIGITS))+" "+SymbolInfoString(symname, SYMBOL_CURRENCY_PROFIT)+")"); }else{ if( rates2[0].close < rates2[0].open ){ StringAdd(msg, "-"+DoubleToString(((rates2[0].open-rates2[0].close)/rates2[0].close)*100, 2) +"% (-"+DoubleToString(rates2[0].open-rates2[0].close, (int) SymbolInfoInteger(symname, SYMBOL_DIGITS))+" "+SymbolInfoString(symname, SYMBOL_CURRENCY_PROFIT)+")"); }else{ StringAdd(msg, "0%"); } } } if(CopyRates(symname, PERIOD_H1, 0, 1, rates2)>0){ StringAdd(msg, ", H1 "); if( rates2[0].close > rates2[0].open ){ StringAdd(msg, "+"+DoubleToString(((rates2[0].close-rates2[0].open)/rates2[0].close)*100, 2)+"% (+"+DoubleToString(rates2[0].close-rates2[0].open, (int) SymbolInfoInteger(symname, SYMBOL_DIGITS))+" "+SymbolInfoString(symname, SYMBOL_CURRENCY_PROFIT)+")"); }else{ if( rates2[0].close < rates2[0].open ){ StringAdd(msg, "-"+DoubleToString(((rates2[0].open-rates2[0].close)/rates2[0].close)*100, 2)+"% (-"+DoubleToString(rates2[0].open-rates2[0].close, (int) SymbolInfoInteger(symname, SYMBOL_DIGITS))+" "+SymbolInfoString(symname, SYMBOL_CURRENCY_PROFIT)+")"); }else{ StringAdd(msg, "0%"); } } } return msg; }
方向は、ユーティリティが起動されたチャートコメントに表示されます。 これは、次のようになります。
誘導シンボルの移動方向は自動的には更新されませんのでご注意ください。 データを更新するには、他のタブに切り替えるか、Rキーを押します。 ただし、新しいインプットで簡略化することもできます。
ユーティリティ タブの自動更新
Input:開いているタブを設定した秒数ごとに更新する
Area:追加データの表示
現在開いているタブの内容を(R キーを押すだけでなく)自動的に更新する場合は、更新が行われた秒数を設定するだけです。 0を超える値は、指定した秒数が経過した後にタブを更新するようになります。 これは、タブが N
秒ごとに厳密に更新されることを意味するものではありません。 代わりに、タブが N に加えてさらに 1 ~ 2 秒で更新されることを意味します。
この関数を実装するコードはOnTimer関数内で、シンプルです。
//指定した秒数後にタブの内容を更新する if( autoUpdateAfter>0 && TimeCurrent()-lastUpd >= autoUpdateAfter ){ start_symbols(); lastUpd=TimeCurrent(); }
ユーティリティー操作の開始時に、OnInit関数の現在の時刻で直近のUpd変数値を初期化しました。
株式に関する財務データの表示
Input:会社情報の表示
Area:外部データ
株式を売買する前に会社のファンダメンタルズの指標に従う場合は、異なるウェブサイトを閲覧しないように、パラメータをMetaTraderウィンドウに直接表示する必要があります。
その関数を実装してみましょう。 これをするために、ユーティリティを使用してチャートが開かれるとすぐに、ターミナルのエキスパートタブにパラメータが表示されます。
もちろん、金融指標自体はどこからともなく引き出すことはできません。 最初は、直接EAに「ハードコーディング」したかったのですが、メモリエラーが原因で計画の妨げになりました。 したがって、すべての財務指標は、この記事に添付されているファインダーフォルダに個別に格納されます。 この関数を機能させるには、アーカイブをダウンロードして解凍し、 ファインダーフォルダをターミナルのファイルディレクトリに配置します。
Filesディレクトリを見つけるには、MetaTraderの[ファイル]メニューを開き、[データフォルダを開く]をクリックします。 新しく開いたエクスプローラ ウィンドウで、MQL4またはMQL5フォルダに移動します。
財務指標は、この記事を執筆した時点で、今後数ヶ月間分あります。 後でデータが必要な場合は、個人的にメッセージを書いてください。
しかし、データ出力関数に戻りましょう。 この関数は、会社のティッカー、つまり #プレフィックス、およびブローカーによって追加された .us および .eu サフィックスから冗長な要素を削除します。 ブローカーがティッカーに何か他のものを追加する場合は、ユーティリティコードに独自のフィルタを追加して、過剰な文字を削除します。
finderフォルダに必要なティッカーデータが見つからない場合、検索は会社名で実行されます。
void printTicker(string ticker, string name){ bool isYes=false; int filehandle; //ティッカーからサフィックスとプレフィックスを削除する //小文字に変換する StringToLower(ticker); StringReplace(ticker, "#", ""); StringReplace(ticker, ".us", ""); StringReplace(ticker, ".eu", ""); //会社名を小文字に変換する StringToLower(name); ResetLastError(); //「ファインダー」フォルダに会社のデータがある場合、 if( FileIsExist("finder\\"+ticker+".dat") ){ isYes=true; filehandle=FileOpen("finder\\"+ticker+".dat",FILE_READ|FILE_TXT); if(filehandle!=INVALID_HANDLE){ int str_size; string str; Print("----------------"); while(!FileIsEnding(filehandle)){ str_size=FileReadInteger(filehandle,INT_VALUE); str=FileReadString(filehandle,str_size); Print(str); } FileClose(filehandle); } }else if( FileIsExist("finder\\"+name+".dat") ){ isYes=true; filehandle=FileOpen("finder\\"+name+".dat",FILE_READ|FILE_TXT); if(filehandle!=INVALID_HANDLE){ int str_size; string str; Print("----------------"); while(!FileIsEnding(filehandle)){ str_size=FileReadInteger(filehandle,INT_VALUE); str=FileReadString(filehandle,str_size); Print(str); } FileClose(filehandle); } } //それ以外の場合は、データが見つからないことを出力します。 if(!isYes){ Print("No symbol data"); } }
その結果、ユーティリティを使用してチャートを開くと、[エキスパート] タブに会社情報が表示されます。 おおよそ次のようになります。
日の利益を表示する
Input:日の利益を表示する
Area:追加データの表示
最後に、1日に受け取った損益の額である日のトレード活動をストップするパラメータを追加し、収益性と損失を生み出すトレードの総数(チャートに表示) 上記のシーケンス)です。
以下に示すgetmetoday_profit()カスタム関数を使用して、MQL4 の現在の利益を取得します。 MQL5の場合、この関数は不十分です。
MQL5では、まずクローズポジションのデータを更新する必要があるかどうかを確認します。 これを行うには、グローバルに宣言されたneedHistory変数を使用します。 OnInit()標準関数では、この変数は
'true' の値を取得します。 したがって、
getmetoday_profit()関数の最初の起動時に、トレードに関するデータがヒストリーからアップロードされます。 その後、needHistory変数の値は 'false' です。
次に、標準の MQL5 OnTrade()関数を使用して、オープンポジションの 1 つがクローズされるたびにトレードヒストリーを再度アップロードします。
その結果、次のコードが得られます。
#ifdef __MQL5__ void OnTrade(){ if(orders_total==PositionsTotal()){ return; } if(orders_total>PositionsTotal()){ needHistory=true; } orders_total=(ushort) PositionsTotal(); } #endif /* 日の損益を含む文字列を返します。 */ string getmetoday_profit(){ string msg=""; double curProfit=0; int tradeAll=0; int tradeMinus=0; int tradePlus=0; MqlDateTime curD; TimeCurrent(curD); curD.hour=0; curD.min=0; curD.sec=0; #ifdef __MQL5__ if( needHistory ){ HistorySelect(StructToTime(curD),TimeCurrent()); } uint totalHistory=HistoryDealsTotal(); double currHistory=0; ulong ticket_history; for(uint j=0;j<totalHistory;j++){ if((ticket_history=HistoryDealGetTicket(j))>0 ){ double profitHistory=HistoryDealGetDouble(ticket_history,DEAL_PROFIT); profitHistory+=HistoryDealGetDouble(ticket_history,DEAL_COMMISSION); profitHistory+=HistoryDealGetDouble(ticket_history,DEAL_SWAP); if(profitHistory!=0){ currHistory+=profitHistory; } } } #else int cntMyPos=OrdersHistoryTotal(); if(cntMyPos>0){ for(int ti=cntMyPos-1; ti>=0; ti--){ if(OrderSelect(ti,SELECT_BY_POS,MODE_HISTORY)==false) continue; if( OrderCloseTime()<StructToTime(curD) ){ continue; } double tmpProfit=OrderProfit(); tmpProfit+=OrderSwap(); tmpProfit+=OrderCommission(); tradeAll++; if(tmpProfit>0){ tradePlus++; }else if(tmpProfit<0){ tradeMinus++; } curProfit+=tmpProfit; } } #endif if(tradeAll>0){ StringAdd(msg, "Today: "+DoubleToString(curProfit, 2)+" "+AccountInfoString(ACCOUNT_CURRENCY)+" ("+(string) tradeAll+";+"+(string) tradePlus+";-"+(string) tradeMinus+")"); } return msg; }
この利益は、ユーティリティが起動されたチャートにも表示されます。 これは次のようになります。
その日の利益は自動的に再計算されないことに注意してください。 現在の利益データを更新するには、別のタブを開くか、Rキーを押します。
結論
この記事は、おそらくこのシリーズの最後の記事です。 結果のユーティリティが役立つことを願っています。
しかし、機能性について何か欠けている場合は、そのことについて個人的にメッセージをください。 新しい記事を書くために十分な機能が欠落している場合に備えて、ユーティリティを改善し続けます。
最後に、この一連の記事で実装した機能を要約し、確認しましょう。
このユーティリティを起動すると、条件を満たすツールの一覧にアクセスできます。 リストの上には、All,LONG,SHORT,Rangeのタブのボタンだけでなく、自動ソートタブが表示されます。 All[すべて]タブはデフォルトで開きます。
このチャートのコメントでは、更新で始まるラインを見ることができます。 このラインには、直近のタブコンテンツ更新の日時があります。 Rキーを押して、現在のタブを手動で更新します。 また、ユーティリティ設定で、現在開いているタブコンテンツの更新周期性 (秒単位) を指定できます。
ユーティリティの設定といえば... 設定を考慮すると、ユーティリティの関数を理解する方がはるかに楽になります。
All[すべて] タブに表示されるシンボルの一覧は、フィルタ設定グループによって異なります。
ユーティリティによって表示されるシンボル ボタンをクリックすると、追加のデータを含む適切なシンボル チャートが開きます。
チャート上で最初に目に入るのはナビゲーションボタンです。 ユーティリティでソートされたシンボルから別のシンボルに移動できます。 また、ボタンを使用すると、"ホームワーク" タブ (LONG, SHORT, Range) シンボルを追加したり、そこからシンボルを削除したりできます。
また、チャートコメントには様々なシンボルデータがあります。 また、様々な水平線があります。
紫色の線は、年の高値/安値を示します。
赤いのはカスタムレベルを表します。 このユーティリティは、シンボル用に描画されたすべてのカスタムレベルを保存および復元できます。
既に述べたように、緑色の線は、おとといの始値/終値を表します。 スクリーンショットの最後のラインは、前日の始値/終値を意味します。
[チャート設定]グループは、シンボル チャートに表示する線とデータを定義します。
時間枠とチャート表示スケールもカスタマイズ可能です。 これは、All[すべて]タブ、"ホームワーク" タブ、および一部の自動並べ替えタブに対して個別に行われます。
All[すべて]タブの時間枠は、追加データグループで設定されます。
D1は、All[すべて] タブのすべてのシンボルボタンにデフォルトで使用します。 M15に変更してみましょう:
これより、ラインは1日未満の期間にのみ表示されるので、ユーティリティが表示できるチャート上の複数のラインを確認できます。
赤い垂直線は、現在のセッションが開始する足を示し、シンボルが今日上昇または下降しているかどうかを視覚的に判断しやすくします。
破線の水平線は、小数点以下2桁のクオートの場合は .00 または .50 で終わり、小数点以下4桁と5桁のクオートの場合は 0.x1000/0.xx500 で終わるラウンドレベルを示します (ここでは同様)。
しかし、この設定に戻りましょう。 自動並べ替えタブには、独自の設定もあります。 グローバルグループは、追加タブグループに配置されます。 また、一部のタブの設定を持つ別々のグループがあります。
設定の直近のグループは、新しいウィンドウと外部データでチャートを開きます。
新しいウィンドウでチャートを開くの設定は、新しいウィンドウをクリックしたときに開いたチャートの期間とスケールに影響します。
ユーティリティの機能の詳細については、このシリーズの前の記事にあります。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/5614
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索