9月30日は台風18号が原因で飛行機は午後からは飛びませんでした。
また、午前便も次のような張り紙が貼ってありました。
台風18号の影響により、場合によっては羽田空港へ引き返す可能性がございます。
無事、台湾に着陸することはできましたが、台湾の会社は軒並み「台風休暇」でした。何だそりゃ・・・。
台風の被害が大きい台湾では、被害を最小限に抑えるため政府から「休校・休業情報」が前日に発表されます。
休校・休業になった場合、学校だけでなく会社や公共施設、お店なども休業になります。
確認は「行政院人事行政總處WEBサイト」で可能です。
夜の10時頃に政府が更新します。日本語訳は次のようになっています。
表示例 | 意味 |
---|---|
明天停止上班,停止上課 | 明日は休校・休業になります |
明天照常上班,照常上課 | 明日は平常通り |
明天上午照常上班,照常上課 | 明日午前は平常通り(午後から休校の可能性あり) |
尚末宣佈消息 | まだ発表されていません |
実は私は事前に知っていたので、水着・ゴーグルを持参してホテルのプールで500mぐらい泳ぎました。
朝食はファーストクラスのラウンジと機内食、昼食は鼎泰豐(ディンタイフォン)、夕食は焼肉と、すごく健康的な1日でした★
さて本題。
Protraで外部データ(例:NYダウ平均)が取得できるようになったので、cosisin氏の手法のバックテストをやってみました。
cosisin氏の2013年08月17日の日記「ドドンパ」です。
cosisin氏のダウ逆張り改良ドドンパ(待ち)の有効性検証
ブログ村には次のように書かれています。
待つというのがコンセプトとなっております。ダウが下がるのを待ち、シグナル数が3日間で1番多くなるまで待ちます。あとは勢いよく落ちてきている銘柄を翌日寄りで体を張って受け止めるだけです。ある程度上にいる銘柄だけに絞っています。下のほうにいるやつはギャップダウンが激しいほどいい感じです。ただし、倒産懸念や、上場廃止懸念がある銘柄はやばい感じなのでやめといたほうがよさそうです。
【基本設定】
- 1) 株価の低い場合はランキングしない[150]万円以下
- 2) 売買代金の少ない場合はランキングしない(売買代金の[3]日間平均が[5]千万円以下の場合)
- 3) 単利利用、通年
- 4) 全ての銘柄対象
【買いルール】
- 1) [前日比(率)]が[-5]より[小さい(同じ含む)]
- 2) [始値→終値(率)]が[-5]より[小さい(同じ含む)]
- If(1 or 2) 3) [前日比(率)(1日前)]が[0]より[大きい]
- 4) [始値→終値(率)(1日前)]が[0]より[小さい]
- If (3 or 4) 5) [移動平均乖離率(終値)(75)]が[0]より[大きい]
- 6)[期間上昇(率)(25)]が[0]より[大きい]
- If(5 or 6) 7) [始値]が[終値(1日前)]より[小さい]
- 8) [移動平均乖離率(終値)(5)]が[0]より[小さい]
- 9) [翌日始値]が[終値(-5.00%)]より[大きい]
- If(9) 10) [翌日指値(寄付)][終値(-2.00%)]で[買い]を仕掛ける
- Else(9) 11) [翌日逆指(終日)][翌日始値(+1Tick)]で[買い]を仕掛ける
【仕掛け条件】
- [寄り逆張り] = [移動平均乖離率(終値)(3)] が[小さい順]
- 12)[寄り逆張り(仕掛け銘柄数)]が[寄り逆張り(仕掛け銘柄数の期間最大(3))]より[大きい(同じ含む)]
- 13)[ダウ終値(前日比)]が[0]より[小さい]
【手仕舞いルール】
- 1) [Stop高(高値)]が[1]と[同じ]
- 2) [当日指定値][高値]で手仕舞いする
- 3) [保有日数]が[1]より[大きい(同じ含む)]
- 4) [当日引け]で手仕舞いする
複雑過ぎる・・・・。
これ・・・絶対に自分では思いつかないよ・・・。
分岐があり過ぎです。
さらに翌日始値に応じて購入額を変更しています。こんなのは現実には簡単ではありません。
Protraで実装するだけでも数時間かかりました・・・。
ソースコード
TIlib、Utility、TrendCheckライブラリはGitHubに置いています(日記の公開日に合わせたバージョンを利用下さい)
外部データを利用します。「CSVを読み込み外部データを使えるようにする方法」を先に読んで設定してください。
今回は「銘柄番号1番」に「ダウ平均」を登録しています。
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 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
# loop-type: date-only //============================== require "TIlib" require "Utility" require "TrendCheck" // ====================================== // cosisinのダウ逆張り改良ドドンパ(待ち) // ====================================== // //【基本設定】 // 1) 株価の低い場合はランキングしない[150]万円以下 // 2) 売買代金の少ない場合はランキングしない(売買代金の[3]日間平均が[5]千万円以下の場合) // 3) 単利利用、通年 // 4) 全ての銘柄対象 // //【買いルール】 // 1) [前日比(率)]が[-5]より[小さい(同じ含む)] // 2) [始値→終値(率)]が[-5]より[小さい(同じ含む)] // If(1 or 2) 3) [前日比(率)(1日前)]が[0]より[大きい] // 4) [始値→終値(率)(1日前)]が[0]より[小さい] // If (3 or 4) 5) [移動平均乖離率(終値)(75)]が[0]より[大きい] // 6)[期間上昇(率)(25)]が[0]より[大きい] // If(5 or 6) 7) [始値]が[終値(1日前)]より[小さい] // 8) [移動平均乖離率(終値)(5)]が[0]より[小さい] // 9) [翌日始値]が[終値(-5.00%)]より[大きい] // If(9) 10) [翌日指値(寄付)][終値(-2.00%)]で[買い]を仕掛ける // Else(9) 11) [翌日逆指(終日)][翌日始値(+1Tick)]で[買い]を仕掛ける // // 【仕掛け条件】 // [寄り逆張り] = [移動平均乖離率(終値)(3)] が[小さい順] // 12)[寄り逆張り(仕掛け銘柄数)]が[寄り逆張り(仕掛け銘柄数の期間最大(3))]より[大きい(同じ含む)] // 13)[ダウ終値(前日比)]が[0]より[小さい] // //【手仕舞いルール】 // 1) [Stop高(高値)]が[1]と[同じ] // 2) [当日指定値][高値]で手仕舞いする // 3) [保有日数]が[1]より[大きい(同じ含む)] // 4) [当日引け]で手仕舞いする codes = CodeList if ($code_num && $code_num != Length(codes)) Print("前回と異なる銘柄リストでは実行できません。") Dummy end $code_num = Length(codes) //グローバル変数を初期化 if (!$__INIT__) $budgetIni = 10000000 $buyUnit = 1000000 // 1回の購入資金 (100万円) $MaxHoldDay = 0 // 最大保有日数 $shortSelling = 0 // 空売り戦略 Yes(1)/No(0) $Interest = 1 // 無制限(0) / 単利(1) / 複利(2) $reverse = 0 // 購入順序 昇順(0) / 降順(1) $udcount = 0 // 騰落レシオ利用数 Init() // テクニカル指標初期化 -------------------------- $DiffMA75 = [$code_num] $DiffMA5 = [$code_num] $DiffMA3 = [$code_num] $buyCnt0 = 0 // 仕掛け銘柄数 0日前 $buyCnt1 = 0 // 仕掛け銘柄数 1日前 $buyCnt2 = 0 // 仕掛け銘柄数 2日前 $buyCnt3 = 0 // 仕掛け銘柄数 3日前 $check13 = 0 // 騰落レシオ初期値代入($udcountの数) ---------- //------------------------------------------------ InitDone() // 騰落レシオ初期化 $__INIT__ = 1 end // 1) [期間上昇(率)]=[当日終値(現在値)]÷[指定期間前の終値] def PeriodUpRate(i) if ! ({-1 * i}Close) return 0 end return (float)Close / (float){-1 * i}Close * 100 end def Main(i) //================================================== // 条件(買条件, 売条件共通部分) //================================================== //まだ上場していない銘柄は株価データがないためnullが返る if (Index == null) return end if ! ($order[(int)Code]) $order[(int)Code] = i end if ! ($DiffMA75[i] && $DiffMA5[i] && $DiffMA3[i]) // 銘柄ごとのグローバル変数を初期化する $DiffMA75[i] = DiffMA_new(75) $DiffMA5[i] = DiffMA_new(5) $DiffMA3[i] = DiffMA_new(3) $hold[i] = 0 return end // 指標の計算を1日進める DiffMA_next($DiffMA75[i]) DiffMA_next($DiffMA5[i]) DiffMA_next($DiffMA3[i]) if ! (Index >= 75) return end //================================================== // 保有してない→購入 //================================================== if (! $hold[i]) diffma75 = DiffMA_value($DiffMA75[i]) diffma5 = DiffMA_value($DiffMA5[i]) if ! (diffma75 && diffma5 && Close && {"1"}Close && {-1}{"1"}Close ) return end if ! (Volume && Close && {-1}Close && {-2}Close && {-3}Close) return end //================================================== // 売買(買い) //================================================== // 1) 株価の低い場合はランキングしない[150]万円以下 // 2) 売買代金の少ない場合はランキングしない(売買代金の[3]日間平均が[5]千万円以下の場合) if ! (SalesValue()/3 + {-1}SalesValue()/3 + {-2}SalesValue()/3 > 50000 && Close > 150) return end // 1) [前日比(率)]が[-5]より[小さい(同じ含む)] check1 = -5 >= DayBfrRatio() // 2) [始値→終値(率)]が[-5]より[小さい(同じ含む)] check2 = -5 >= OpenToClose() if ! (check1 || check2) return end // 3) [前日比(率)(1日前)]が[0]より[大きい] check3 = {-1}DayBfrRatio() > 0 // 4) [始値→終値(率)(1日前)]が[0]より[小さい] check4 = 0 > {-1}OpenToClose() if ! (check3 || check4) return end // 5) [移動平均乖離率(終値)(75)]が[0]より[大きい] check5 = diffma75 > 0 // 6)[期間上昇(率)(25)]が[0]より[大きい] check6 = PeriodUpRate(25) > 0 if ! (check5 || check6) return end // 7) [始値]が[終値(1日前)]より[小さい] check7 = {-1}Close > Open // 8) [移動平均乖離率(終値)(5)]が[0]より[小さい] check8 = 0 > diffma5 if (check7 && check8) diffma3 = DiffMA_value($DiffMA3[i]) if ! (diffma3) return end PrintLog("購入候補 diffma3=" + diffma3) // 9) [翌日始値]が[終値(-5.00%)]より[大きい] if ! ({1}Open) return end check9 = {1}Open > Close * 0.95 // 13)[ダウ終値(前日比)]が[0]より[小さい] $check13 = 0 > ((float)({"1"}Close - {-1}{"1"}Close) / {-1}{"1"}Close * 100) if (check9) // 10) [翌日指値(寄付)][終値(-2.00%)]で[買い]を仕掛ける $buyflag[i][0] = 1 // 好きなパラメータをもとにソート $buyflag[i][1] = diffma3 $buyCnt = $buyCnt + 1 else // 11) [翌日逆指(終日)][翌日始値(+1Tick)]で[買い]を仕掛ける $buyflag[i][0] = 2 // 好きなパラメータをもとにソート $buyflag[i][1] = diffma3 $buyCnt = $buyCnt + 1 end end //================================================== // 保有している→売却 //================================================== elsif ($hold[i]) if ($set[i] < 1) $set[i] = 1 return end $set[i] = $set[i] + 1 //================================================== // 売買(売り) //================================================== // 1) [Stop高(高値)]が[1]と[同じ] // 2) [当日指定値][高値]で手仕舞いする // 3) [保有日数]が[1]より[大きい(同じ含む)] // 4) [当日引け]で手仕舞いする if ($set[i] >= $MaxHoldDay) PrintLog("手仕舞い") $sellflag[i] = 1 $set[i] = 0 end end end //================================================== // 買い(カスタマイズ条件) //================================================== def Buying2(i) if (0 == PricedataExistCheck({1}Open)) if ($buyflag[i][0] == 1) // 10) [翌日指値(寄付)][終値(-2.00%)]で[買い]を仕掛ける t = StopOrderClose(0.98) else // 11) [翌日逆指(終日)][翌日始値(+1Tick)]で[買い]を仕掛ける t = StopOrderOpenTick() end if (t) BuyingLimitedPrice(i,1,t) end end end //==================== // 買い処理 //==================== def SortBuy(i) if (PricedataExistCheck(Close)) return end $long = 0 $long = Num($buyUnit, Close) codeset = $order[(int)Code] Buying2(codeset) end //================================================== // 売り(カスタマイズ条件) //================================================== def Selling2(i) if (0 == PricedataExistCheck(Close)) SellingClose(i,0) end end //==================== // 売り処理 //==================== def Sell_(i) if ($sellflag[i]) Selling2(i) $sellflag[i] = 0 end // 使用した$buyflag 配列を初期化 if ($buyflag[i][0]) $buyflag[i][0] = 0 $buyflag[i][1] = 0 end 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 while i + 1 < $code_num i = i + 1 {codes[i]}Sort(i) end i = -1 // 12)[寄り逆張り(仕掛け銘柄数)]が[寄り逆張り(仕掛け銘柄数の期間最大(3))]より[大きい(同じ含む)] $buyCnt3 = $buyCnt2 $buyCnt2 = $buyCnt1 $buyCnt1 = $buyCnt0 $buyCnt0 = $buyCnt if ($check13 && ($buyCnt0 > $buyCnt1 || $buyCnt0 > $buyCnt2 || $buyCnt0 > $buyCnt3)) while i + 1 < $buyCnt i = i + 1 {$sortList2[i]}SortBuy(i) end end i = -1 while i + 1 < $code_num i = i + 1 {codes[i]}Sell_(i) end $check13 = 0 |
バックテスト結果
バックテストの計算時間は約2時間です。
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 |
株価データ: 日足 銘柄リスト: 全銘柄 1998/01/05~2019/09/24における成績です。 ---------------------------------------- 全トレード数 3551 勝ちトレード数(勝率) 1922(54.13%) 負けトレード数(負率) 1629(45.87%) 全トレード平均利率 0.72% 勝ちトレード平均利率 5.12% 負けトレード平均損率 -4.48% 勝ちトレード最大利率 55.86% 負けトレード最大損率 -30.94% 全トレード平均期間 1.47 勝ちトレード平均期間 1.44 負けトレード平均期間 1.52 ---------------------------------------- 必要資金 ¥9,712,900 最大ポジション(簿価) ¥9,985,200 最大ポジション(時価) ¥11,345,600 純利益 ¥22,813,320 勝ちトレード総利益 ¥88,652,820 負けトレード総損失 -¥65,839,500 全トレード平均利益 ¥6,424 勝ちトレード平均利益 ¥46,125 負けトレード平均損失 -¥40,417 勝ちトレード最大利益 ¥537,600 負けトレード最大損失 -¥302,400 プロフィットファクター 1.35 最大ドローダウン(簿価) -¥2,012,120 最大ドローダウン(時価) -¥2,160,120 ---------------------------------------- 現在進行中のトレード数 0 ---------------------------------------- 平均年利 11.74% 平均年利(直近5年) 1.38% 最大連勝 11回 最大連敗 8回 ---------------------------------------- [年度別レポート] 年度 取引回数 運用損益 年利 勝率 PF 最大DD 2019年 140回 ¥513,500円 5.29% 54.29% 1.23倍 -12.71% 2018年 253回 -¥250,916円 -2.58% 50.20% 0.95倍 -24.14% 2017年 106回 ¥864,687円 8.90% 56.60% 1.54倍 -13.17% 2016年 207回 -¥431,996円 -4.45% 50.24% 0.91倍 -23.83% 2015年 207回 -¥25,136円 -0.26% 45.89% 0.99倍 -20.42% 2014年 205回 ¥626,500円 6.45% 49.27% 1.14倍 -20.35% 2013年 212回 ¥1,876,840円 19.32% 52.36% 1.42倍 -23.02% 2012年 113回 -¥191,900円 -1.98% 45.13% 0.93倍 -25.97% 2011年 147回 ¥500,268円 5.15% 51.02% 1.12倍 -30.94% 2010年 106回 -¥65,800円 -0.68% 55.66% 0.96倍 -20.58% 2009年 190回 ¥1,923,614円 19.80% 61.58% 1.81倍 -11.65% 2008年 374回 ¥1,763,968円 18.16% 53.48% 1.24倍 -19.89% 2007年 193回 ¥2,200,400円 22.65% 63.21% 1.81倍 -16.56% 2006年 206回 ¥2,699,712円 27.80% 58.25% 1.91倍 -14.47% 2005年 84回 ¥2,684,876円 27.64% 72.62% 4.61倍 -9.81% 2004年 143回 ¥1,898,300円 19.54% 58.74% 1.68倍 -13.58% 2003年 144回 ¥2,046,900円 21.07% 63.19% 1.96倍 -18.56% 2002年 177回 ¥1,588,000円 16.35% 62.71% 1.62倍 -17.27% 2001年 160回 ¥1,984,500円 20.43% 59.38% 2.02倍 -14.05% 2000年 184回 ¥607,000円 6.25% 55.43% 1.17倍 -20.58% |
利益曲線は次のとおりです。
cosisin氏のブログには2011年頃までの資金曲線が書かれていますが、そこまでは私の実装でも単調増加をしています。
まとめ
急遽仕事が休みとなったので実装してみましたが、これを通常時に実装する気にはなれません・・・・。
これだけパラメーターが入っているとカーブフィッティングするのは当然では?