SSブログ

エクセルのちょっといい話(7) [システムトレード]

エクセルにおいて、IF関数は恐らく最も多く用いられる関数の一つでしょう。この関数があるお陰で、ワークシートの多彩な表現が可能になるわけです。
今回は、そのIF関数の使い方について考えてみたいと思います。

IF関数は、通常、次のような書式で表されます。

  =IF(論理式,真の場合,[偽の場合]) ・・・①

ここで、[偽の場合]は省略することが可能ですが、省略した場合の戻り値は、"真の場合"か"FALSE"となります。すなわち、論理式が真であれば2つ目の引数(ひきすう)の値、偽であれば"FALSE"となるわけです。省略しない場合は、指定した値が得られます。
通常は、[偽の場合]を省略せずに、3つの引数を全て用いる場合がほとんどだと思います。

ちなみに、真の場合を省略することも可能ですが、その場合には論理式が真の時に"0"が返ります。これは、真の場合が省略されたことを、単に"0"と判断しているだけであり、"TRUE"が返るわけではありません。
真の場合に"TRUE"、偽の場合に"FALSE"を返したい時は、単に"=論理式"とします。

例えば次式のようにすれば、

  =A1=1 ・・・②

A1セルの値が"1"の時に"TRUE"、"1"以外のときに"FALSE"を返すことになります。

さて、IF関数を単独で使用する場合には、特に問題が生じることはありませんが、IF関数を入れ子構造(ネストといいます)にすると、途端に訳が分からなくなってきます。
例えば、A1セルの値が"1"だったら"1"、"0"だったら"0"、それ以外だったら"-1"としたい場合、通常はIF関数をネストして、次のように表します。

  =IF(A1=1,1,IF(A1=0,0,-1)) ・・・③

これくらいなら、まだ付いて行けるかと思いますが、トレーディングシステムを作成する場合、もっと複雑なネストを用いることが少なくありません。
そのような時には、ネストの階層を出来るだけ少なくすると、見通しが良くなります。

例えば上記の例では、数式を次のように書き換えることもできます。

  =IF(OR(A1=1,A1=0),A1,-1) ・・・④

OR関数は、その引数となる論理式のいずれかが真であれば"TRUE"、そうでなければ"FALSE"を返します。④式では、A1セルの値が"1"か"0"ならA1セルの値をそのまま返し、そうでなければ"-1"を返すということになります。

ここで、論理式が"TRUE"になったり"FALSE"になったりすることの意味が、分かりにくいと感じるかもしれません。
エクセルを使用できる方は、任意のセルで次の式を実行してみてください。

  =IF(TRUE,1,0) ・・・⑤

すると、そのセルに"1"が表示されると思います。エクセルにおいては、"TRUE"という文字と"FALSE"という文字は特別な意味を持っていて、それらは論理式の結果(真偽)として扱われる訳です。
ちなみに、⑤式において"TRUE"を"FALSE"に置き換えると、"0"が返ってきます。

すなわち、OR(A1=1,A1=0)という論理式の戻り値は、本当に"TRUE"か"FALSE"かの文字(値)となり、その結果、④式のIF関数のOR関数(論理式)の部分が"TRUE"または"FALSE"となって、⑤式のような形態になるということが分かります。
⑤式が矛盾なく実行できることは、前述した通りです。

さて、トレーディングシステムにおいて、日々の損益を累計していく必要がありますが、その際、買いと売りとで損益を反転させて集計しなければなりません。
売買は必ず寄付きで行なうものとした場合、どのような計算式が考えられるでしょうか?

一番最初に思いつくのは、買いの場合と売りの場合とをきっちりと分ける方法です。例えば、次のような計算式です。

  =IF(買いの場合,買いの処理,売りの処理) ・・・⑥

しかし、これではうまく行きません。何故なら、買いと売り以外に、買いHOLDと売りHOLDの場合があるからです。
それらを考慮すると、⑥式は次のようになります。

  =IF(買いの場合,買いの処理,IF(売りの場合,売りの処理,
    IF(買いHOLDの場合,買いHOLDの処理,売りHOLDの場合))) ・・・⑦

これで3重のネストです。⑦式程度なら、そんなにややこしくないように思えるかもしれませんが、実際には、手数料やレバレッジ等を考慮すると、各処理の内容は結構複雑になりますし、場合によっては、さらにIF関数が入るかもしれません。

また、エクセルの常套手段として、エラーを出さないために次のような処理を行なう必要が多々あります。

  =IF(データセルが空白,"",⑦式) ・・・⑧

すると、ネストは少なくとも4重、下手をすれば5重やそれ以上になってしまうわけです。最初にシステムを作成する時は、それでも勢いで何とかなってしまうものですが、後で修正を行なう必要が生じたりすると、訳が分からなくなってしまいます。

何か上手い方法はないのでしょうか?
この例の場合ですと、次のような処理を行なえば、見通しが良くなります。

  当日損益=ギャップ分損益+日差分損益(-手数料) ・・・⑨

もしも前日引け時点のシグナルが買いHOLDもしくは売りの場合は、ギャップ分損益は当日始値-前日終値、売りHOLDもしくは買いの場合は、前日終値-当日始値となります。
また、日差分損益は、前日引け時点のシグナルが買いもしくは買いHOLDの場合は、当日終値-当日始値、売りもしくは売りHOLDの場合は、当日始値-当日終値となります。

すなわち、空白処理を行なわず手数料も考慮しない場合、⑦式に替わる計算式は次のようになるわけです。

  =IF(OR(買いHOLD,売り),1,-1)*ギャップ+IF(OR(買い,買いHOLD),1,-1)*日差 ・・・⑩

ずいぶん簡単になりましたね。IF関数に他の値を掛けたり足したりすることを、奇異に感じるかもしれませんが、この例ではIF関数は必ず"1"か"-1"の値を採るわけですから、普通に計算できることになります。

ここでは、ギャップ=当日始値-前日終値、日差=当日終値-当日始値、としています。もしもシグナルが買いHOLDまたは売りであれば、ギャップ分損益はギャップに"1"を掛けるわけですから、当日始値-前日終値となり、それ以外であればギャップに"-1"を掛けて、前日終値-当日始値となるわけです。

日差の場合も、ギャップの場合と同様に考えることができます。また、もしも手数料を考慮する必要が生じた場合は、⑩式から手数料分を引いてやれば良いだけです。
手数料は、通常、売買の際にのみ掛かりますから、手数料を求める式は次のようになります。

  =IF(OR(買い,売り),1,0)*IF(ドテン,2,1)*手数料 ・・・⑪

シグナルが買いまたは売りの場合は手数料が生じますから、手数料に"1"を掛けてやります。また、それ以外の場合は手数料が生じませんから、手数料に"0"を掛けてやれば良いわけです。
2番目のIF関数は、そのシステムがドテンシステムかそうでないかによって、手数料の額が2倍異なってきますので、それを補正するためのものです。

結局、空白処理も含めて、当日損益を求めると、次式のようになります。

  =IF(データセルが空白,"",⑩式-⑪式) ・・・⑫

また、レバレッジを掛ける場合は、⑩式全体にレバレッジを乗じてやればOKです。ただし、手数料に関しては、レバレッジによってどのように変わるかが明確ではありませんので、自身の投資環境に応じて変更してやる必要があります。

以上、IF関数の使い方について考えてきました。IF関数というと、複雑な入れ子構造を連想しがちですが、上手く条件を分類することにより、簡潔で分かりやすい計算式にすることができます。
⑩式や⑪式、そして⑫式のような形態であれば、計算式のメンテナンスも容易になるのではないかと思います。

nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

Facebook コメント

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。