チャネルブレイクアウトbotコード(by スナフキン氏)読解メモ41

の続きです。
題材コードは https://sshuhei.com/entry/channelbreakout/ です。

最後に最適化のコードを見ます。

   #最適化
   #optimization()

optimization メソッドを見ます。

def optimization():
   entryAndCloseTerm = [(5,3),(5,5),(10,10),(20,10)]
   rangeThAndrangeTerm = [(5000,5),(5000,15),(10000,15),(None,15),(None,20),(None,15)]
   waitTermAndwaitTh = [(10,10000),(10,20000),(5,10000)]
   paramList = []
   for i in entryAndCloseTerm:
       for j in rangeThAndrangeTerm:
           for k in waitTermAndwaitTh:
               channelBreakOut = ChannelBreakOut()
               channelBreakOut.entryTerm = i[0]
               channelBreakOut.closeTerm = i[1]
               channelBreakOut.rangeTh = j[0]
               channelBreakOut.rangeTerm = j[1]
               channelBreakOut.waitTerm = k[0]
               channelBreakOut.waitTh = k[1]
               channelBreakOut.candleTerm = "1T"
               #テスト
               pl, profitFactor =  channelBreakOut.describeResult(entryTerm=channelBreakOut.entryTerm, closeTerm=channelBreakOut.closeTerm, rangeTh=channelBreakOut.rangeTh, rangeTerm=channelBreakOut.rangeTerm,  originalWaitTerm=channelBreakOut.waitTerm, waitTh=channelBreakOut.waitTh, candleTerm=channelBreakOut.candleTerm,fileName="20180221_0310.csv", showFigure=False)
               paramList.append([pl,profitFactor, i,j,k])
   pF = [i[1] for i in paramList]
   pL = [i[0] for i in paramList]
   print("ProfitFactor max:")
   print(paramList[pF.index(max(pF))])
   print("PL max:")
   print(paramList[pL.index(max(pL))])

冒頭で最適化したい変数の候補を列挙します。
entryAndCloseTermでは、entryTermとcloseTermの対の候補が列挙されています。
rangeThAndrangeTermでは、ranthThとrangeTermの対が候補として列挙されています。
waitTermAndwaitThでは、waitTermとwaitThの対が候補として列挙されています。

   paramList = []

結果を入れるらしき空配列を作ります。

   for i in entryAndCloseTerm:
       for j in rangeThAndrangeTerm:
           for k in waitTermAndwaitTh:

候補に挙げた変数を総当たりします。

               channelBreakOut = ChannelBreakOut()
               channelBreakOut.entryTerm = i[0]
               channelBreakOut.closeTerm = i[1]
               channelBreakOut.rangeTh = j[0]
               channelBreakOut.rangeTerm = j[1]
               channelBreakOut.waitTerm = k[0]
               channelBreakOut.waitTh = k[1]
               channelBreakOut.candleTerm = "1T"
               #テスト
               pl, profitFactor =  channelBreakOut.describeResult(entryTerm=channelBreakOut.entryTerm, closeTerm=channelBreakOut.closeTerm, rangeTh=channelBreakOut.rangeTh, rangeTerm=channelBreakOut.rangeTerm,  originalWaitTerm=channelBreakOut.waitTerm, waitTh=channelBreakOut.waitTh, candleTerm=channelBreakOut.candleTerm,fileName="20180221_0310.csv", showFigure=False)
               paramList.append([pl,profitFactor, i,j,k])

変数をdescribeResultメソッドに渡し、バックテストを実行します。
最終損益とプロフィットファクターが返ってくるのでparamListに追加します。
paramListには、最終損益、プロフィットファクター、entryAndCloseTermの番号、rangeThAndrangeTermの番号、waitTermAndwaitThの番号が入った配列をいれます。

   pF = [i[1] for i in paramList]
   pL = [i[0] for i in paramList]

forブロック処理終了後、プロフィットファクターの一覧をpFに、
最終損益の一覧をpLに詰めます。

   print("ProfitFactor max:")
   print(paramList[pF.index(max(pF))])
   print("PL max:")
   print(paramList[pL.index(max(pL))])

プロフィットファクターが最大のものの番号を取得し、paramListに与えることで、プロフィットファクター最大となる変数組み合わせを出力します。
同様に、最終損益最大となる変数組み合わせを出力します。
出力された損益が仮にプラスであれば、少なくともテストの対象期間においては勝てた可能性が高いことを意味します。

さて、これでスナフキン氏のチャネルブレイクアウトコードは全て読んだことになります。
色々と勉強になりましたが、特に下記3点が学びになりました。

1. レンジ判定をしていること
2. 一定以上買った後はロットを下げること
3. バックテストを実行してから実取引をしている(ように読める)こと

1,2はご本人が「概要と変数の説明」にも書かれていることで、(読解した)結果的にやはりこれが売りなんだなと理解しました。
3は、自分はできていない部分で、エイヤと実戦投入してしまいます。
しかし相場が変わったときに柔軟に対応できないので、やはりバックテストは有用でしょう。
バックテストの総当たりの部分を効率化したものが https://github.com/Connie-Wild/ChannelBreakoutBot で提供されているので見てみるとよいかもしれません。

この毎日少しずつ読み進める試みを自分の中でコードリーディング筋トレと呼んでいたのですが、
これをやったおかげでリーディング速度・レビュー品質が少し上がったように思います。

今後もできれば続けたいので、
明日からはmagitoさんのPython3 MarketMaker(MM)BOTのサンプルロジックとソースコードを読んでいきたいと思います。

(ご本人曰く)エッジが消失しているとはいえ、mmbotの基礎を読み取れるはずなので期待です。

それでは、ここまで読んでいただいてありがとうございました。

↓次シリーズ


この記事が気に入ったらサポートをしてみませんか?