なんだかんだ言いながら、周囲を見渡すと米株の長期積立やゴールド積立で資産が倍になっている人が多数いる。
遅れながらも先月から定期貯金を解約して仮想通貨と世界株、米株に手を出したら一週間で初任給レベルのマイナス。
当時、志を同じくして私はシステムトレードを選択した。
選択した経緯は次のように書いてある。
- 【目的】 投資で安定的に長期的な利益を得ること
- 【問題】 ルールがなく心理的に弱く投資で勝てない。継続的にコツコツが苦手
- 【課題】 再現性があり、精神的に負担のない投資手法確立
- 【施策】 完全自動な環境を構築し、バックテストによる手法の妥当性確認後に実践を行う
これ、既にシステムトレードを行う前提の施策ありきのロジックじゃん。
社内でこんな説明してバジェット貰おうとしたら怒鳴られるよ。
最近はシステムトレードに対して甘い事をいっているツイッターとかブログを見るとイラっとする。
そんな折、西村剛氏のメーリングリストで、斉藤正章氏とコラボした「アフィリエイトメール」が目に入った。
結論じゃねーだろ!ロジックが破綻してるだろ!
そこまで自信あるなら、システムトレードでヘッジファンド立ち上げたら良いのに……。
そもそも、システムトレードの達人は昨年で販売中止にするんじゃなかったの?
そんな彼がボラティリティに関するシステムトレードの結果を公開してたので、やってみた。
株価が大きく下落した銘柄を買い付けする逆張り戦略の期待値検証
【基本条件】
- 1) 初期費用 300万円
- 2) 単利運用
- 3) 現物取引:1銘柄当たり仕掛け金額20万円
- 5) 売買対象:全銘柄
【買い条件】
- 1) 終値と移動平均(5日)の乖離率が-10%以下
- 2) ボラティリティ(5日)が10%以上
上記2つを共に満たした翌日に成行で買い
【売り条件】
- 1) 終値と移動平均(5日)の乖離率が0%以上、または
- 2) 仕掛けた日から10日以上経過
上記どちらかを満たした翌日に成行で売り
「終値と移動平均(5日)の乖離率が-10%以下」となった銘柄は、短期的に大きく株価が下落していることを表す。
この時点で数十銘柄しか抽出され無いが、これにボラティリティを追加すると利益が上がり安定するらしい。
ボラティリティ(Volatility)って何?何なの?
最近よく目にするキーワード。
今日の株式見通し=軟調、週末の米株安を嫌気 ボラティリティーの高い相場
ロイター
意味としてはこういうこと。
- ボラティリティの数値が高い・・・・値動きが荒い銘柄
- ボラティリティの数値が小さい・・・値動きが緩やかな銘柄
要するに
どっちに行くか分からないが、何かが起こりそうだ(大きく動きそうだ)ということを示す指数
言い換えれば「市場の不安」を表す指数。
ボラティリティの計算式
これ……以前もヒストリカルボラティリティとか実装したけど、何故か結果が違うんだよね。
と思ったら式も公開されていた。
ボラティリティ(標準偏差)=√(各日の終値ー終値の平均)の2乗の値の合計/N(N=○日)
これを平均と分散の分解をすると次のような式変形できる。
式変形自体は間違ってないっぽい。
バックテスト結果
バックテスト時間は全銘柄で42分。
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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
株価データ: 日足 銘柄リスト: 全銘柄 2000/01/06~2022/02/24における成績です。 ---------------------------------------- 全トレード数 5137 勝ちトレード数(勝率) 2559(49.82%) 負けトレード数(負率) 2578(50.18%) 全トレード平均利率 0.82% 勝ちトレード平均利率 10.30% 負けトレード平均損率 -8.58% 勝ちトレード最大利率 129.80% 負けトレード最大損率 -75.00% 全トレード平均期間 6.94 勝ちトレード平均期間 5.23 負けトレード平均期間 8.63 ---------------------------------------- 必要資金 ¥2,953,500 最大ポジション(簿価) ¥3,424,900 最大ポジション(時価) ¥3,831,000 純利益 ¥19,618,410 勝ちトレード総利益 ¥117,999,500 負けトレード総損失 -¥98,381,060 全トレード平均利益 ¥3,819 勝ちトレード平均利益 ¥46,112 負けトレード平均損失 -¥38,162 勝ちトレード最大利益 ¥662,000 負けトレード最大損失 -¥492,000 プロフィットファクター 1.20 最大ドローダウン(簿価) -¥12,098,590 最大ドローダウン(時価) -¥12,897,680 ---------------------------------------- 現在進行中のトレード数 3 ---------------------------------------- 平均年利 28.88% 平均年利(直近5年) -36.76% 最大連勝 16回 最大連敗 11回 ---------------------------------------- [年度別レポート] 年度 取引回数 運用損益 年利 勝率 PF 最大DD 2022年 23回 -¥1,193,272円 -40.40% 30.43% 0.15倍 -75.00% 2021年 159回 -¥1,146,850円 -38.83% 40.88% 0.66倍 -75.00% 2020年 229回 -¥581,009円 -19.67% 50.66% 0.88倍 -45.94% 2019年 231回 -¥373,857円 -12.66% 45.45% 0.90倍 -30.31% 2018年 255回 -¥2,133,259円 -72.23% 44.31% 0.60倍 -50.79% 2017年 222回 -¥11,439円 -0.39% 48.65% 1.00倍 -32.02% 2016年 216回 -¥2,237,720円 -75.77% 41.67% 0.55倍 -36.19% 2015年 227回 -¥2,902,593円 -98.28% 37.44% 0.45倍 -36.50% 2014年 233回 -¥1,223,590円 -41.43% 45.06% 0.76倍 -33.64% 2013年 249回 ¥1,061,880円 35.95% 51.81% 1.23倍 -32.56% 2012年 223回 ¥1,849,500円 62.62% 53.36% 1.34倍 -50.00% 2011年 213回 ¥308,770円 10.45% 53.52% 1.07倍 -52.61% 2010年 219回 ¥3,555,040円 120.37% 56.62% 1.77倍 -50.00% 2009年 256回 ¥4,172,339円 141.27% 64.06% 1.91倍 -66.67% 2008年 264回 ¥997,110円 33.76% 54.55% 1.13倍 -65.66% 2007年 243回 -¥1,630,470円 -55.20% 44.03% 0.71倍 -41.88% 2006年 210回 -¥1,372,800円 -46.48% 47.62% 0.72倍 -64.34% 2005年 192回 ¥2,033,300円 68.84% 56.25% 1.78倍 -60.90% 2004年 229回 ¥4,033,130円 136.55% 66.81% 2.66倍 -23.53% 2003年 249回 ¥3,386,700円 114.67% 62.25% 2.01倍 -31.93% 2002年 261回 ¥4,408,300円 149.26% 63.98% 2.28倍 -31.30% 2001年 255回 ¥3,843,300円 130.13% 62.35% 2.06倍 -38.74% 2000年 279回 ¥4,775,900円 161.70% 65.23% 2.25倍 -36.63% |
利益曲線は次の通り。
グニャグニャじゃねーか!!
西村氏のページの結果とは雲泥の差がある。
無制限に購入した場合
上の結果は単利購入で、かつ資金は300万円、一株の上限購入金額を50万円にしている。
次に無制限に購入した場合を検証する。
ただし西村氏は一株の上限購入金額を20万円にしていので、そちらに合わせた。
計算時間は26分。
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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
株価データ: 日足 銘柄リスト: 全銘柄 2000/01/06~2022/02/24における成績です。 ---------------------------------------- 全トレード数 22640 勝ちトレード数(勝率) 12799(56.53%) 負けトレード数(負率) 9841(43.47%) 全トレード平均利率 1.68% 勝ちトレード平均利率 9.32% 負けトレード平均損率 -8.27% 勝ちトレード最大利率 133.33% 負けトレード最大損率 -76.00% 全トレード平均期間 6.51 勝ちトレード平均期間 5.11 負けトレード平均期間 8.33 ---------------------------------------- 必要資金 ¥17,488,900 最大ポジション(簿価) ¥47,468,050 最大ポジション(時価) ¥50,387,800 純利益 ¥63,669,750 勝ちトレード総利益 ¥202,153,000 負けトレード総損失 -¥138,483,200 全トレード平均利益 ¥2,812 勝ちトレード平均利益 ¥15,794 負けトレード平均損失 -¥14,072 勝ちトレード最大利益 ¥240,000 負けトレード最大損失 -¥196,800 プロフィットファクター 1.46 最大ドローダウン(簿価) -¥6,069,552 最大ドローダウン(時価) -¥11,022,800 ---------------------------------------- 現在進行中のトレード数 31 ---------------------------------------- 平均年利 15.83% 平均年利(直近5年) 5.52% 最大連勝 18回 最大連敗 27回 ---------------------------------------- [年度別レポート] 年度 取引回数 運用損益 年利 勝率 PF 最大DD 2022年 124回 -¥534,583円 -3.06% 45.16% 0.62倍 -74.89% 2021年 586回 ¥99,331円 0.57% 45.39% 1.03倍 -76.00% 2020年 1724回 ¥3,507,686円 20.06% 59.69% 1.29倍 -58.87% 2019年 827回 ¥662,020円 3.79% 51.27% 1.18倍 -36.72% 2018年 1469回 ¥1,088,250円 6.22% 53.17% 1.13倍 -63.91% 2017年 537回 ¥347,252円 1.99% 50.28% 1.13倍 -25.14% 2016年 1107回 ¥1,305,880円 7.47% 54.92% 1.21倍 -38.37% 2015年 707回 ¥1,669,945円 9.55% 54.88% 1.41倍 -38.73% 2014年 981回 ¥290,546円 1.66% 51.07% 1.04倍 -44.19% 2013年 1350回 ¥7,367,983円 42.13% 63.33% 2.07倍 -38.89% 2012年 749回 ¥508,720円 2.91% 56.21% 1.09倍 -50.00% 2011年 888回 ¥8,777,249円 50.19% 66.78% 3.01倍 -52.73% 2010年 764回 -¥608,705円 -3.48% 53.66% 0.91倍 -50.00% 2009年 1349回 ¥3,727,241円 21.31% 61.53% 1.42倍 -60.07% 2008年 2707回 -¥1,119,957円 -6.40% 56.37% 0.95倍 -69.86% 2007年 1147回 ¥260,840円 1.49% 53.79% 1.03倍 -54.35% 2006年 1056回 ¥4,621,900円 26.43% 62.59% 1.86倍 -46.74% 2005年 300回 ¥2,235,900円 12.78% 69.67% 3.38倍 -25.93% 2004年 589回 ¥3,933,232円 22.49% 65.53% 2.51倍 -40.85% 2003年 814回 ¥7,550,300円 43.17% 75.80% 3.62倍 -31.93% 2002年 1046回 ¥6,517,400円 37.27% 68.36% 2.40倍 -41.04% 2001年 1006回 ¥6,130,200円 35.05% 68.79% 2.21倍 -47.37% 2000年 813回 ¥5,331,100円 30.48% 69.37% 2.59倍 -33.33% |
利益曲線は次の通り。
おお、サイトに書かれている結果に近づいた感じがする。
やったー!!聖杯見つけたね!!
とはならない。
実現するには2000万円必要で、辛いドローダウンににも耐える必要がある。
そして今年は既にマイナスだから、西村氏の顔を思い浮かべて
「私、彼を信じてるから大丈夫」
と言い聞かせながら耐えなければならない。
まとめ
安定的にシステムトレードで得られる年利は、せいぜい5%〜15%ぐらいだと思う。
だったらインデックス投資で良いんじゃない?
今は、世界株買って大損して胃が痛いけどさ……。
だけど、同じ境遇の人が多いから耐えられる。
これがシステムトレードになるとプロでもない自身の力を信じ続けることになるけど……
結局、旧式システムトレードでやってるのは、OHLCVデータを捏ねくり回してるだけ。
これで勝てたらオカルトじゃん。
ソースコード
バックテストには無料OSSの「Protra」を利用した。
TIlib、Utility、TrendCheck、TOPIXライブラリは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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# loop-type: date-only //============================== require "TIlib" require "Utility" require "TrendCheck" // ====================================== // 西村剛氏のボラティリティを追加した逆張り戦略 // ====================================== // //【買い条件】 // //1) 終値と移動平均(5日)の乖離率が-10%以下 //2) ボラティリティ(5日)が10%以上 // //【売り条件】 // //1) 終値と移動平均(5日)の乖離率が0%以上、または //2) 仕掛けた日から10日以上経過 codes = CodeList if ($code_num && $code_num != Length(codes)) Print("前回と異なる銘柄リストでは実行できません。") Dummy end $code_num = Length(codes) //グローバル変数を初期化 if (!$__INIT__) $budgetIni = 3000000 $buyUnit = 500000 // 1回の購入資金 (50万円) $MaxHoldDay = 7 // 最大保有日数(営業日) $shortSelling = 0 // 空売り戦略 Yes(1)/No(0) $Interest = 1 // 無制限(0) / 単利(1) / 複利(2) $reverse = 0 // 購入順序 昇順(0) / 降順(1) $udcount = 0 // 騰落レシオ利用数 Init() //------------------------------------------------ $MA5 = [$code_num] $DiffMA = [$code_num] //------------------------------------------------ InitDone() // 騰落レシオ初期化 $__INIT__ = 1 end // ボラティリティ // √Σ(各日の終値 - 終値の平均)^2 / N def CalVolatility(num) a0 = 0 a1 = 0 a2 = 0 c = 0 while (c < num) a0 = {(int)(c * -1)}Close if ! (a0) return 0 end // Σa_i^2 a1 = a1 + a0 * a0 // Σa_i/N a2 = a2 + a0 c = c + 1 end a1 = a1 / (float)num a2 = (a2 / (float)num) * (a2 / (float)num) // 標準偏差 = √{ 分散 } // = √{ Σ(a_i - avg(a))^2/N } // = √{ Σa_i^2/N - (Σa_i/N)^2 } return Sqrt(a1 - a2) end def Main(i) //================================================== // 条件(買条件, 売条件共通部分) //================================================== //まだ上場していない銘柄は株価データがないためnullが返る if (Index == null) return end if ($order[(int)Code] == -1) $order[(int)Code] = i end if ! ($DiffMA[i]) // 銘柄ごとのグローバル変数を初期化する $MA5[i] = MA_new(5) $DiffMA[i] = DiffMA_new(15) $hold[i] = 0 return end //指標の計算を1日進める MA_next($MA5[i]) DiffMA_next($DiffMA[i]) //================================================== // 保有してない→購入 //================================================== if (! $hold[i]) ma5 = MA_value($MA5[i]) diffma = DiffMA_value($DiffMA[i]) if ! (ma5 && diffma && Close) return end r5 = 100 * (Close - ma5) / ma5 //================================================== // 売買(買い) //================================================== //1) 終値と移動平均(5日)の乖離率が-10%以下 flag1 = r5 <= -10 if ! (flag1) return end //2) ボラティリティ(5日)が10%以上 flag2 = CalVolatility(5) if (flag2 >= 10) // PrintLog("買い候補") $buyflag[i][0] = 1 $buyflag[i][1] = diffma $buyflag[i][2] = 1 $buyCnt = $buyCnt + 1 end //================================================== // 保有している→売却 //================================================== elsif ($hold[i]) if ($set[i] < 1) $set[i] = 1 return end $set[i] = $set[i] + 1 //================================================== // 売買(売り) //================================================== ma5 = MA_value($MA5[i]) if ! (ma5) return end r5 = 100 * (Close - ma5) / ma5 //================================================== // 売買(買い) //================================================== //1) 終値と移動平均(5日)の乖離率が-10%以下 flag1 = r5 >= 0 // 1) 利食い:5%以上の含み益が出た場合 if (flag1) PrintLog("利食い") $sellflag[i] = 1 $set[i] = 0 // 2) 損切り:10日以上持っていた場合 elsif ($set[i] >= $MaxHoldDay) PrintLog("損切り") $sellflag[i] = 1 $set[i] = 0 end end end //==================== // 買い処理 //==================== def SortBuy() if ! (HasPricedata({1}Open)) return end $long = 0 $long = Num($buyUnit, Close) codeset = $order[(int)Code] Buying(codeset) end //==================== // 売り処理 //==================== def Sell_(i) if ($sellflag[i]) Selling(i) $sellflag[i] = 0 $buyflag[i][2] = 0 end // 使用した$buyflag 配列を初期化 if ($buyflag[i][0]) $buyflag[i][0] = 0 $buyflag[i][1] = 0 end end //==================== // 銘柄コードを変えながらMain関数,BuySell関数を実行 //==================== Print("-------------------------------------------------") Print("日付 = "+ Year + "/" + Month + "/" + Day) $buyCnt = 0 // 購入数初期化 i = -1 while (i + 1 < $code_num) i = i + 1 {codes[i]}Main(i) end i = 0 if ($buyCnt) sortList = SelectionSort(10, 0) 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 |