ある日の職場での会話。
 
 
先輩「俺は株のセンス結構あると思うんだよね。」
先輩「10億ぐらい貸してくれたら、利子つけて返せる自信があるよ。」
先輩「元手が無いからやってないけどさ。」
私「では、まず100万円を200万円にすることから始めたらどうでしょう?」
私「自信があるなら何度もやっていれば1億いきますよ?」
先輩「いや、何度も予想を当て続けるのは無理っしょ。」
 
 
何度も勝ち続けれない=再現性が無い
 
そんな手法はギャンブルだ。
 
 
東大生や慶応早稲田などの高学歴者が多い会社だけど、投資の世界じゃ てんでトーシローだな……。
そもそも投資は「センス」で行ったり「予想」するものではない。
徹底的に裁量を捨て再現性を追求した投資方法の一つが
 
 
システムトレード
 
 
これは、システムトレードで億万長者という安易な夢を見て
人生の大半を費やしてしまった 一人の愚かな中年男性のストーリー。
全然、儲からねーーー。
ソート部分の実装結局どうしたか?
前回、システムトレードツール「Protra」でソートの部分が遅かった事が分かった。

 
 
「遅くても別に良いや~!」
と思っていたけど、週末に手持ち無沙汰だったので「選択ソート」を使った形に作り直した。
週末を潰したけどね。
「釣り」や「ウンチク」記事って全くPVが伸びない。
一方、システムトレード関連の記事ならどんな話でも「釣り」の記事の6倍以上は訪問客が来る。
訪問客をブログに呼ぶために修正したと言っても過言ではない……。
……という訳ではなく、時間を忘れて没入して実装&検証していた。
きっと自分はこういう作業が好きなのだと思う。
 
 
「課題」まで出させておいて「施策」を実施させない、うちのような組織になっちゃ駄目だしね。
ソート修正後の、バックテスト時間はどうなった?
で、前回同様に下記のストラテジーを使って「時間測定」をしてみた。



 
 
【修正前】
- 約3時間(2時間54分52秒)
【修正後】
- 約30分(0時間30分24秒)
その差
 
 
 
まさかの 6倍
 
 
 
6倍だよ……6倍。
 
 
 
(C)鳥山明/ドラゴンボール
 
 
 
悟空がこの時「界王拳6倍」を使えていたら
楽にベジータを倒すことができていただろう。
 
 
 
衝撃的な速度改善。
 
 
 
図に表すとこうなる。
 
 
 
今まで、どれだけ無駄なアルゴリズムで実装していたのか……。
中身を理解せずにソースコードを拝借したら駄目だなーー。
 
 
この関数はUtility.ptに追加。
既にGitHubにも公開済み。

| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | //================================================== // 昇順/降順($reverse = 1)で選択候補数だけ選択ソート // 引数: max 銘柄選択候補数 // 引数: selectFlag 複数ストラテジーの優先度(0 = 利用しない) // 戻値: sortList max数のソートしたCodeリスト //================================================== def SelectionSort(max, selectFlag)       if ! ($buyCnt)             return       end       buylist  = [$code_num]       codelist = [$maxCode]       if (max > $buyCnt)             max = $buyCnt       end       // 購入銘柄Codeのリストを作成       i = 0       m = 0       while (i < $code_num)             // 購入の場合$buyflag[i][0]は0以外             if ((selectFlag && $buyflag[i][0] == selectFlag) _                 || (! selectFlag && $buyflag[i][0]))                    buylist[m] = i // 購入順序                    m = m + 1             end             i = i + 1       end       i = 0       while (i < $maxCode)             if ($order[i] != -1)                    codelist[$order[i]] = i             end             i = i + 1       end       // 選択ソート       sortList = [max]       i = 0       while (i < max)             m = i             j = i + 1             while (j < $buyCnt)                     if (! $reverse && $buyflag[buylist[j]][1] < $buyflag[buylist[m]][1])                            m = j                     elsif ($reverse && $buyflag[buylist[j]][1] > $buyflag[buylist[m]][1])                            m = j                     end                     j = j + 1             end             min = buylist[m]             buylist[m] = buylist[i]             buylist[i] = min             sortList[i] = (string)codelist[buylist[i]]             i = i + 1       end       return sortList end | 
大域変数や実処理部分に「オマジナイ」的な処理を書きたくないので、これでも色々と無駄な計算が走っている。
できる限り下位互換を取るつもりだったが、過去の無駄な大域変数を消すことにした。
なので、少しアルゴリズムに修正が必要。
抜粋すると次のような書き方となる。
| 1 2 3 4 5 6 7 8 9 10 11 | def Main(i)         //==================================================         // 条件(買条件, 売条件共通部分)         //==================================================         //まだ上場していない銘柄は株価データがないためnullが返る         if (Index == null)                 return         end         if ($order[(int)Code] == -1)                 $order[(int)Code] = i         end | 
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | //==================== // 銘柄コードを変えながらMain関数,BuySell関数を実行 //==================== Print("-------------------------------------------------") Print("日付 = "+ Year + "/" + Month + "/" + Day) $buyCnt = 0   // 購入数初期化 UpDownRatio() // 騰落レシオ計算 i = -1 while (i + 1 < $code_num)         i = i + 1         {codes[i]}Main(i) end i = 0 if ($buyCnt)         sortList = SelectionSort(10, 0)         // 1) [デイトレサンプルスイング改良版(順位)]が[10]より[小さい(同じ含む)]         cnt = $buyCnt         if ($buyCnt > 10)             cnt = 10         end         while i < cnt                {sortList[i]}SortBuy()                i = i + 1         end end //---------------------------------------------- i = -1 while (i + 1 < $code_num)         i = i + 1         {codes[i]}Sell_(i) end | 
この例では、銘柄を最大10件のみ選定して選択ソートで昇順に並べている。
まぁ……別に誰も使っているライブラリでも無いし、多くの人にはどうでも良い話だろうけどね。
まとめ
ソート部分を選択ソート&必要銘柄数だけソートをするように変更することで、今回のストラテジーでは6倍の速度改善を実現した。
今後のバックテストでは、この方法を使っていく。
ただし、シグナルが極端に多いような手法に有効な高速化であり、すべての手法が6倍早くなる訳ではない。念の為。

 
  
  
  
  




