明日、朝になって相場が開くのが恐怖でしかない。
時間がこのまま止まって日付が変わらないでほしいと切に思う。
明日になったら嫌でも含み損と向き合わなければならないから。これほどまでに時間が残酷なものになり得るなんて知らなかった。
時を刻む音が、確実に迫りくる破産の足音にしか聞こえない。
死刑宣告された囚人や余命僅かな末期患者も、同じような心境になるのだろうか。
[引用] 専業トレーダーになって1000万損した男の末路
どんなに苦しくてもウイットに富んだ文が書けるのは才能だ、うらやましい。
「時を刻む音が・・」とか使ったことないよ。
結局、振り返ってみると、コロナで笑ったもの、泣いたもの色々いた。
思ったより相場は下がらなかったし、思った以上に株価が上がっている。
この時期の自分の日記を見直すと、生き物観察ばかりしていた。
自然と戯れてる場合じゃなかったな・・・・。
とは言え、過去20年間のバッグテストで勝ち続けることが出来るストラテジーが全く作れません。
根気が足りないのか?
アイデア不足なのか?
知識が足りないのか?
経験不足なのか?
・・・・・全く分かりません。
優秀なストラテジーを組み合わせると期待する結果が得られるかもしれない。
ということで、ライブラリの拡張です。
ストラテジーの合体手法
各種ストラテジーを合体する記事は過去にも登場しています。
![](https://nehori.com/nikki/wp-content/uploads/2019/10/mix-160x90.jpg)
ですが、それらは
- シグナルが出たら合算してソートを行い買い判断をする
というものでした。
そして、フラグが多くてソースコードが汚くなり公開できませんでした。
勝率やプロフィットファクターに応じて、ストラテジーには優先度がつけたくなるものです。つまり、
- 優先度の高いストラテジーのシグナルを優先して購入する
これを実現する為に、
- ソートの手法
- 購入フラグ
などを見直しました。
利用したストラテジー
今回はあくまでライブラリ実装なので、ストラテジーは有名な「斉藤正章氏の手法」と「三点チャージ法」を組み合わせました。
斉藤正章氏の手法は次のとおりです。
【買い】
- 1) 25日間移動平均との乖離率が-25%を下回った。
- 2) 5日間移動平均との乖離率が-10%を下回った。
- 3) 急落している銘柄数が、過去100営業日の平均と比べて7倍以上
【売り】
- 1) 買値の10%を上回った
- 2) 4営業日経過
3点チャージ法は次のとおりです。
【買い】
- 1) 移動平均線の乖離率(26日)の乖離率が-15%以下
- 2) VR(25日)が70%以下
- 3) RSI(14日)が25%以下
【売り】
- 1) 買値の10%を上回った
- 2) 2営業日経過 or 買値5%を下回った
ソースコード
独自ライブラリの取り込みが必要です(Utility.ptは今回の為に更新しました)
- [NEW] Utility.pt
- TIlib.pt
- TrendCheck.pt
実装としては次のようになります。
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 |
# loop-type: date-only //============================== require "TIlib" require "Utility" require "TrendCheck" //============================== // 斎藤氏の手法 → 3点チャージ法 の順で購入 //============================== // 1) 株価の高い場合はランキングしない[200]円以下 // 2) 売買代金の少ない場合はランキングしない(売買代金の[3]日間平均が[1]千万円以下の場合) // // 斉藤正章氏の手法 // 【買い】 // 1) 25日間移動平均との乖離率が-25%を下回った。 // 2) 5日間移動平均との乖離率が-10%を下回った。 // 3) 急落している銘柄数が、過去100営業日の平均と比べて7倍以上 // 【売り】 // 1) 買値の10%を上回った // 2) 4営業日経過 // // 3点チャージ法 // 【買い】 // 1) 移動平均線の乖離率(26日)の乖離率が-15%以下 // 2) VR(25日)が70%以下 // 3) RSI(14日)が25%以下 // 【売り】 // 1) 買値の10%を上回った // 2) 2営業日経過 or 買値5%を下回った //============================== 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 = 3 // 最大保有日数 $shortSelling = 0 // 空売り戦略 Yes(1)/No(0) $Interest = 1 // 無制限(0) / 単利(1) / 複利(2) $reverse = 0 // 購入順序 昇順(0) / 降順(1) $udcount = 0 // 騰落レシオ利用数 Init() //------------------------------------------------ // 斎藤氏の手法 $MA5 = [$code_num] $MA25 = [$code_num] // 3点チャージ法 $VR = [$code_num] $Diff = [$code_num] $RSI = [$code_num] // 値上がり銘柄のカウント ------------------------ InitDone() // 騰落レシオ初期化 $__INIT__ = 1 end def Main(i) //================================================== // 条件(買条件, 売条件共通部分) //================================================== //まだ上場していない銘柄は株価データがないためnullが返る if (Index == null) return end if ! ($order[(int)Code]) $order[(int)Code] = i end //================================================== if ! ($MA5[i] && $MA25[i]) // 斎藤氏 $MA5[i] = MA_new(5) $MA25[i] = MA_new(25) // 3点チャージ法 $Diff[i] = DiffMA_new(26) $VR[i] = VR_new(25, 0) $RSI[i] = RSI_new(14, 0) // グローバル変数を初期化 $hold[i] = 0 return end // 斉藤正章氏の指標の計算を1日進める MA_next($MA5[i]) MA_next($MA25[i]) // 3点チャージの指標の計算を1日進める DiffMA_next($Diff[i]) VR_next($VR[i]) RSI_next($RSI[i]) // ここまで ======================================== //================================================== // 保有してない→購入 //================================================== if ! ($hold[i]) // 1) 株価の高い場合はランキングしない[200]円以下 // 2) 売買代金の少ない場合はランキングしない(売買代金の[3]日間平均が[1]千万円以下の場合) if ! ({-1}Close && Close && {-2}Close && {-3}Close) return end if ! (Volume && {-1}Volume && {-2}Volume) return end if ! (SalesValue()/3 + {-1}SalesValue()/3 + {-2}SalesValue()/3 > 50000 && Close > 50) return end // 斉藤正章氏の手法 ma5 = MA_value($MA5[i]) ma25 = MA_value($MA25[i]) if ! (ma5 && ma25 && Close && Close >= 50) return end r25 = 100 * (Close - ma25) / ma25 r5 = 100 * (Close - ma5) / ma5 // 3点チャージ法 diff = DiffMA_value($Diff[i]) vr = VR_value($VR[i]) rsi = RSI_value($RSI[i]) if ! (diff && vr && rsi && Close) return end // 購入ロジック saito = r25 <= -25 && r5 <= -10 chage3 = diff <= -15 && vr <= 70 && rsi <= 25 if (saito) PrintLog("斉藤正章氏の手法") $buyflag[i][0] = 1 // 購入フラグ $buyflag[i][1] = r25 // 好きなパラメータをもとにソート $buyflag[i][2] = $buyflag[i][0] // 呪文(複数ロジック用) $buyCnt = $buyCnt + 1 elsif (chage3) PrintLog("3点チャージ法") $buyflag[i][0] = 2 // 購入フラグ $buyflag[i][1] = diff // 好きなパラメータをもとにソート $buyflag[i][2] = $buyflag[i][0] // 呪文(複数ロジック用) $buyCnt = $buyCnt + 1 end //================================================== // 保有している→売却 //================================================== elsif ($hold[i]) if $set[i] < 1 $set[i] = 1 return end $set[i] = $set[i] + 1 //================================================== // 売買(売り) //================================================== // 1) 利食い if ($buyflag[i][2] == 1 && (Close >= 1.10 * $buy[i])) PrintLog("斉藤正章氏_利食い") $sellflag[i] = 1 $set[i] = 0 elsif ($buyflag[i][2] == 2 && (Close >= 1.10 * $buy[i])) PrintLog("3点チャージ_利食い") $sellflag[i] = 1 $set[i] = 0 // 2) 損切り elsif ($buyflag[i][2] == 1 && ($set[i] >= 4)) PrintLog("斉藤正章氏_損切り") $sellflag[i] = 1 $set[i] = 0 elsif ($buyflag[i][2] == 2 && (Close <= 0.95 * $buy[i] || $set[i] >= 2)) PrintLog("3点チャージ_損切り") $sellflag[i] = 1 $set[i] = 0 end end 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 //==================== // 買い処理 //==================== def SortBuy(i) if (PricedataExistCheck(Close)) return end $long = 0 $long = Num($buyUnit, Close) codeset = $order[(int)Code] Buying(codeset) end //==================== // 銘柄コードを変えながらMain関数,BuySell関数を実行 //==================== Print("-------------------------------------------------") Print("日付 = "+ Year + "/" + Month + "/" + Day) SortInit() // ソート初期化 i = -1 while (i + 1 < $code_num) i = i + 1 {codes[i]}Main(i) end i = -1 // ストラテジーによって買いの優先度を変える if ($buyCnt) // 斉藤正章氏の手法 sg = SignalCount(100) // 突入タイミング 過去100日平均サイン点灯数の7倍以上 Print("過去100日平均サイン点灯数 =" + sg + " $sflag=" + $sflag) BuyLoop(1, sg * 7, codes) // 3点チャージ法 BuyLoop(2, 1, codes) end //---------------------------------------------- i = -1 while i + 1 < $code_num i = i + 1 {codes[i]}Sell_(i) end |
重要なのは「BuyLoop」というストラテジー毎にソートして購入する関数を呼び出す部分と、「$buyflag[i][2]」というストラテジー判別子です。
また「$MaxHoldDay」という変数は使っていません。ストラテジー毎に売却タイミングも異なるためです。
それ以外は、以前とできる限り同じような実装にしています。
バックテスト結果
実行結果は次のようになります。
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 |
ファイル: 3点チャージ法+斉藤氏の手法.pt 株価データ: 日足 銘柄リスト: 全銘柄 1998/01/05~2020/08/07における成績です。 ---------------------------------------- 全トレード数 6835 勝ちトレード数(勝率) 3363(49.20%) 負けトレード数(負率) 3472(50.80%) 全トレード平均利率 0.67% 勝ちトレード平均利率 5.97% 負けトレード平均損率 -4.45% 勝ちトレード最大利率 67.58% 負けトレード最大損率 -49.46% 全トレード平均期間 2.99 勝ちトレード平均期間 3.02 負けトレード平均期間 2.96 ---------------------------------------- 必要資金 ¥2,908,600 最大ポジション(簿価) ¥2,999,200 最大ポジション(時価) ¥3,580,300 純利益 ¥20,632,270 勝ちトレード総利益 ¥88,188,930 負けトレード総損失 -¥67,556,660 全トレード平均利益 ¥3,019 勝ちトレード平均利益 ¥26,223 負けトレード平均損失 -¥19,458 勝ちトレード最大利益 ¥319,800 負けトレード最大損失 -¥231,000 プロフィットファクター 1.31 最大ドローダウン(簿価) -¥1,872,860 最大ドローダウン(時価) -¥2,026,760 ---------------------------------------- 現在進行中のトレード数 4 ---------------------------------------- 平均年利 33.78% 平均年利(直近5年) 7.28% 最大連勝 13回 最大連敗 9回 ---------------------------------------- [年度別レポート] 年度 取引回数 運用損益 年利 勝率 PF 最大DD 2020年 238回 -¥1,114,795円 -38.33% 45.80% 0.68倍 -27.25% 2019年 370回 ¥1,065,883円 36.65% 54.59% 1.48倍 -24.93% 2018年 491回 -¥410,814円 -14.12% 48.27% 0.91倍 -49.46% 2017年 293回 ¥896,520円 30.82% 52.56% 1.54倍 -13.03% 2016年 352回 ¥622,615円 21.41% 49.15% 1.22倍 -13.76% 2015年 327回 ¥313,426円 10.78% 49.85% 1.10倍 -26.70% 2014年 330回 ¥1,739,330円 59.80% 52.12% 1.68倍 -20.25% 2013年 253回 ¥1,171,440円 40.28% 51.78% 1.46倍 -23.47% 2012年 267回 ¥800,800円 27.53% 54.31% 1.36倍 -21.37% 2011年 247回 ¥1,617,220円 55.60% 53.04% 1.67倍 -38.59% 2010年 276回 ¥1,616,120円 55.56% 60.87% 1.77倍 -14.42% 2009年 267回 ¥1,350,120円 46.42% 56.18% 1.46倍 -29.35% 2008年 467回 ¥658,195円 22.63% 49.04% 1.09倍 -28.87% 2007年 467回 -¥736,960円 -25.34% 45.18% 0.87倍 -22.27% 2006年 377回 ¥679,700円 23.37% 49.87% 1.15倍 -30.99% 2005年 252回 ¥2,094,870円 72.02% 53.97% 2.12倍 -22.73% 2004年 279回 ¥1,276,400円 43.88% 54.12% 1.45倍 -22.92% 2003年 244回 ¥2,034,100円 69.93% 58.61% 2.04倍 -21.74% 2002年 316回 ¥1,208,000円 41.53% 52.85% 1.38倍 -23.08% 2001年 357回 ¥1,151,100円 39.58% 52.10% 1.30倍 -29.23% 2000年 365回 ¥2,599,000円 89.36% 53.15% 1.63倍 -24.53% |
利益曲線は次の通りです。
ログを見る限り、優先順序に従って購入できているようなので、とりあえず動作しているようです。
組み合わせたストラテジーは両方とも底狙いの逆張り手法なので、結果がよくなる・・・という事はありませんでした。
まとめ
今回は「実装方法」の紹介なので「ストラテジー」はサンプルです。
この実装により、何個の手法でも組み合わせる事が可能となります。
たとえば保有期間の異なる「順張り」+「空売り」+「逆張り」などが、組み合わせてバックテストが可能となります。
なお、ストラテジー毎に一銘柄あたりの購入額を分けることはサポートしていません。