
セマフォインディケーターを使った簡単なトレーディングシステム
はじめに
セマフォ、あるいはシグナルインディケーターはマーケットにエントリーするべきタイミングか、イグジットするべきタイミングかを示す簡単な発見器です。最新の足でエントリーシグナルが発生している場合、シンボルのチャート上にふさわしいラベルが出現します。このラベルは、取引を行うための条件として使われます。
そのようなインディケーターはたくさんありますが、そのインディケーターに基づくトレーディングシステムの本質は全く変わりません。ですから、もっともシンプルでユニバーサルな形でインプリメントするのが良いでしょう。そうすることで、得られた結果を似たようなインディケーターで使う時に、大きな変更を行う必要がなくなります。
図1. ASCtrendセマフォシグナルインディケーター
図 2. ASCtrendセマフォシグナルインディケーターを使用した取引を行うためのトレーディングシグナル
典型的なセマフォシグナルインディケーターのサンプル
現在、Code Baseにこのようなインディケーターがたくさんあります。この記事では、いくつかの有用なウエブページにのみリンクを張ります。
- BykovTrend,
- ASCtrend,
- BrainTrend1Sig,
- BrainTrend2Sig,
- SilverTrend_Signal,
- Stalin,
- WPRSI signal,
- StepMA_NRTR,
- LeManSignal,
- 3Parabolic System,
- PriceChannel_Stop,
- Arrows&Curves,
- Karacatica,
- Sidus.
セマフォシグナルインディケーターの他に、セマフォトレンドインディケーターがあります。
図 3. セマフォトレンドインディケーター
図 4. Heiken Ashi Smoothed semaphoreトレンドインディケーター
これらのインディケーターを使うトレーディングシステムのトレーディングシグナルを得るためのコードは少し変わりますが Expert Advisorのコードはほとんど変わりません。
典型的なセマフォトレンドインディケーターのサンプル
これらのインディケーターを豊富に含むコードベース。この記事では、いくつかの有用なウエブページにリンクを張ります。
- FiboCandles,
- Parabolic SAR,
- X2MA,
- Candles_Smoothed,
- SuperTrend,
- Go,
- 3LineBreak,
- Laguerre,
- Heiken Ashi Smoothed,
- NonLagDot.
トレードシステムを開発するための基礎データ
- Expert Advisorの中にあって表示されるべき入力パラメータを持ったセマフォインディケーター;
- 追加の入力となるExpert Advisorトレーディングパラメータのリスト:
- 取引に使用される入金された金融資産のシェア
- ストップロスとテイクプロフィットのサイズ (0値の場合は未処理のオーダーは使用できません);
- スリッページ(セットされた値と実際の約定価格との間の最大許容差);
- トレーディングシグナルが受信される足のインデックス;
- ロングとショートのポジションを開くための許可;
- インディケーターシグナルに応じた、ロングポジションとショートポジションの強制クローズの許可
もちろん、汎用のトレーディング関数を使いトレードオーダーを出せればはるかに便利です。これらの関数はかなり複雑で実行コードをできるだけシンプルにするために、別々のライブラリファイルに入れておくべきです。
セマフォトレーディングシステムをインプリメントするExpert Advisorのコード
//+------------------------------------------------------------------+ //| Exp_ASCtrend.mq5 | //| Copyright © 2011, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+------------------------------------------------------------------+ #property copyright "Copyright © 2011, Nikolay Kositsin" #property link "farria@mail.redcom.ru" #property version "1.00" //+----------------------------------------------+ //| Expert Advisor indicator input parameters | //+----------------------------------------------+ input double MM=-0.1; // Share of a deposit in a deal, negative values - lot size input int StopLoss_=1000; // Stop loss in points input int TakeProfit_=2000; // Take profit in points input int Deviation_=10; // Max. price deviation in points input bool BuyPosOpen=true; // Permission to buy input bool SellPosOpen=true; // Permission to sell input bool BuyPosClose=true; // Permission to exit long positions input bool SellPosClose=true; // Permission to exit short positions //+----------------------------------------------+ //| ASCtrend indicator input parameters | //+----------------------------------------------+ input ENUM_TIMEFRAMES InpInd_Timeframe=PERIOD_H1; // ASCtrend indicator time frame input int RISK=4; // Risk level input uint SignalBar=1; // Bar index for getting an entry signal //+----------------------------------------------+ int TimeShiftSec; //---- declaration of integer variables for the indicators handles int InpInd_Handle; //---- declaration of integer variables of the start of data calculation int min_rates_total; //+------------------------------------------------------------------+ //| Trading algorithms | //+------------------------------------------------------------------+ #include <TradeAlgorithms.mqh> //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //---- getting ASCtrend indicator handle InpInd_Handle=iCustom(Symbol(),InpInd_Timeframe,"ASCtrend",RISK); if(InpInd_Handle==INVALID_HANDLE) Print(" Failed to get handle of ASCtrend indicator"); //---- initialization of a variable for storing a chart period in seconds TimeShiftSec=PeriodSeconds(InpInd_Timeframe); //---- initialization of variables of the start of data calculation min_rates_total=int(3+RISK*2+SignalBar); //---- return(0); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //---- GlobalVariableDel_(Symbol()); //---- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //---- checking the number of bars to be enough for calculation if(BarsCalculated(InpInd_Handle)<min_rates_total) return; //---- uploading history for IsNewBar() and SeriesInfoInteger() functions normal operation LoadHistory(TimeCurrent()-PeriodSeconds(InpInd_Timeframe)-1,Symbol(),InpInd_Timeframe); //---- declaration of local variables double DnVelue[1],UpVelue[1]; //---- declaration of static variables static bool Recount=true; static bool BUY_Open=false,BUY_Close=false; static bool SELL_Open=false,SELL_Close=false; static datetime UpSignalTime,DnSignalTime; static CIsNewBar NB; //+----------------------------------------------+ //| Searching for deals performing signals | //+----------------------------------------------+ if(!SignalBar || NB.IsNewBar(Symbol(),InpInd_Timeframe) || Recount) // checking for a new bar { //---- zeroing out trading signals BUY_Open=false; SELL_Open=false; BUY_Close=false; SELL_Close=false; Recount=false; //---- copy newly appeared data into the arrays if(CopyBuffer(InpInd_Handle,1,SignalBar,1,UpVelue)<=0) {Recount=true; return;} if(CopyBuffer(InpInd_Handle,0,SignalBar,1,DnVelue)<=0) {Recount=true; return;} //---- getting buy signals if(UpVelue[0] && UpVelue[0]!=EMPTY_VALUE) { if(BuyPosOpen) BUY_Open=true; if(SellPosClose) SELL_Close=true; UpSignalTime=datetime(SeriesInfoInteger(Symbol(),InpInd_Timeframe,SERIES_LASTBAR_DATE))+TimeShiftSec; } //---- getting sell signals if(DnVelue[0] && DnVelue[0]!=EMPTY_VALUE) { if(SellPosOpen) SELL_Open=true; if(BuyPosClose) BUY_Close=true; DnSignalTime=datetime(SeriesInfoInteger(Symbol(),InpInd_Timeframe,SERIES_LASTBAR_DATE))+TimeShiftSec; } //---- searching for the last trading direction for getting positions closing signals //if(!MQL5InfoInteger(MQL5_TESTING) && !MQL5InfoInteger(MQL5_OPTIMIZATION)) //if execution is set to "Random delay" in the Strategy Tester if((BuyPosOpen && BuyPosClose || SellPosOpen && SellPosClose) && (!BUY_Close && !SELL_Close)) { int Bars_=Bars(Symbol(),InpInd_Timeframe); for(int bar=int(SignalBar+1); bar<Bars_; bar++) { if(SellPosClose) { if(CopyBuffer(InpInd_Handle,1,bar,1,UpVelue)<=0) {Recount=true; return;} if(UpVelue[0]!=0 && UpVelue[0]!=EMPTY_VALUE) { SELL_Close=true; break; } } if(BuyPosClose) { if(CopyBuffer(InpInd_Handle,0,bar,1,DnVelue)<=0) {Recount=true; return;} if(DnVelue[0]!=0 && DnVelue[0]!=EMPTY_VALUE) { BUY_Close=true; break; } } } } } //+----------------------------------------------+ //| Performing deals | //+----------------------------------------------+ //---- Closing a long position BuyPositionClose(BUY_Close,Symbol(),Deviation_); //---- Closing a short position SellPositionClose(SELL_Close,Symbol(),Deviation_); //---- Buying BuyPositionOpen(BUY_Open,Symbol(),UpSignalTime,MM,0,Deviation_,StopLoss_,TakeProfit_); //---- Selling SellPositionOpen(SELL_Open,Symbol(),DnSignalTime,MM,0,Deviation_,StopLoss_,TakeProfit_); //---- } //+------------------------------------------------------------------+
いくつかの細かな点は明確にする必要がありますが、このアイデアを実現するためのコードはとても簡単で明快です。
シグナルインディケーターとExpert Advisorで使用されるチャートの期間はExpert AdvisorのInpInd_Timeframe入力変数で固定されています。そのため、Expert Advisorが置かれたチャートの変化によりExpert Advisorのこのパラメータが変更されることはありません。
新しい足の出現を決定するためのIsNewBar()関数はTradeAlgorithms.mqhファイルに置かれたクラスとしてインプリメントされます。これにより、コードにあるこのような関数はいくつでもそれぞれに静的なCIsNewBar変数を設定することで簡単に使うことができます。
UpSignalTimeとDnSignalTime変数が時間の保存とトレーディング関数への転送に使われ、その後で前の取引の後に新たな取引を行うことが可能になります。今回のケースではこの機能は同じ足で同じ方向への複数の取引を防ぐために使います(取引を行うと、トレーディング関数が最新の足の終わりの時間を保管し、同じ方向への新しい取引を行いません)。
”ポジションを閉じるシグナルを得るために最後の取引の方向を検索する”というOnTick()関数内のブロックは、トレーディングシグナルのない足でポジションを閉じるためのシグナルを受け取るために必要です。Expert Advisorの通常の動作中にはその必要ありません。しかし、ネット接続の障害が起こると新しいトレーディングシグナルが失われてしまうことがあります。その後でそのマーケットに入るのはまったく良いアイデアではありませんが、開いたポジションを閉じるのは賢い選択でしょう。
他のセマフォシグナルインディケーターを使ったトレーディングシステム
さて、このコードを他のマフォシグナルインディケーターで使う必要が出てきたとき、次のアクションが実行されるはずです:
- 必要なExpert Advisorの新しい入力パラメータでこれまでのインディケーターのデータを置き換えます。
- OnInit() ブロックにあるインディケーターハンドルを取得するためのコードを変更します;
- インディケーターのコードの売買トレーディングシグナルを格納するためのインディケーターバッファのインデックスを決定し、それをOnTick()ブロックのCopyBuffer()関数呼び出しに正しく入力します。この場合は、0と1番目のインディケーターバッファが使用されます;
- Expert Advisor にあるデータ計算の開始ポイント変数(min_rates_total)の初期設定をインディケーターコードに対応して変更します;
- ”ポジションを閉じるシグナルを得るために最後の取引の方向を検索する”というOnTick()関数内のブロックをインディケーターコードに応じて変更します。
他のセマフォトレンドインディケーターを使ったトレーディングシステム
セマフォトレンドインディケーターを使ったこのトレーディングシステムの使用では、Expert AdvisorコードはOnTick()関数の取引シグナルを決めるためのブロックで少し変更があります。例えば、FiboCandlesインディケーターに基づくExpert Advisorのコードは次のようになります。
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //---- checking the number of bars to be enough for calculation if(BarsCalculated(InpInd_Handle)<min_rates_total) return; //---- uploading history for IsNewBar() and SeriesInfoInteger() functions LoadHistory(TimeCurrent()-PeriodSeconds(InpInd_Timeframe)-1,Symbol(),InpInd_Timeframe); //---- declaration of local variables double TrendVelue[2]; //---- declaration of static variables static bool Recount=true; static bool BUY_Open=false,BUY_Close=false; static bool SELL_Open=false,SELL_Close=false; static datetime UpSignalTime,DnSignalTime; static CIsNewBar NB; //+----------------------------------------------+ //| Searching for deals performing signals | //+----------------------------------------------+ if(!SignalBar || NB.IsNewBar(Symbol(),InpInd_Timeframe) || Recount) // checking for a new bar { //---- zeroing out trading signals BUY_Open=false; SELL_Open=false; BUY_Close=false; SELL_Close=false; Recount=false; //---- copy the newly obtained data into the arrays if(CopyBuffer(InpInd_Handle,4,SignalBar,2,TrendVelue)<=0) {Recount=true; return;} //---- getting buy signals if(TrendVelue[0]==1 && TrendVelue[1]==0) { if(BuyPosOpen) BUY_Open=true; if(SellPosClose)SELL_Close=true; UpSignalTime=datetime(SeriesInfoInteger(Symbol(),InpInd_Timeframe,SERIES_LASTBAR_DATE))+TimeShiftSec; } //---- getting sell signals if(TrendVelue[0]==0 && TrendVelue[1]==1) { if(SellPosOpen) SELL_Open=true; if(BuyPosClose) BUY_Close=true; DnSignalTime=datetime(SeriesInfoInteger(Symbol(),InpInd_Timeframe,SERIES_LASTBAR_DATE))+TimeShiftSec; } //---- searching for the last trading direction for getting positions closing signals //if(!MQL5InfoInteger(MQL5_TESTING) && !MQL5InfoInteger(MQL5_OPTIMIZATION)) //if execution is set to "Random delay" in the Strategy Tester { if(SellPosOpen && SellPosClose && TrendVelue[1]==0) SELL_Close=true; if(BuyPosOpen && BuyPosClose && TrendVelue[1]==1) BUY_Close=true; } } //+----------------------------------------------+ //| Performing deals | //+----------------------------------------------+ //---- Closing a long position BuyPositionClose(BUY_Close,Symbol(),Deviation_); //---- Closing a short position SellPositionClose(SELL_Close,Symbol(),Deviation_); //---- Buying BuyPositionOpen(BUY_Open,Symbol(),UpSignalTime,MM,0,Deviation_,StopLoss_,TakeProfit_); //---- Selling SellPositionOpen(SELL_Open,Symbol(),DnSignalTime,MM,0,Deviation_,StopLoss_,TakeProfit_); //---- }
この場合、トレーディングシグナルは1つのカラーインディケーターバッファ(カラーインデックスを含む)からしかシグナルを受け取りません。このバッファのデータは2つの値しか持てません:0 - は上昇相場で1 - は下落相場です。ある足におけるトレンドの方向はインディケーターバッファのセルから直接受け取れるため、”ポジションを閉じるシグナルを得るために最後の取引の方向を検索する”ブロックは可能な限りシンプルになります。
”取引を実行する”ブロックでは、ポジションを閉じる関数がまず実行され、次にポジションを開く関数が実行されます。反対の場合には、1つの足ではポジションを閉じることしかできません。オープンプライスオンリー"モードでテストしている場合は同時に開くことはできません!そのため、トレードの結果にとって深刻な中断となります。
トレーディングシステムのテスト
トレーディングシステムのテストを行う前に、重要なことを1つ明確にする必要があります。SignalBar入力変数が0である場合、Expert Advisorは現在の足から取引実行シグナルを取得します。しかし現在の足のシグナルが、前の足のそのシグナルのトレンドに反する変化があった場合、信頼できません。最新の足のシグナルは出たり消えたりします、一方トレンドはそのようなシグナルに対してかなり長い間かけて動きます。このことは、あるExpert Advisorがすべてのティックに対して視覚化を有効にしてテストされ、SignalBar変数が0であるなら、簡単に見ることができます。ASCtrenインディケーター動作の視覚化が、こういった場合の事実を明確に表します。
ここでも、”ティック毎”モードだけがExpert Advisorの現在の足から受け取ったシグナルの最適化に適しています。過去の足からだけシグナルを受け取る場合は”オープンプライスオンリー”モードでも十分です。それにより、システムの質を落とすことなくトレーディングシステムの動作解析を大きく加速します。
ですから、このようなトレーディングシステムのテストや最適化のためには現在の足からのシグナルを使用しない方が良いのです。
それでは、EUR/USDについてデフォルトパラメータでExpert Advisorを1月1日から12月1日までテストしてみましょう:
図 5. EUR/USD 1時間足についてデフォルトパラメータでExp_ASCtrend Expert Advisorをテストした結果
ストラテジーテスターのExpert Advisorの設定を少し変更することで、既存の過去データとExpert Advisorのパラメータのベストな組み合わせを簡単に見つけることができます:
図 6. パラメータの最適化を行った後の改良パラメーターでEUR/USD 1時間足を Exp_ASCtrend Expert Advisorのでテストした結果
トレーディングシステムの最適化プロセスにはいかなる特殊性もありません。このため、このプロセスを詳しく説明するためのリンクは1つしか貼りません:"MQL5: Guide to Testing and Optimizing of Expert Advisors in MQL5"(MQL5: Expert Advisorsのテストと最適化のためのガイド)。
もちろん、このような簡単なトレーディングシステムから巨大な利益を得られると期待するのは調子が良すぎるでしょう。しかし、この半自動のシステムを正しく使うスキルがあり、マーケットの変化に合わせて規則的に調節することができれば、良い結果を得ることが十分可能です。
例えばEUR/USDの12時間足には2011年の1月から5月まで上昇トレンドがありました。そして、それを初期の段階で把握するのは簡単なことでした:
図 7. EUR/USD 12時間足(2011年1月/5月)
Expert Advisorをこの期間にデフォルトの設定でテストしてみるのは興味深いでしょう。ポジションは買うだけにし、資金の5%のみを使うように設定しましょう(MM=0.05)。これがそのパラメータを使いExpert Advisorを1時間足でテストした結果です:
図 8. デフォルトのパラメータを持つ Exp_ASCtrend Expert Advisorを EUR/USD1時間足に2011年の1月/5月で(買いポジションのみ、MM=0.05) テストした結果
もちろん、トレーダーに取引の方向を決める責任があります。しかし、覚えていてほしいのは、長いタイムフレームのチャートを使えば難しくはないということです。
他のインディケーターと一緒に使うトレーディングモジュールの変更
この記事はここで終わりにしても良いのですが、MetaEditorは既製のトレーディングモジュールを基にしたExpert Advisorsを生成することができるようになりました。ここで紹介されているすべてのものを考慮してこのようなモジュールを作成するプロセスは非常に複雑で別の勉強が必要です。ですので、提案したシステムに類似した既製のトレーディングモジュールについて説明します。そしてその後で、必要のないdetalizationを避ける特別なシグナルインディケーターに対応したこれらのモジュールの変更について詳しく説明します。
セマフォシグナルシステム(MySignals.zip) のトレーディングモジュールのコレクションをすでに持っていて、いずれか特定のインディケーターの類似モジュールを作成したいと仮定しましょう。それは典型的なセマフォシグナルインディケーターであるBykovTrendSignal.mq5インディケーターであるとしょう。まず、このコレクション(Indicators.zip)からこのインディケーターのもっとも正確なアナログを見つけましょう。この記事で最初に紹介したインディケーター(ASCtrend)が一番似ているように見えます。そこで、このインディケーターのトレーディングモジュールをモディフィケーションしてみましょう。
必要とされるコードでのその使用を考えてみましょう。インディケーター自身(BykovTrend)は入力パラメータのセットを持っています:
//+----------------------------------------------+ //| Indicator input parameters | //+----------------------------------------------+ input int RISK=3; input int SSP=9; //+----------------------------------------------+
そして、取引を実行するためのシグナルを保管するインディケーターバッファのインデックスが必要です。今回は: 0 - 売りシグナル と 1 - 買いシグナルです。
これで、どのモジュールをモディフィケーションに使えば良いかが分かりました。\MQL5\Include\Expert\Signal\MySignals\フォルダに BykovTrendSignal.mqhをファイル名と一緒にコピーし、MetaEditorで開きます。使用されたコードには頻繁に目にする”ASCtrend ”(前のインディケーターの名前)という表現があります。新しいインディケーター - "BykovTrend"に置き換えましょう。そのためには、”Ctrl”と”H”キーを同時に押して必要な変更を行います:
図 9. インディケーター名をトレーディングモジュールコード内で置き換えます。
次のステージはもっとも気をつかいます。トレーディングモジュールコード内のインディケーターインプットに関わるすべてのものを置き換えなければなりません。このプロセスは”MQL5 Wizard: How to create a module of trading signals”に書かれているものととても似ています。
まず、MQL5 ウィザード・トレーディングシグナルクラスのディスクリプションのコメントアウトブロックを変更します:
//+----------------------------------------------------------------------+ //| Description of the class | //| Title=The signals based on BykovTrend indicator | //| Type=SignalAdvanced | //| Name=BykovTrend | //| Class=CBykovTrendSignal | //| Page= | //| Parameter=BuyPosOpen,bool,true,Permission to buy | //| Parameter=SellPosOpen,bool,true,Permission to sell | //| Parameter=BuyPosClose,bool,true,Permission to exit a long position | //| Parameter=SellPosClose,bool,true,Permission to exit a short position | //| Parameter=Ind_Timeframe,ENUM_TIMEFRAMES,PERIOD_H1,Timeframe | //| Parameter=RISK,int,4,Risk level | //| Parameter=SSP,int,9,SSP | //| Parameter=SignalBar,uint,1,Bar index for entry signal | //+----------------------------------------------------------------------+ //--- wizard description end //+----------------------------------------------------------------------+ //| CBykovTrendSignal class. | //| Purpose: Class of generator of trade signals based on | //| BykovTrend indicator https://www.mql5.com/ru/code/497/. | //| Is derived from the CExpertSignal class. | //+----------------------------------------------------------------------+
両方のパラメータには同じRISK入力変数が含まれますので、そのままにしておきます。しかし、それぞれのデフォルト値は異なります。実際のところ、この違いは重要ではないのでそのままにしておきます。SSP変数に関するコメントラインが追加されました:
//| Parameter=SSP,int,9,SSP |
そしてCodeBaseインディケーターへのリンクが置換されました:
//| Purpose: Class of generator of trade signals based on | //| BykovTrend values https://www.mql5.com/ru/code/497/. |
これで、入力パラメータの変更に関することはすべてCBykovTrendSignalトレーディングシグナルクラスのディスクリプションに反映されました。変数の設定に新しいグローバルm_SSPクラス変数の宣言の行があります。
uint m_SSP; // SSP
新しいSSP()の設定パラメータのインストールメソッドの宣言の行があります:
void SSP(uint value) { m_SSP=value; }
ここで作成したトレーディングシグナルモジュール内のRISK入力変数は、入力モジュールと等しいため、すべてのトレーディングモジュールブロック内での変更はありません。
では、CBykovTrendSignal::CBykovTrendSignal() クラスコンストラクタに渡しましょう。新しい変数の初期化はこのブロックに追加しなければなりません:
m_SSP=4;
新しい変数の正しさの確認はCBykovTrendSignal::ValidationSettings()パラメータの検証ブロックの設定で行われなければなりません:
if(m_SSP<=0) { printf(__FUNCTION__+": SSP must be above zero"); return(false); }
BykovTrend インディケーター初期化ブロックにパスした後- BykovTrendSignal::InitBykovTrend()。新しいインディケーターは異なる数の入力変数を持ちます。ですので宣言された入力パラメータの次元もそれぞれ異なります:
//--- setting the indicator parameters MqlParam parameters[3];
今回は、インディケーターの文字列名には1次元、その入力パラメータには2次元必要です。
入力パラメータの新しいセルを初期化し、そこに格納する変数の型を示さなければいけません:
parameters[2].type=TYPE_INT; parameters[2].integer_value=m_SSP;
その変更の後に、このブロックのインディケーターの初期化の呼び出しの中の入力変数の数を3に変えます。
//--- object initialization if(!m_indicator.Create(m_symbol.Name(),m_Ind_Timeframe,IND_CUSTOM,3,parameters))
インディケーターのインディケーターバッファの数は2のまま変わりません。ですので、インディケーターバッファのナンバー初期化の行は何も変更する必要はありません。
//--- number of buffers if(!m_indicator.NumBuffers(2)) return(false);
ASCtrendとBykovTrendインディケーターはそれぞれ2つのバッファを持ちます。バッファの関数はそっくりです。売りシグナルの保管に0バッファは使われ、インデックス1のバッファは買いシグナルの保管のために使われます。ですからCBykovTrendSignal::LongCondition() やCBykovTrendSignal::ShortCondition()トレーディングシグナル を送るための関数のブロックは何も変更する必要がありません。そしてトレーディングシグナルモジュールのモディフィケーションは完了したと考えてよいでしょう。
しかし、一般的に、すべてのセマフォインディケーターは異なっているため、異なるセマフォインディケーターのブロックもそれぞれ大きく異なることがあります。MySignals.zipトレーディングモジュールアーカイブとIndicators.zipアーカイブには様々なインディケーターを作成するために十分なサンプルが含まれています。いくつか詳しく見てみれば、置換プロセスとそのためのコードについてよく分かると思います。
次に、トレーディングシグナルモジュールのInd_Timeframe入力変数を見てみたいと思います。この変数を使うと、インディケーターのためにタイムフレームをダウンロードすることができます。しかし、作られたExpert Advisorは割り当てられたタイムフレームで動作します。つまり、Ind_Timeframe入力変数のタイムフレームはモジュールに通常の動作をさせるためにExpert Advisorの動作するチャートの期間を超えてはいけないということです。
最後に、 トレーディングシグナルモジュールの作成のもう1つの特殊性を紹介しましょう。カスタムエニュメレーションはベーシックインディケーターのコードに、モジュール入力変数の型としてインプリメントされることがあります。例えば、Smooth_MethodのカスタムエニュメレーションはCandles_SmoothedインディケーターのMA_SMethod変数の型として使用されます:
//+-----------------------------------+ //| Declaration of enumerations | //+-----------------------------------+ enum Smooth_Method { MODE_SMA_, // SMA MODE_EMA_, // EMA MODE_SMMA_, // SMMA MODE_LWMA_, // LWMA MODE_JJMA, // JJMA MODE_JurX, // JurX MODE_ParMA, // ParMA MODE_T3, // T3 MODE_VIDYA, // VIDYA MODE_AMA, // AMA }; */ //+----------------------------------------------+ //| Indicator input parameters | //+----------------------------------------------+ input Smooth_Method MA_SMethod=MODE_LWMA; // Smoothing method input int MA_Length=30; // Smoothing depth input int MA_Phase=100; // Smoothing parameter // for JJMA varying within the range -100 ... +100, // for VIDIA it is a CMO period, for AMA it is a slow average period //+----------------------------------------------+
このような場合、その種類の変数とそれに関連するトレーディングシグナル(Candles_SmoothedSignal.mqh) 内のすべての要素は int型かuint型の変数に変換されなければなりません。また、カスタムエニュメレーションからExpert Advisor入力変数と必要な入力変数の型の置換 (ExpM_Candles_Smoothed Expert Advisor) までの逆の手順は完成したEAで生成されたコード内の入力変数を使用しやすいように実行されなければなりません。
//+------------------------------------------------------------------+ //| Declaration of enumerations | //+------------------------------------------------------------------+ enum Smooth_Method { MODE_SMA_, // SMA MODE_EMA_, // EMA MODE_SMMA_, // SMMA MODE_LWMA_, // LWMA MODE_JJMA, // JJMA MODE_JurX, // JurX MODE_ParMA, // ParMA MODE_T3, // T3 MODE_VIDYA, // VIDYA MODE_AMA, // AMA }; //+------------------------------------------------------------------+ //| Inputs | //+------------------------------------------------------------------+ //--- inputs for expert input string Expert_Title ="Candles_Smoothed"; // Document name ulong Expert_MagicNumber =29976; // bool Expert_EveryTick =false; // //--- inputs for main signal input int Signal_ThresholdOpen =40; // Signal threshold value to open [0...100] input int Signal_ThresholdClose=20; // Signal threshold value to close [0...100] input double Signal_PriceLevel =0.0; // Price level to execute a deal input double Signal_StopLevel =50.0; // Stop Loss level (in points) input double Signal_TakeLevel =50.0; // Take Profit level (in points) input int Signal_Expiration =1; // Expiration of pending orders (in bars) input bool Signal__BuyPosOpen =true; // Candles_Smoothed() Permission to buy input bool Signal__SellPosOpen =true; // Candles_Smoothed() Permission to sell input bool Signal__BuyPosClose =true; // Candles_Smoothed() Permission to exit a long position input bool Signal__SellPosClose =true; // Candles_Smoothed() Permission to exit a short position input ENUM_TIMEFRAMES Signal__Ind_Timeframe=PERIOD_H1; // Candles_Smoothed() Timeframe input Smooth_Method Signal__MA_SMethod =4; // Candles_Smoothed() Smoothing method (1 - 10) input uint Signal__MA_Length =30; // Candles_Smoothed() Smoothing depth input uint Signal__MA_Phase =100; // Candles_Smoothed() Smoothing parameter input uint Signal__SignalBar =1; // Candles_Smoothed() Bar index for the entry signal input double Signal__Weight =1.0; // Candles_Smoothed() Weight [0...1.0] //--- inputs for money input double Money_FixLot_Percent =10.0; // Percent input double Money_FixLot_Lots =0.1; // Fixed volume
今回はSignal__MA_SMethod入力変数によって行われました。
2つのコードバージョン (ASCtrendSignal.mqh and BykovTrendSignal.mqh)をエディターで両方開き(左右に並べて)それぞれのバージョンを注意深く比較すれば、コードの変更スピードをかなり加速することができます。
まとめ
この記事に添付されたExperts.zipアーカイブには、Expert Advisorの開発の初心者の方が、書かれたコードの機能の理解や、とても人気のある既製のインディケーターを使うことができるようになるための、豊富なセマフォトレーディングシステムに基づいたExpert Advisorが入っています。
添付されたすべてのExpert Advisorは、自身のトレーディングシステムの基礎としてトレーディングストラテジーのジェネレーターを使いたい人たちのために、追加のトレーディングモジュールとして提供されています。これらのモジュールはMySignals.zipに入っていて、それに基づいたトレーディングシステムはExpertsez.zipに入っています。Expert Advisorsで使われるインディケーターはIndicators.zipに入っています。解凍するためのパスは次の通りです:
- Experts.zip: "\MQL5\Experts\";
- Expertsez.zip: "\MQL5\Experts\";
- MySignals.zip: "\MQL5\Include\Expert\Signal\MySignals\";
- Indicators.zip: "\MQL5\Indicators\";
- SmoothAlgorithms.mqh: "\Include\";
- TradeAlgorithms.mqh: "\Include\".
MetaEditorを再起動し、ナビゲータウインドウを開き、MQL5ラベルを右クリックしてポップアップメニューの”コンパイル”をクリックします。
SmoothAlgorithms.mqhファイルがIndicators.zipのいくつかのインディケーターのコンパイルには必要で、Experts.zipのすべてのExpert AdvisorのコンパイルにはTradeAlgorithms.mqhファイルが必要です。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/358





- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索