記事「多通貨エキスパートアドバイザーの開発(第3回):アーキテクチャの改訂」についてのディスカッション

 

新しい記事「多通貨エキスパートアドバイザーの開発(第3回):アーキテクチャの改訂」はパブリッシュされました:

複数の戦略が並行して動作する多通貨EAの開発はすでにある程度進んでいます。蓄積された経験を考慮し、先に進みすぎる前に、ソリューションのアーキテクチャを見直し、改善を試みましょう。

EAオブジェクト(CAdvisorクラスまたはその子孫)を割り当てたが、これは取引戦略オブジェクト(CStrategyクラスまたはその子孫)のアグリゲーターです。EA操作の最初に、OnInit()ハンドラで以下のことが起こります。

  • EAオブジェクトが作成されます。
  • 取引戦略のオブジェクトが作成され、EAの取引戦略の配列に追加されます。

OnTick()イベントハンドラでは、次のことが起こります。

  • CAdvisor::Tick()メソッドが EA オブジェクトのために呼ばれます。
  • このメソッドは、すべての戦略を反復処理し、それらのCStrategy::Tick()メソッドを呼び出します。
  • CStrategy::Tick()内の戦略は、マーケットポジションのオープンとクローズに必要なすべての操作を実行します。

これを図式化するとこうなります。

このモードの利点は、ある取引戦略に従ったEAのソースコードがあれば、比較的簡単な操作で他の取引戦略のインスタンスとEAを連動させることができることでした。

しかし、主な欠点がすぐに浮かび上がった。複数の戦略を組み合わせる場合、戦略の各インスタンスで建てるポジションのサイズをある程度小さくしなければなりません。このため、一部の、あるいはすべての戦略インスタンスが取引から完全に排除される可能性があります。並行作業に含める戦略インスタンスが多ければ多いほど、あるいは初期預託金が少なければ少ないほど、そのような結果になる可能性は高くなります。

作者: Yuriy Bykov

 
FOREACH(m_orders, if(m_orders[i].IsOpen()) { m_ordersTotal += 1; })

心の中の何かが、そうやって書くことに駆り立てることがある。

FOREACH(m_orders, m_ordersTotal += m_orders[i].IsOpen())
 
最後まで読んでいない。しかし、(テスターにはない)ペンディングでの作業は、この、実際、かなり改善されたアーキテクチャには当てはまらないような気がする。
 

ボリューメトリシアン(仮想ボリュームの受け手)を考慮し、ストラテジーのオン/オフを切り替えるマスクを追加するのが良いでしょう。

例えば、しばらくの間、ポートフォリオからTSのスイッチを切る必要がある。同様に、逆にスイッチを入れることもできる。

 
このアーキテクチャーをすぐに洗練させる方法は思いつかない。今はこれしかない。
//+------------------------------------------------------------------+
//|| 専門家ベースクラス|
//+------------------------------------------------------------------+
class CAdvisor {
protected:
   CStrategy         *m_strategies[];  // 取引戦略の配列

しかし、どこかに似たようなものを埋め込んだ有能なものがあるはずだ。

 CAdvisor *m_advisors[];  // 仮想ポートフォリオの配列

独自の魔道士を使ってね。

 
Оповещение получателя и стратегии должно происходить только при открытии или закрытии виртуальной позиции.

見積もりセッションが取引セッションから外れて いる場合、テスターでもこれが困難な場合があります。

出来高の同期が成功したというフラグが、この問題を解決してくれます。

 
//+------------------------------------------------------------------+
//| 仮想注文と仮想ポジションのクラス
//+------------------------------------------------------------------+
class CVirtualOrder {
private:
//--- スタティック・フィールド ...
   
//--- 関連する受信者オブジェクトと戦略オブジェクト
   CVirtualReceiver  *m_receiver;
   CVirtualStrategy  *m_strategy;

仮想オーダーにまったく別のエンティティを挿入するのは疑問の残る解決策だ。

アーキテクチャーを作る際に、パフォーマンスの問題を並列的に解決したようだ。私にもそのような罪がある。


おそらく、パフォーマンスを見ずに設計するのがまだ正しい。そして、どうすれば高速化できるかを考える。

 
fxsaber #:
最後まで読んでいません。しかし、(テスターにはない)未決済注文を扱うことは、この、実に大幅に改善されたアーキテクチャにはなじまないような気がします。

私は実際の未決注文を扱うことはなく、仮想の未決注文がトリガーされたときにマーケットポジションをオープンするだけで十分なようです。実際の取引では、スリッページや再クオートにより、正確なエントリーができない可能性があることは承知している。しかし、実際にはまだそのようなことはありません。仮想保留注文のサポートは次のパートで行います。

もしあなたがまだ本物の未決注文を使いたいのであれば、原理的には、アーキテクチャはそれを許します:CVirtualSymbolReceiverクラスの別の実装を書かなければなりません。現在の実装では、仮想的な未決注文は単に無視されます。

 
fxsaber #:

ボランチ(仮想ボリュームの受け手)を考慮したオン/オフ戦略のマスクを追加するのは良いアイデアだろう。

例えば、あるTSをポートフォリオからしばらくの間オフにする必要がある。同様に、逆にスイッチを入れることもできる。

このようなことを実現するのは難しいことではありませんが、それを使用することなく、各戦略の明確なオン/オフ基準が必要になります。これはもっと複雑な作業で、私はまだ手をつけていない。

 
fxsaber #:

そして、このようなものを取り入れた有能な選手がどこかにいるはずだ。

CAdvisor *m_advisors[];  // 仮想ポートフォリオの配列

独自の魔道士を持つ。

その予定はない。ポートフォリオへの統合は、CAdvisorとCStrategyの中間レベルで行われる。解決策の草案はあるが、リファクタリングを進めている間に大きく変わる可能性がある。

 
fxsaber 取引セッションから外れて いる場合、テスターでもこの問題が発生する可能性があります。

出来高の同期が成功したというフラグが、この問題を解決してくれます。

すでにあるようです:

class CVirtualSymbolReceiver : public CReceiver {
  ...
   bool              m_isChanged;      // 仮想ポジションの構成に変化はあるか?

各シンボルについて、必要な実数量が正常にオープンされた場合にのみリセットされます。