こんにちは、エンリコ。私の問題を解決するために、あなたの作品を拝見しています。StopBaseクラスをコンパイルすると、エラーのリストが表示されます。
implicit conversion from 'number' to 'string' OrderStopBase.mqh 395 25 implicit conversion from 'number' to 'string' OrderStopBase.mqh 467 26 implicit enum conversion OrderStopBase.mqh 468 33 implicit enum conversion OrderStop.mqh 37 33 implicit conversion from 'number' to 'string' OrderStop.mqh 44 43 'COrderBase' - import not defined OrderStop.mqh 54 7 'else' - semicolon expected OrderStop.mqh 81 4 ')' - unexpected token OrderStop.mqh 81 46 implicit conversion from 'number' to 'string' StopBase.mqh 767 22 implicit conversion from 'number' to 'string' StopBase.mqh 774 28 implicit conversion from 'number' to 'string' StopBase.mqh 796 22 implicit conversion from 'number' to 'string' StopBase.mqh 803 28 implicit conversion from 'number' to 'string' StopBase.mqh 698 36 'OrderType' - cannot convert enum Stop.mqh 227 52 'StopLossCustom' - no one of the overloads can be applied to the function call Stop.mqh 228 61 could be one of 2 function(s) Stop.mqh 228 61 double CStopBase::StopLossCustom(const string,const ENUM_ORDER_TYPE,const double) StopBase.mqh 136 22 bool CStopBase::StopLossCustom() StopBase.mqh 99 22 'OrderType' - cannot convert enum Stop.mqh 215 71 'TakeProfitCustom' - no one of the overloads can be applied to the function call Stop.mqh 215 98 could be one of 2 function(s) Stop.mqh 215 98 double CStopBase::TakeProfitCustom(const string,const ENUM_ORDER_TYPE,const double) StopBase.mqh 140 22 bool CStopBase::TakeProfitCustom() StopBase.mqh 111 22 implicit conversion from 'number' to 'string' Stop.mqh 250 39 implicit enum conversion Stop.mqh 291 31 implicit conversion from 'number' to 'string' Stop.mqh 292 36
警告を無視すると、エラーはオーダータイプの問題から来ているようです。また、例のsignal_maをコンパイルすると、以下のエラーが発生します。
'GetPointer' - parameter conversion not allowed OrderStopVirtualBase.mqh 51 39 'GetPointer' - parameter conversion not allowed OrderStopVirtualBase.mqh 58 41 '=' - type mismatch OrderStopsBase.mqh 106 23 '=' - type mismatch OrderStopsBase.mqh 108 23 '=' - type mismatch OrderStopsBase.mqh 110 23 '=' - type mismatch OrderStopsBase.mqh 180 20 '=' - type mismatch OrderStopsBase.mqh 182 20 '=' - type mismatch OrderStopsBase.mqh 184 20
これらのエラーはどこから来ているのでしょうか? 関連する問題ですが、私の理解では、リスコフ代入は、スーパークラスがその基底クラスで代入できるように、インターフェイスにプログラムすることを規定しています。なぜオブジェクトを基底クラスで代用するのではなく、関数(それ自体がインターフェイスである)に渡すことにしたのですか?間違っているかもしれませんが、それがベストプラクティスではないでしょうか?
あなたの助けに感謝します。シェパードさん、コメントありがとうございます。ご質問の件ですが
- 残念ながら、現時点ではStopBase.mqhを単独でコンパイルする方法はありません。MQL4およびMQL5コンパイラーは前方宣言を受け付けますが、前方宣言されたクラスのメソッドやメンバーにアクセスしようとするとエラーになります。StopBase.mqhをCOrderManagerやCExpertAdvisor(CStopとCStopsはこれら2つのクラスのコンポーネントです)などのはるかに大きなクラスとコンパイルする必要があります。
- タイプ・ミスマッチ・エラーについては、オリジナルのファイルでは見つけられませんでした(ソースはあなたの側で修正されたのでしょうか)。
- ほとんどの場合、ベース・クラスは問題なくクラス・メソッドに渡すことができると思います。エキスパートにライブラリを使わせる場合、基底クラスは存在しないと考えた方が楽でしょう。しかし、オブジェクトの中には、非仮想メソッドだけでなく、新しい仮想メソッドを持っているものもある。この2つのメソッドは、基底クラスだけではアクセスできない。基底クラスの代わりに派生クラスを使えば、コンパイラーは派生クラスの正しいバージョンを選択することができるので、派生クラスを使う方が基底クラスだけを使うよりも包括的です。
シェパードさん、コメントありがとうございます。ご質問の件ですが
- 残念ながら、現時点ではStopBase.mqhを単独でコンパイルする方法はありません。MQL4およびMQL5コンパイラーは前方宣言を受け付けますが、前方宣言されたクラスのメソッドやメンバーにアクセスしようとするとエラーになります。StopBase.mqhをCOrderManagerやCExpertAdvisor(CStopとCStopsはこれら2つのクラスのコンポーネントです)などのはるかに大きなクラスとコンパイルする必要があります。
- タイプ・ミスマッチ・エラーについては、オリジナルのファイルでは見つけられませんでした(ソースはあなたの側で修正されたのでしょうか)。
- ほとんどの場合、ベース・クラスは問題なくクラス・メソッドに渡すことができると思います。エキスパートにライブラリを使わせる場合、基底クラスは存在しないと考えた方が楽でしょう。しかし、オブジェクトの中には、非仮想メソッドだけでなく、新しい仮想メソッドを持っているものもある。この2つのメソッドは、基底クラスだけではアクセスできない。基底クラスの代わりに派生クラスを使えば、コンパイラーは派生クラスの正しいバージョンを選択することができるので、派生クラスを使う方が基底クラスだけを使うよりも包括的です。
こんにちは、エンリコ、
素早い回答をどうもありがとう。基底クラスの代わりに具象クラスを渡す理由は理解できます。C++では簡単な実装でも、MQLでは不可能なことがあります。
型の不一致に関しては、何も変更していません。単にダウンロードしてコンパイルしただけだ。あなたのアプローチは本当に素晴らしい。
私は自分のシステムをこのように開発した。シグナルを出力するシステムをストラテジーと考えました。 例えば、MAクロスオーバーの システムを持っているとします。しかし、ストラテジーはOnTickで呼び出されるのではなく、オブザーバー・パターンの一部として呼び出されます。 例えば、5分足の新しいバー、10Pip Renkoの新しいバーなど、特定のイベントが発生したときに更新されたり、呼び出されたりします。
あなたの知識と技術を共有するために時間を割いていただき、迅速な対応に改めて感謝します。
こんにちは、シェパード、
あなたの提案と洞察をシェアしてくれてありがとう。
あなたが取り組んでいることは素晴らしいアイデアだと思います。現在、このシリーズの最後の数記事(オーダーストップとストップを含む)を執筆中です。 ストップクラスが適しているかどうかはわかりません(実装次第です)。もし、オーダーマネージャーから 独立して動作させることができるのであれば、それはクラスオブジェクトを単純化するのに役立つので良いでしょう。しかし、あなたの仕事に役立つことを期待しています。
コンパイルについて:
- エラーなしでコンパイルできるのは、メイン・ソース/ヘッダー・ファイルとベース・クラス・ファイルだけです(前方宣言を使用しているものは例外です)。例題で、ベース・ファイル用のヘッダー・ファイルに#includeディレクティブを使用したのはこのためです(言語固有のファイルではありません)。
- 正しいコンパイラーを使用すべきである(MQL4コンパイラーでmq5ファイルをコンパイルすると、コンパイラー・エラーにつながる)。
こんにちは、エンリコ、
御社のシグナルモジュールをテストしています。SHORTシグナルとNEUTRALシグナルを1つずつ持っています。最終的にCMD_VOIDが表示されたのはなぜですか?CMD_VOIDはいつ現れるのですか?
実はこれはCSignalsBase::Checkで 表示されます。
if(signal.Entry()) { if(m_signal_open>CMD_VOID) { ENUM_CMD signal_open=signal.SignalOpen(); if(m_signal_open==CMD_NEUTRAL) { m_signal_open=signal_open; } else if(m_signal_open!=signal_open) { m_signal_open=CMD_VOID; } } }
シグナルは2つしかない。前のシグナルはCMD_SHORT。現在のシグナルはCMD_NEUTRALです。CMD_SHORTとCMD_NEUTRALが結果としてCMD_VOIDを与えることを確認できますか?
最初の信号がCMD_NEUTRALで、2番目の信号がCMD_SHORTの場合、合計の信号はCMD_SHORTになります。しかし、最初のシグナルがCMD_SHORTで2番目のシグナルがCMD_NEUTRALの場合、CMD_VOIDとなります。
こんな感じだろうか:
if(signal.Entry()) { if(m_signal_open>CMD_VOID) { ENUM_CMD signal_open=signal.SignalOpen(); if(m_signal_open==CMD_NEUTRAL) { m_signal_open=signal_open; } else if(m_signal_open!=signal_open && signal_open!=CMD_NEUTRAL) { m_signal_open=CMD_VOID; } } }
if(m_new_signal) { if(m_signal_open==m_signal_open_last) m_signal_open = CMD_NEUTRAL; if(m_signal_close==m_signal_close_last) m_signal_close= CMD_NEUTRAL; }
これは終値シグナルという点では完全には正しくない。なぜ同じ方向の終値シグナルが2つ存在できないのですか?
例えば、エントリーシグナルがショート、次のエグジットシグナルがロング(ショートを決済)、次のエントリーシグナルがロング、次のエントリーシグナルがショート、次のエグジットシグナルがロングです。この場合、最後のエグジットシグナルは、前のエグジットシグナルと同じ方向なので、機能しません。
これは終値シグナルという点では完全には正しくない。なぜ同じ方向の終値シグナルが2つ存在できないのですか?
例えば、エントリーシグナルがショート、次のエグジットシグナルがロング(ショートを決済)、次のエントリーシグナルがロング、次のエントリーシグナルがショート、次のエグジットシグナルがロングです。この場合、最後のエグジットシグナルは、前のエグジットシグナルと同じ方向なので、機能しません。
シグナルをどのように評価するかは、何を達成したいかによります。
あなたが投稿した最後のコードは、クラスメンバーm_new_signalがtrueに設定されているときにのみ実行されます。これは新しいシグナルでのみ取引するためです。この保護されたクラス・メンバーを設定するには、クラスで利用可能なメソッドNewSignalを使用します。
シグナルがどのように評価されるべきかについては、何を実現したかったかによります。
最後に投稿されたコードは、クラス・メンバーm_new_signalがtrueに設定されたときのみ実行されます。これは、新しいシグナルのみで取引するためのものです。この保護されたクラス・メンバーを設定するには、クラスで利用可能なメソッドNewSignalを使用します。
それは分かっている。しかし、これをfalseに設定すると、エントリーシグナルにも影響します。エントリー・シグナルには問題ありませんが、エグジット・シグナルには使えません。エグジットシグナルはリバージョンであったり、エグジットシグナルであったりするので、同じ方向のエグジットシグナルが2つあるのは普通のことです。
こんにちは、mbjen、
エンリコ、こんにちは、
シグナルモジュールをテストしています。SHORTとNEUTRALのシグナルを1つずつ持っています。最終的にCMD_VOIDが表示されたのはなぜですか?CMD_VOIDはいつ現れるのですか?
実はこれはCSignalsBase::Checkで表示されます。
シグナルは2つしかない。前のシグナルはCMD_SHORT。現在のシグナルはCMD_NEUTRALです。CMD_SHORTとCMD_NEUTRALが結果としてCMD_VOIDを与えることを確認できますか?
最初の信号がCMD_NEUTRALで、2番目の信号がCMD_SHORTの場合、合計の信号はCMD_SHORTになります。しかし、最初のシグナルがCMD_SHORTで2番目のシグナルがCMD_NEUTRALの場合、CMD_VOIDとなります。
こんな感じでしょうか:
最初の質問を見落としていました。今まで気づきませんでした。とても良いフィードバックでした。
ご指摘ありがとうございます。そうですね。コードを更新し、記事を修正します。
それは分かっています。でもfalseにするとエントリーシグナルにも影響します。エグジット・ルールが異なる可能性があるためです。エグジットシグナルはリバージョンであったり、エグジットシグナルであったりするので、同じ方向のエグジットシグナルが2つあるのは普通のことです。
それは一理あります。しかし、例えば、MAクロスオーバーの時だけエグジットシグナルを出したい場合、これは必要でしょう。現在のコードよりも、2つのシグナルを分離したほうがいいと思います:
if(m_new_signal) { if(m_signal_open==m_signal_open_last) m_signal_open = CMD_NEUTRAL; } if(m_new_signal_close) { if(m_signal_close==m_signal_close_last) m_signal_close= CMD_NEUTRAL; }
m_signal_closeには、以前のシグナル値がSignalBase.mqhに保存されているようです。例えば、終了シグナルがあります。それをチェックしてCalculate()メソッドがfalseを返すと、前回の終了時のシグナル値が返されます。
Calculateメソッドは仮想メソッドです。もしメソッドがfalseを返すのであれば、メソッド自体からこれらのクラス・メンバーをニュートラルにリセットする必要があります。
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索
新しい記事 クロスプラットフォームEA: シグナル はパブリッシュされました:
この記事では、クロスプラットフォームEAで使用される CSignal および CSignals クラスについて解説します。 MQL4 と MQL5 の違いについて、トレードシグナルの評価に必要なデータがどのようにアクセスされるかを調べ、記述されたコードが両方のコンパイラと互換性があることを確認します。
現在のシグナルの生成に必要なその他の計算はすべて、CSignal および CSignals オブジェクトに移動されました。 したがって、あとはCSignals がチェックを実行し、そのメソッドの CheckOpenLong と CheckOpenShort を呼び出してその出力を取得することだけです。 次のスクリーンショットは、MT4とMT5のエキスパートをテストした結果を示しています。
(MT4)
作者: Enrico Lambino