The sixth part of the article about the universal Expert Advisor describes the use of the trailing stop feature. The article will guide you through how to create a custom trailing stop module using unified rules, as well as how to add it to the trading engine so that it would automatically manage positions.
CExpertSignal* CSignalAdapter::CreateSignal(MqlSignalParams& params)
{
DeleteSignal();
switch(params.signal_type)
{
case SIGNAL_AO:
m_signal = new CSignalAO();
break;
case SIGNAL_AC:
m_signal = new CSignalAC();
break;
case SIGNAL_ADAPTIVE_MA:
m_signal = new CSignalAMA();
break;
case SIGNAL_CCI:
m_signal = new CSignalCCI();
break;
case SIGNAL_DeMARKER:
m_signal = new CSignalDeM();
break;
case SIGNAL_DOUBLE_EMA:
m_signal = new CSignalDEMA();
break;
case SIGNAL_ENVELOPES:
m_signal = new CSignalEnvelopes();
break;
case SIGNAL_FRAMA:
m_signal = new CSignalFrAMA();
break;
case SIGNAL_MA:
m_signal = new CSignalMA();
break;
case SIGNAL_MACD:
m_signal = new CSignalMACD();
break;
case SIGNAL_PARABOLIC_SAR:
m_signal = new CSignalSAR();
break;
case SIGNAL_RSI:
m_signal = new CSignalRSI();
break;
case SIGNAL_RVI:
m_signal = new CSignalRVI();
break;
case SIGNAL_STOCHASTIC:
m_signal = new CSignalStoch();
break;
case SIGNAL_TRIPLE_EA:
m_signal = new CSignalTriX();
break;
case SIGNAL_TRIPLE_EMA:
m_signal = new CSignalTEMA();
break;
case SIGNAL_WILLIAMS_PER_RANGE:
m_signal = new CSignalWPR();
break;
}
if(CheckPointer(m_signal)!= POINTER_INVALID)
m_params = params;
return m_signal;
}
bool CSignalAdapter::Init()
{
if(m_params.symbol == "") /* CreateSignal method should be called first in order to update m_params */
return false;
m_info.Name(m_params.symbol);
if(!m_signal.Init(GetPointer(m_info), m_params.period, m_params.point))
return false;
if(!m_signal.InitIndicators(GetPointer(m_indicators)))
return false;
m_signal.EveryTick(m_params.every_tick);
m_signal.Magic(m_params.magic);
m_open.Create(m_params.symbol, m_params.period);
m_high.Create(m_params.symbol, m_params.period);
m_low.Create(m_params.symbol, m_params.period);
m_close.Create(m_params.symbol, m_params.period);
m_times.Create(m_params.symbol, m_params.period);
m_spread.Create(m_params.symbol, m_params.period);
m_tik_vol.Create(m_params.symbol, m_params.period);
m_real_vol.Create(m_params.symbol, m_params.period);
m_signal.SetPriceSeries(GetPointer(m_open), GetPointer(m_high), GetPointer(m_low), GetPointer(m_close));
//m_signal.SetOtherSeries(GetPointer(m_spread), GetPointer(m_times), GetPointer(m_tik_vol), GetPointer(m_real_vol));
int mask = 1;
mask = mask << m_params.usage_pattern;
m_signal.PatternsUsage(mask);
return true;
}
そしてもちろん、新しく作成したInitメソッドを呼び出す必要があります:
CAdapterMACD::CAdapterMACD(void)
{
m_params.symbol = Symbol();
m_params.period = Period();
m_params.every_tick = false;
m_params.signal_type = SIGNAL_MACD;
m_params.magic = 1234;
m_params.point = 1.0;
m_params.usage_pattern = 2;
CSignalMACD* macd = m_signal.CreateSignal(m_params);
macd.PeriodFast(15);
macd.PeriodSlow(32);
macd.PeriodSignal(6);
m_signal.Init(); /* This call is going to create the CSignalMACD object with the custom parameters */
}
バシリイの貢献に感謝する。とても勉強になりました。すべてのコードをダウンロードしましたが、Panel.mqh ファイルでコンパイルエラーが発生しました:
'At' - オブジェクトポインタが予想されます Panel.mqh 210 39
'At' - オブジェクトポインタが予想されます Panel.mqh 228 37
確認していただけますか?
エイミーさん、こんにちは。Vasiliy Sokolov の 記事を読み終えたところです。もしまだ解決策にご興味がおありでしたら、エラーログをこちらに投稿してください。エラーログをここに投稿してください。そのエラーに遭遇して、StrategiesList ファイルの宣言に「.˶PanelPanel.mqh」があることに気づきました。 Panel.mqh は存在しません。代わりに、https://www.mql5.com/ja/articles/2411 にアクセスし、そこから Panel File をダウンロードしてください。そこに Panel.mqh ファイルがあると思います。
Vasiliyのこのシリーズはフレームワークとして本当に良い。私も多くのことを学びましたが、ライブラリに問題がある場合、作者がサポートを提供しなければ、あなたが優秀なプログラマーでない場合、立ち往生することになりかねません。これは、アラン・ヴェルレーエンが 他のディスカッションで指摘していたことだ。しかし、ここで自分の知識と技術を共有するために時間を費やしている人たちは、まったく素晴らしい。私は永遠に感謝している。
このエンジンは本当に素晴らしい。私が乗り換えようと決めた最初のOOP MQL5エンジンです。
しかし、Manager.OnTick()は残念ながら非常に遅いです。トレースではほぼ100%です。テストは1分のタイムフレームとOHLC M1で非常に遅いです。3年間は約50秒です。同時に、Expert Advisor自体はテストのために何もしません。つまり、バーを検索するだけです。
Manager.OnTick()のコードを最適化 したい。
このエンジンは本当に素晴らしい。私が乗り換えようと決めた最初のOOP MQL5エンジンです。
しかし、Manager.OnTick()は残念ながら非常に遅いです。トレースではほぼ100%です。テストは1分のタイムフレームとOHLC M1で非常に遅いです。3年間は約50秒です。同時に、Expert Advisor自体はテストのために何もしません。つまり、バーを検索するだけです。
Manager.OnTick()のコードを最適化 したい。
もちろん、100%になります。この関数の中を見て、何に時間が費やされているかを確認し、最適化してください。スクリーンショットを公開してください。
このエンジンは本当に素晴らしい。私が乗り換えようと決めた最初のOOP MQL5エンジンです。
しかし、Manager.OnTick()は残念ながら非常に遅いです。トレースではほぼ100%です。テストは1分のタイムフレームとOHLC M1で非常に遅いです。3年間は約50秒です。同時に、Expert Advisor自体はテストのために何もしません。つまり、バーを検索するだけです。
Manager.OnTick()のコードを最適化 したい。
驚くようなことは何もありません。このスピードはストラテジー・テスターのアイドル動作に匹敵します。OnTick は新しいティックの発生と新しいバーのオープンを決定します。これらの操作は多くのリソースを必要としません。
こんにちは、バシリー。
いつも記事をありがとう。
Universal Expert Advisorは、複雑さとソフトウェアアーキテクチャの面で本当に印象的です。
この特定のバージョンについて、私はここのコードのこの部分のポイントを提起したいと思います:
CreateSignal()メソッドは、パラメータが 更新される前にMACDシグナルを初期化するからです。
この場合、CSignalAdapter::CreateSignal()メソッドを2つの部分に分割することをお勧めします。最初の部分では、シグナルが実際に作成され、そのまま返されます:
CExpertSignal* CSignalAdapter::CreateSignal(MqlSignalParams& params) { DeleteSignal(); switch(params.signal_type) { case SIGNAL_AO: m_signal = new CSignalAO(); break; case SIGNAL_AC: m_signal = new CSignalAC(); break; case SIGNAL_ADAPTIVE_MA: m_signal = new CSignalAMA(); break; case SIGNAL_CCI: m_signal = new CSignalCCI(); break; case SIGNAL_DeMARKER: m_signal = new CSignalDeM(); break; case SIGNAL_DOUBLE_EMA: m_signal = new CSignalDEMA(); break; case SIGNAL_ENVELOPES: m_signal = new CSignalEnvelopes(); break; case SIGNAL_FRAMA: m_signal = new CSignalFrAMA(); break; case SIGNAL_MA: m_signal = new CSignalMA(); break; case SIGNAL_MACD: m_signal = new CSignalMACD(); break; case SIGNAL_PARABOLIC_SAR: m_signal = new CSignalSAR(); break; case SIGNAL_RSI: m_signal = new CSignalRSI(); break; case SIGNAL_RVI: m_signal = new CSignalRVI(); break; case SIGNAL_STOCHASTIC: m_signal = new CSignalStoch(); break; case SIGNAL_TRIPLE_EA: m_signal = new CSignalTriX(); break; case SIGNAL_TRIPLE_EMA: m_signal = new CSignalTEMA(); break; case SIGNAL_WILLIAMS_PER_RANGE: m_signal = new CSignalWPR(); break; } if(CheckPointer(m_signal)!= POINTER_INVALID) m_params = params; return m_signal; } bool CSignalAdapter::Init() { if(m_params.symbol == "") /* CreateSignal method should be called first in order to update m_params */ return false; m_info.Name(m_params.symbol); if(!m_signal.Init(GetPointer(m_info), m_params.period, m_params.point)) return false; if(!m_signal.InitIndicators(GetPointer(m_indicators))) return false; m_signal.EveryTick(m_params.every_tick); m_signal.Magic(m_params.magic); m_open.Create(m_params.symbol, m_params.period); m_high.Create(m_params.symbol, m_params.period); m_low.Create(m_params.symbol, m_params.period); m_close.Create(m_params.symbol, m_params.period); m_times.Create(m_params.symbol, m_params.period); m_spread.Create(m_params.symbol, m_params.period); m_tik_vol.Create(m_params.symbol, m_params.period); m_real_vol.Create(m_params.symbol, m_params.period); m_signal.SetPriceSeries(GetPointer(m_open), GetPointer(m_high), GetPointer(m_low), GetPointer(m_close)); //m_signal.SetOtherSeries(GetPointer(m_spread), GetPointer(m_times), GetPointer(m_tik_vol), GetPointer(m_real_vol)); int mask = 1; mask = mask << m_params.usage_pattern; m_signal.PatternsUsage(mask); return true; }そしてもちろん、新しく作成したInitメソッドを呼び出す必要があります:
Vasily、素晴らしい仕事をありがとう!
ありがとう、
ロドリゴ・ハラー
著者は尊敬の多くを持っています。彼らはすべてが私たちの前に発明されたと言うように、もう一度私は実質的に何かをやったという事実に直面し、私は実質的に同じすでに前に行われた)を発見した。)
一つの瞬間、私は注意したい - 非常に最初から私に信号の仕事で売買する信号の加重平均を取る野生だった、それは正規の形式(ここですでに言及されている決定木、)で意思決定のロジックに適合していないと私はそうしました - 信号のプロジェニターは、方向が(-100から100まで)AND、ANDNOT、XOR上の信号のためのスロットが取られる信号の実際のリストに加えて含まれています。これらのスロットを処理するロジックはすべて、曖昧さを排除した形で始祖クラスに縫い込まれています。つまり、ストラテジーを構築するには、エキスパートアドバイザーにメインシグナルを追加し、対応するロジックスロットにシグナルを追加するだけです。私はこの解決策が最もシンプルで簡単に実現可能だと考えています。このアイデアに興味があり、わからないことがあれば、私にご連絡ください。
CSignalMACDクラスを スクリプトで使用する方法は?
インプレースでシグナルの結果を得ようとしましたが、いつも0でした: