2011/01/08

バックテスト(自動)時代 - ForexTester2ストラテジの内部設計(GetSingleTick内ロジックの流れ)



さてさて、前回までは一応サンプルをコピーして名前変えただけのバックテスト用ストラテジ(自動売買プログラム)を作成し、実行できたところまで話しました。

今回はついに、自分なりの売買ルールでのストラテジ作成です!!!

といってもいわゆるトレーディングシステムの話ではなく、ForexTester2でどういう流れでロジックを書くのか
(ここは過去の試行錯誤は省きます。というか忘れてしまった。。。。)
一番カナメのGetSingleTick関数(ティック毎に呼び出され、売買のロジックを書くところ)を重点的に


サンプル内(SMAStrategy.dpr)での関数内のロジックの流れは次の様な感じ。
-------------------
①最初のブロック(おまじない系)
 ・予約変数であるSymbolに現在の通貨ペア文字列("USDJPY"等)が入っていて、外部変数で指定されたCurrency(通貨ペア)と比較し、異なれば何もせず抜ける。
 ・デフォルトのタイムフレーム(1日足とか1H足とか)と、Currencyを設定
 ・一定バー数は何もせずに抜ける
  →つまりインジケータが過去Nバーの情報を必要とする場合、Nバー分の情報が溜まるまで何もしない。というかできないので。

②手仕舞いロジック
 既に発注済オーダがある場合、決済すべき条件が整っていれば決済するロジック。

③発注ロジック
 発注済オーダがない場合で発注条件が整えば発注処理。
 発注後、発注時の情報を変数に格納
-------------------

すんごくシンプルで、この構造だと自分のやりたい事ができないのでいろいろ修正。

ちなみに、今の私のストラテジ構造のGetSingleTick関数内はこんな感じ
--------------------------------
①最初のブロック
 ・予約変数であるSymbolに現在の通貨ペア文字列("USDJPY"等)が入っていて、外部変数で指定されたCurrency(通貨ペア)と比較し、異なれば何もせず抜ける。
  (これほんまに必要なんか???)
 ・一定バー数は何もせずに抜ける
 ※「デフォルトのタイムフレーム(1日足とか1H足とか)と、Currencyを設定」はResetStrategy関数内の最後に移動
   → ちょっとでも処理速度速くならないかなぁと思って移動しやした。


②手仕舞い関連ロジック
 o 約定済注文がストップロスにひっかかっていれば、注文に関する変数の初期化をする。
  つまり、ポジション無しの状態に各種変数の値を戻す  
 o ペンディング中だった注文が約定されたかどうかを判定。
  約定されたら、約定時の情報を変数に格納しておく等。
  → 独自にログ出力する場合とかに便利。他には約定後Nバーで手仕舞いとかしたい場合等
 o ポジションがあれば毎回処理する関数の呼び出し。
  手仕舞いに向けていろんな手仕舞いセットアップ用の変数の更新等
 o もし、ペンディング中(注文オーダが注文約定されていない状態)のオーダをキャンセルしたい場合はキャンセルする
  o 手仕舞いの要否判定し、必要に応じて手仕舞い。そして、注文に関する各種変数を初期化
  独自ログの出力
 o ポジションを持っていれば、オーダ情報の変更要否を判断して必要に応じてオーダ情報変更
  例えば、トレーリングする為に、ストップロスの価格を変更する。

③ばたつき防止ロジック
 もし、前回発注時と同じバーであれば、発注処理をせずに終了
 →のロジック無いと実運用で怖いですよ~!!!
  GetSingleTick関数は、ティック毎に呼び出されます。
  つまり、発注→約定→ロスカットをたった1本のバーで何回も繰り返してしまう可能性が。
  そうなってしまうと、あっというまに大幅ドローダウンです。怖っ!!

④発注処理関連ロジック
 o もし保有ポジションが無く、ショート発注条件を満たしていればショートポジションで発注。
  ・発注する場合は、逆指値の計算→ストップロス価格の計算→決済指値の計算→ロット数の計算
   当然成行き注文の場合は、発注時逆指値の計算は不要。もちろん指値注文も可能。
   私は指値注文を使わない主義なので。ストップロス・決済指値を使わなければ”0”でOK
  ・発注用API(SendPendingOrder/SendInstantOrder)の呼び出し
   SendPendingOrderは、指値/逆指値注文用
   SendInstantOrderは、成行き注文用
   →発注用APIを呼び出すと発注オーダのハンドルが返されるので、それをグローバル変数に格納しておく。
  ・発注成功したときに、発注時の情報(※)を変数にセット
   ※発注時刻、発注時のバー数、その他ログ出力用の情報
  ・成行き注文の場合、「②」の約定された場合のロジックと同じことをする
 o もし保有ポジションが無く、ロング発注条件を満たしていればロングポジションで発注。
  ここの流れもショートポジションの時と同じ
--------------------------------


ちなみに、随所にログ出力用のロジックありますが、ForexTester2ではストラテジを流した後、各注文の情報をExcel/csvに出力できます。
ただ、私には情報不十分なのと、その後の効率化の為、自作でログ出力する様にしました。

独自ログ出力の理由はこんな感じ

・「Strategy Optimizer」で一括で流すと、最後のパラメータでのトレード情報しか残らない。他はサマリの出力だけになってしまう。
 仮に、Print分でデバッグログ出力ロジック書いていても、「Strategy Optimizer」からでは出力されません。
・複数の通貨ペアを連続で流したい場合に、「Strategy Optimizer」使うと効率的。
・スィーニーのMAE/MFE分析をしたかった。
・R値(初期リスク)による期待値を求めたかった。


お!!まるで、役に立つブログみたいな書き方やんけ!!


この構造に至るまでだいぶ試行錯誤しましたよ。

ふぅ。。。。つかれちゃった。。

そして、「FXシステムトレード初心者奮闘記」のバックテスト(自動)時代は、バックテストが始まらずプログラムの中身の話が続くのでした。
次回はプログラミングの注意点と共通部品関連だす。


0 件のコメント:

コメントを投稿