アマチュアのシステムトレード集団で構成されたシルバーマンファンドというサイトがある。
チームシルバーマンは平均投資歴約10年のトレーダー5人のメンバーで成り立っています。
全員がシステムトレード実践者ですが全員でノウハウを出し合って共同運用したら面白い結果が出るのではと内輪でファンドを立ち上げました。
2018年から更新が止まってしまっているけどね。
メンバーは2016年に1人追加され6人。
TED(テッド)、toty(トティ)、ukyori(ウキョリ)、茶話田 良寛(さわだ・りょうかん)、ロビン、ミスタァ-(研修生)
彼らは
年利136%
という、高い目標を掲げている。
誰やねん?
と思って調べたら、何人かは素性を明かしていた。
茶話田 良寛(さわだ・りょうかん)が「夢幻」氏
ミスタァ-(研修生)が「ゆうし」氏
え?
マジ?
システムトレード界隈では有名な人々じゃん。
「システムトレードの達人」の関係者の集団っぽいね。
ちなみに知らない人向けに説明すれば「イザナミ」「システムトレードの達人」が有名なシステムトレード用の有料ツール。
ツール名 | 説明 | 有名な利用者 |
---|---|---|
イザナミ | 日本では最もポピュラーなツール。ユーザも多い。価格16万2000円(月払いだと月7700円) | koz-kay氏、ニッパー氏、hamhamseven氏、アイアン鉄氏、Sand氏、シスヤ氏、トレシズ氏、スカイダイヤ氏・・多数 |
システムトレードの達人 | 斎藤正章氏が製作。機能は一番豊富。2020年のどこかで販売終了。価格20万4120円 | 夢幻氏(年利104%)、紫苑氏(300万→1億)、ゆうし、中原良太氏、スカイダイヤ氏 |
今ではPythonが書けるなら無料で使えるシステムトレードのツールも幾つかあるよ。
因みに、私がバックテストで使っている「Protra」は古いけど完全無料のオープンソース。
シルバーマンファンドの押し目買い有効性検証
メンバーの中で「toty(トティ)」氏が書いた記事にストラテジーが掲載されていた。
押し目買い戦略では、長期上昇トレンドの銘柄に絞ることがひとつ大事なポイント
とのこと。
【買いルール】
- 株価が100円以上
- 20日平均売買代金が2億円以上
- 100日ヒストリカルボラティリティが30以上
- ADX(10,5)が30以上
- 連続下落日数が2日以上
- 6日移動平均乖離率が-5%以下
- 175日移動平均乖離率が0%以上
すべての条件に合致した銘柄を翌日指値(当日終値0%)
【売りルール】
- 3日移動平均乖離率が+3%以上
- 保有日数が20日以上
いずれか条件に合致した銘柄を当日引成決済
「175日移動平均乖離率が0%以上」という条件を追加した理由も書いてあった。
右肩上がりであるものの2008年あたりで大きくやられてしまいます。
そこで登場するのが長期トレンド判定です。
横軸に移動平均乖離率(175日)、縦軸に利益率をプロットをすると長期トレンドが上昇しているほど利益率がよく、下落しているほど利益率が悪くなっているのがわかります。
これをもとに上記の戦略に「175日移動平均乖離率が0%以上」という条件を追加します。
なるほど。
しっかりと統計データを使って分析して追加する指標を決めてるのか〜。
やったことねーー
因みにヒストリカルボラティリティは以前実装した。
他のルールも難しくない。
ただ実践に辺り「当日引成決済」はどうやって実現しているんだろう?
「システムトレードの達人」でも無理じゃない?
バックテスト結果
計算時間は全銘柄で5時間20分。
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 |
株価データ: 日足 銘柄リスト: 全銘柄 2000/01/06~2021/09/13における成績です。 ---------------------------------------- 全トレード数 2777 勝ちトレード数(勝率) 1600(57.62%) 負けトレード数(負率) 1177(42.38%) 全トレード平均利率 0.72% 勝ちトレード平均利率 7.52% 負けトレード平均損率 -8.52% 勝ちトレード最大利率 38.25% 負けトレード最大損率 -45.58% 全トレード平均期間 11.39 勝ちトレード平均期間 7.86 負けトレード平均期間 16.18 ---------------------------------------- 必要資金 ¥2,686,600 最大ポジション(簿価) ¥3,000,000 最大ポジション(時価) ¥3,195,000 純利益 ¥9,445,475 勝ちトレード総利益 ¥52,847,660 負けトレード総損失 -¥43,402,180 全トレード平均利益 ¥3,401 勝ちトレード平均利益 ¥33,030 負けトレード平均損失 -¥36,875 勝ちトレード最大利益 ¥190,900 負けトレード最大損失 -¥211,200 プロフィットファクター 1.22 最大ドローダウン(簿価) -¥1,516,800 最大ドローダウン(時価) -¥1,813,600 ---------------------------------------- 現在進行中のトレード数 5 ---------------------------------------- 平均年利 15.98% 平均年利(直近5年) 2.66% 最大連勝 12回 最大連敗 7回 ---------------------------------------- [年度別レポート] 年度 取引回数 運用損益 年利 勝率 PF 最大DD 2021年 95回 -¥250,700円 -9.33% 48.42% 0.84倍 -23.53% 2020年 145回 -¥96,897円 -3.61% 52.41% 0.97倍 -30.63% 2019年 148回 ¥1,031,800円 38.41% 60.81% 1.66倍 -20.73% 2018年 154回 -¥957,900円 -35.65% 48.05% 0.71倍 -34.49% 2017年 141回 ¥630,800円 23.48% 59.57% 1.31倍 -24.41% 2016年 139回 -¥21,840円 -0.81% 56.12% 0.99倍 -29.56% 2015年 149回 ¥73,000円 2.72% 55.03% 1.03倍 -29.86% 2014年 158回 ¥50,300円 1.87% 54.43% 1.02倍 -32.19% 2013年 180回 ¥1,712,000円 63.72% 65.00% 1.69倍 -45.58% 2012年 138回 ¥626,900円 23.33% 60.14% 1.29倍 -31.34% 2011年 131回 ¥101,400円 3.77% 59.54% 1.03倍 -42.86% 2010年 123回 ¥952,864円 35.47% 66.67% 1.55倍 -40.70% 2009年 131回 ¥837,200円 31.16% 58.78% 1.44倍 -23.92% 2008年 112回 -¥175,400円 -6.53% 56.25% 0.92倍 -33.70% 2007年 101回 ¥185,548円 6.91% 62.38% 1.13倍 -28.19% 2006年 105回 ¥364,900円 13.58% 60.95% 1.26倍 -27.66% 2005年 139回 ¥1,257,300円 46.80% 61.15% 1.84倍 -35.16% 2004年 125回 ¥800,000円 29.78% 68.80% 1.50倍 -39.29% 2003年 109回 ¥907,200円 33.77% 67.89% 1.68倍 -20.96% 2002年 76回 ¥254,000円 9.45% 52.63% 1.30倍 -13.58% 2001年 78回 ¥67,100円 2.50% 56.41% 1.05倍 -33.33% 2000年 100回 ¥1,095,900円 40.79% 62.00% 2.29倍 -22.64% |
利益曲線は次のとおり。
んーー、2013年から横ばいだなーー。
保有期間も少し長い。
因みに
- 東証一部だけだと、2015年から下降する
- 東証ニ部だけだと、2015年から激しく下降する
- マザーズだけだと2020年から横ばいになる
なので「全銘柄(TOPIX銘柄を除く)」で利益曲線を出してみた。
悪くないグラフにはなったね。
まとめ
大型株はファンドが人工知能などによる自動投資に参入するようになり、
古典的なシステムトレードは通用しなくなった
気がする。
黒田総裁の月間ETF購入も影響してるだろうけど。
横ばいになるのは、それが理由じゃないかな?
素人の個人投資家がシステムトレードで勝つには
ファンドが購入しないような小型株かつ安定した銘柄
が一つの答えな気がしてる。
ソースコード
バックテストには無料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 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
# loop-type: date-only //============================== require "TIlib" require "Utility" require "TrendCheck" //========================================== // //【買いルール】 // // 1) 株価が100円以上 // 2) 20日平均売買代金が2億円以上 // 3) 100日ヒストリカルボラティリティが30以上 // 4) ADX(10,5)が30以上 // 5) 連続下落日数が2日以上 // 6) 6日移動平均乖離率が-5%以下 // 7) 175日移動平均乖離率が0%以上 // すべての条件に合致した銘柄を翌日指値(当日終値0%) // //【売りルール】 // // 1) 3日移動平均乖離率が+3%以上 // 2) 保有日数が20日以上 // いずれか条件に合致した銘柄を当日引成決済 // //========================================== 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 = 15 // 最大保有日数 $shortSelling = 0 // 空売り戦略 Yes(1)/No(0) $Interest = 1 // 無制限(0) / 単利(1) / 複利(2) $reverse = 0 // 購入順序 昇順(0) / 降順(1) $udcount = 0 // 騰落レシオ利用数 Init() //------------------------------------------------ $DMI = [$code_num] $DiffMA6 = [$code_num] $DiffMA175 = [$code_num] $DiffMA3 = [$code_num] //------------------------------------------------ InitDone() // 騰落レシオ初期化 $__INIT__ = 1 end // 価格変動率 def DayBefore(i) // 前日比 = (終値) ÷ 1日前の終値 return Log((float){i}Close / (float){i - 1}Close ) end // ヒストリカル・ボラティリティ // hv = Math.sqrt(250) * closes[-101..-1].log.dev(100)[-1] * 100 // HV = √250 * 1日あたりのヒストリカルボラティリティ * 100 // 過去20日分(log|今日の価格(株価)÷昨日の価格(株価) |) def CalcHV(num) // 1日あたりのヒストリカルボラティリティ day_hv = 0 a1 = 0 a2 = 0 c = 0 while (c < num) if ! ({(int)(c * -1)}Close && {(int)(c * -1 - 1)}Close) return 0 end a0 = DayBefore(c * -1) a1 = a0 * a0 + a1 a2 = a0 + a2 c = c + 1 end // 標準偏差 = √Σ(a_i - a)^2/N = Σa_i^2/N - (Σa_i/N)^2 day_hv = Sqrt(a1 / (float)num - (a2 / (float)num) * (a2 / (float)num)) // 年間の営業日数の平方根 × 1日あたりのヒストリカルボラティリティ × 100 return Sqrt(250) * day_hv * 100 end def Main(i) //================================================== // 条件(買条件, 売条件共通部分) //================================================== //まだ上場していない銘柄は株価データがないためnullが返る if (Index == null) return end if ($order[(int)Code] == -1) $order[(int)Code] = i end if ! ($DiffMA6[i]) // 銘柄ごとのグローバル変数を初期化する $DMI[i] = DMI_new(10, 5, 0) // ADX(10, 5日) $DiffMA6[i] = DiffMA_new(6) // 6日移動平均線乖離率 $DiffMA175[i] = DiffMA_new(175) // 175日移動平均線乖離率 $DiffMA3[i] = DiffMA_new(3) // 3日移動平均線乖離率 $hold[i] = 0 return end //指標の計算を1日進める DMI_next($DMI[i]) DiffMA_next($DiffMA6[i]) DiffMA_next($DiffMA175[i]) DiffMA_next($DiffMA3[i]) //================================================== // 保有してない→購入 //================================================== if (! $hold[i]) adx = DMI_adx($DMI[i]) diff6 = DiffMA_value($DiffMA6[i]) diff175 = DiffMA_value($DiffMA175[i]) if ! (adx && diff6 && diff175 && Close && {-1}Close && Open && {-1}Open) return end //================================================== // 売買(買い) //================================================== // 1) 株価が100円以上 flag1 = Close >= 100 // 4) ADX(10,5)が30以上 flag4 = adx > 30 // 5) 連続下落日数が2日以上 flag5 = ({-1}Open > {-1}Close) && (Open > Close) // 6) 6日移動平均乖離率が-5%以下 flag6 = diff6 <= -5 // 7) 175日移動平均乖離率が0%以上 flag7 = diff175 >= 0 if ! (flag1 && flag4 && flag5 && flag6 && flag7) return end // 2) 20日平均売買代金が2億円以上 tv = TradingValume(20) flag2 = tv >= 20000 // 3) 100日ヒストリカルボラティリティが30以上 flag3 = CalcHV(100) >= 30 if (flag2 && flag3) PrintLog("買い候補") $buyflag[i][0] = 1 $buyflag[i][1] = diff6 $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 //================================================== // 売買(売り) //================================================== diff3 = DiffMA_value($DiffMA3[i]) if ! (diff3) return end // 1) 3日移動平均乖離率が+3%以上 flag1 = diff3 >= 3 // 1) 利食い if (flag1) PrintLog("利食い") $sellflag[i] = 1 $set[i] = 0 // 3) 損切り elsif ($set[i] >= $MaxHoldDay) $sellflag[i] = 1 $set[i] = 0 end end end def CheckHighLow2(t) t = Yobine(t, 0) if ! ({1}High > t && t > {1}Low) return 0 end if (t > {1}Open) return 0 else return t end end //================================================== // 買い(翌日指値(当日終値0%)) //================================================== def Buying2(i) if (0 == PricedataExistCheck({1}Open)) t = 0 if ($buyflag[i][0] == 1) // 10) [翌日指値(寄付)][終値(0.00%)]以下で[買い]を仕掛ける t = CheckHighLow2(Close) end if (t) BuyingLimitedPrice(i, 1, t) end end end //==================== // 買い処理 //==================== def SortBuy() if ! (HasPricedata({1}Open)) return end $long = 0 $long = Num($buyUnit, Close) codeset = $order[(int)Code] Buying2(codeset) end //==================== // 売り処理(当日引成決済) //==================== def Sell_(i) if ($sellflag[i]) // 当日のCloseで売る 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 |