
以前の記事では、イベント指向のバックテストシステムとは何かについて説明し、そのために開発する必要がある
クラス階層を整理し、そのようなシステムが過去のテストと取引所での「ライブ」作業において
市場データをどのように
使用するかについて説明しました。
今日は、ポートフォリオ内のポジションの追跡を担当し、着信信号に基づいて限られた数の株式で注文を生成するNaivePortfolioオブジェクトについて説明します。
位置の追跡と注文の操作
注文管理システムは、イベント指向のバックテスターの最も複雑なコンポーネントの1つです。 その役割は、現在の市場ポジションとその市場価値を追跡することです。 したがって、バックテスターの対応するコンポーネントから取得したデータに基づいて、位置の残差値が計算されます。
ポートフォリオコンポーネントは、ポジションの分析に加えて、リスク要因を考慮し、ポジションのサイズを決定する手法を適用できる必要があります。これは、ブローカーのトレーディングシステムを通じて市場に送信される注文を最適化するために必要です。
Portfolio
オブジェクトは、
SignalEvent
オブジェクトを処理し、
SignalEvent
オブジェクトを生成し、
OrderEvent
オブジェクトを解釈して位置を更新できる必要があります。 したがって、Portfolioオブジェクトが通常、コード行の点でバックテストシステムの最も膨大な要素であることは驚くことではありません。
実装
新しいportfolio.pyファイルを作成し、必要なライブラリをインポートしましょう-以前に使用した抽象基本クラスの同じ実装です。 整数次数を生成するには、数学ライブラリからフロア関数をインポートする必要があります。
FillEvent
と
OrderEvent
も必要です
OrderEvent
オブジェクトはそれぞれを処理します。
Portfolioの抽象基本クラスと、2つの抽象メソッド
update_signal
および
update_fill
ます。 前者はイベントキューから取得された新しい取引シグナルを処理し、後者は処理オブジェクトのエンジンから受信した実行済み注文に関する情報を処理します。
この記事の主なオブジェクトは、
NaivePortfolio
クラスです。 これは、ポジションと予約済みファンドのサイズを計算し、取引注文を簡単な方法で処理するために作成されました-特定の株式数でそれらを証券取引システムに送信するだけです。 現実の世界では、すべてがより複雑ですが、このような単純化は、ポートフォリオ注文処理システムがイベント指向製品でどのように機能するかを理解するのに役立ちます。
NaivePortfolio
は初期資本が必要です-例では、100,000ドルに設定されています。 また、仕事を開始する日時を設定する必要があります。
ポートフォリオには、
all_positions
および
current_positions
が含まれ
current_positions
。 最初の要素は、市場イベントのタイムスタンプによって記録された以前のすべてのポジションのリストを保存します。 ポジションは、単に金融商品の額です。 マイナスのポジションは、株式が「ショート」で売却されることを意味します。 2番目の要素には、バーの最終更新の現在の位置を含む辞書が格納されます。
ポートフォリオは、ポジションを担当する要素に加えて、オープンポジション(保有)の現在の市場価値に関する情報を保存します。 この場合の「現在の市場価値」とは、現在のバーから得られる終値を意味します。これは近似値ですが、現時点では非常に妥当です。
all_holdings
要素には、すべてのポジションのコストの履歴リストが格納され、
current_holdings
は値の最新の辞書が格納されます。
次のconstruct_all_positionsメソッドは、各金融商品の辞書を作成し、各値をゼロに設定してから、日付と時刻のキーを追加します。 Python辞書ジェネレーターを使用しました。
construct_all_hldings
メソッドは上記のメソッドと似ていますが、利用可能な資金、手数料、取引後の口座の残高、支払った手数料の合計、利用可能な資産の合計額(オープンポジションとマネー)の追加キーを追加します。 ショートポジションは「マイナス」とみなされます。
starting cash
と
total account
の値は、初期資本と同じです
construct_current_holdings
メソッドは、辞書をリストに「ラップ」しないことを除いて、前のメソッドとほとんど同じです。
各「ハートビート」で、つまり
DataHandler
オブジェクトからの市場データの要求ごとに、ポートフォリオは保有ポジションの現在の市場価値を更新する必要があります。 実際の取引シナリオでは、この情報は仲介システムから直接ダウンロードして解析できますが、バックテストシステムの場合、これらの値は個別に計算する必要があります。
残念ながら、ビッド/アスクのスプレッドと流動性により、「現在の市場価値」などは存在しません。 したがって、保有する資産の量に「価格」を乗じて評価する必要があります。 この例では、以前に受け取ったバーの終値が使用されます。日中の取引戦略では、これはかなり現実的なアプローチですが、1日以上の期間の取引では、始値が次のバーの始値と大きく異なる可能性があるため、すべてがそれほど妥当ではありません。
update_timeindex
メソッド
update_timeindex
、新しいポジションの現在の値を処理します。 彼は市場データプロセッサから最新の価格を取得し、現在のポジションを表す新しいディクショナリのディクショナリを作成し、「新しい」ポジションを「現在の」ポジションと同一視します。 このスキーマは、
FillEvent
ときにのみ変更されます。 その後、メソッド
all_positions
現在の位置
all_positions
セットを
all_positions
リストに
all_positions
ます。 次に、現在値の値が同様の方法で更新されますが、市場価値は、現在のポジションの数に最後のバーの終値を掛けることによって計算されます(
self.current_positions[s] * bars[s][0][5]
)。 取得された新しい値は、
all_holdings
リストに追加されます。
update_positions_from_fill
メソッドは、
FillEvent
何で
FillEvent
(買いまたは売り)を正確に判別し、対応する数の共有を追加または削除することでcurrent_positions辞書を更新します。
対応する
update_holdings_from_fill
メソッド
update_holdings_from_fill
上記のメソッド
update_holdings_from_fill
似ていますが、
保有値を更新します。 実行コストをシミュレートするために、このメソッドは
FillEvent
関連付けられた価格を使用しません。 これはなぜですか? バックテスト環境では、執行価格は実際には不明であるため、想定する必要があります。 したがって、行使価格は「現在の市場価格」(最後のバーの終値)として設定されます。 特定の商品の現在のポジションの値は、執行価格に注文の有価証券の数を乗じたものと等しくなります。
行使価格を決定した後、保有の現在価値、利用可能な資金、および合計額を更新できます。 一般委員会も更新されます。
次に、抽象基本クラス
Portfolio
の抽象
update_fill
メソッドが実装されます。 前の2つのメソッド
update_positions_from_fill
と
update_holdings_from_fill
実行するだけ
update_holdings_from_fill
:
Portfolioオブジェクトは、FillEventイベントを発生させるだけでなく、
SignalEvent
シグナルイベントを受信したときに
OrderEvent
生成する
OrderEvent
があります。 generate_naive_orderメソッドは、シグナルを使用してロングまたはショートポジション、ターゲット金融商品を開き、目的の資産の100株で対応する注文を送信します。 ここで100は任意の値です。 実際の取引の過程で、リスク管理システムまたはポジション値を計算するモジュールによって決定されます。 ただし、
NaivePortfolio
では、リスク管理なしで信号を受信した直後に「
NaivePortfolio
」注文を送信できます。
このメソッドは、ロングポジションとショートポジションのオープン、および現在の数量と特定の金融商品に基づいたそれらの終了を処理します。 次に、対応する
OrderEvent
オブジェクトが
OrderEvent
ます。
update_signal
メソッドは、上記のメソッドを呼び出すだけで、生成された順序をイベントキューに追加します。
NaivePortfolio
の最後の方法は、資本曲線を生成することです。 利益の情報を含むストリームが作成されます。これは、戦略のパフォーマンスを計算するのに役立ち、その後、曲線は割合に基づいて正規化されます。 初期請求書サイズは1.0に設定されています。
Portfolio
オブジェクトは、イベント指向のバックテスター全体の最も複雑な側面です。 複雑さにもかかわらず、ここでのポジションの処理は非常に単純なレベルで実装されています。
次の記事では、イベント指向の歴史的テストシステムの最後の部分である、
OrderEvent
オブジェクトを使用して
OrderEvent
を作成する
ExecutionHandler
オブジェクトについて
FillEvent
します。
継続するには...PSHabréのブログで既に、トレーディングシステムの開発のさまざまな段階を
検討しました 。
ITinvestとパートナーは、このトピックに関する
オンラインコースを実施しています。