TradingSystemの手仕舞いの処理がちょっとヘン。という話を。
check_exit(trade, index)の中身は、
セットされたExitのメソッドcheck_exit(trade, index)を順次呼び、
シグナルが出れば手仕舞う。
というのが基本。というのが昨日までの成果。
ところが、
exit_filterという概念を唐突に導入してる。
引用した方が早い。
exit_filter、すなわち手仕舞いフィルターという概念を導入している。
これは、Exitの子クラスだが特殊なクラスで、
ある条件を満たせば、check_exitメソッドが:no_exitという値を返すものだ。
つまり「手仕舞いを制限する」働きを持つ。
例えば、
「仕掛けてからn日間たたないと手仕舞わない」とか
「移動平均が上向きのときは買いポジションを手仕舞わない」
というようなルールが考えられる。
ソースも載せちゃおう。
def check_exit(trade, index)
@exits.each do |exit_rule|
exit_filter = exit_rule.check_exit(trade, index)
return if exit_filter == :no_exit
return if trade.closed?
end
end
これだと、最初に「特殊な子クラス」セットされてないといけない。
それから、同じメソッドに違う意味を持たせるのは汎化の考え方に反する。
分けろよ、ただのExitと手仕舞い用のFilterは別に。
ついでに言うと、ストップによる手仕舞いも分けた方がいい。
判断というというか処理の分岐を内部でやろうとするよね。
それ逆じゃないかな。
機能単位で内部メソッド用意して、
処理の分岐があるところは出来るだけ最初の流れで見えるようにする。
仕掛けのフィルターによるチェック。←内部メソッド用意。
くぐり抜けたら、
仕掛ける。←内部メソッド用意。
Stopの値を算出←内部メソッド用意。
手仕舞う値なら手仕舞う。
手仕舞いのフィルターのチェック←内部メソッド用意。
くぐり抜けたら、
手仕舞う。←内部メソッド用意。
って、しとかないと可読性が落ちるし、
やり方が一般化されない。
やってることは分かるが、とてもマナー悪い。
質問コーナー、お問い合わせは、sanpome.net@gmail.com まで。