開発記録(第4回)。AI に日本株の売買判断をさせる投資システム investTool を個人で開発しています。全体像は目次記事にまとめています。

- 手元にあるのは日足(1日ごとの始値・高値・安値・終値)だけで、1日の中で何が先に起きたかは分かりません
- そこで、判断に迷う場面はすべて成績が悪くなる側に倒す決まりにしました
- 無料のデータでは上場廃止の銘柄が抜けているため、合格基準にも上乗せをしています
やりたかったこと
売買ルールの良し悪しを、過去10年分の日足で確かめるバックテストを作ることです。
バックテストの成績は、作り方しだいで実際より良く見えます。良く見えたルールで実際に売買すると、期待どおりの成績になりません。そこで最初に「迷ったら、成績が悪くなる側に倒す」ことを決めてから作りました。
手順
1日ずつ、決まった順番で処理する
表計算のように期間全体をまとめて計算する作り方もありますが、それでは資金の制約(買える株数、同時に持てる銘柄数など)や、損失が増えたときに売買を止める決まりを正しく再現できません。1営業日ずつ進め、その日に起きることを決まった順番で処理する形にしました。

その日の終値を見て「買う」と決めた注文を、同じ日の終値で買えたことにはしません。判断に使った情報より後の値でしか約定させないことで、第1回で書いた先読みバイアスを防いでいます。
注文ごとの約定価格
| 注文 | 約定する条件 | 約定価格 |
|---|---|---|
| 寄り付きの成行 | その日に取引がある | 始値に、不利な方向へ 0.1% ずらした値 |
| 指値買い | 安値が指値以下 | 始値と指値の低いほう |
| 逆指値売り(損切り) | 安値が損切りの価格以下 | 始値が損切りの価格を下回っていれば始値、それ以外は損切りの価格。どちらも 0.1% 不利にずらす |
| 指値売り(利確) | 高値が利確の価格以上 | 始値と利確の価格の高いほう |
損切りで始値を使うのは、前日より大きく下がって始まった(窓を開けた)日を再現するためです。損切りの価格で売れたことにすると、実際より損が小さく見えます。
判断に迷う場面と、その決まり
日足だけでは決められない場面が、いくつもありました。
1. 持っている株が、同じ日に損切りと利確の両方に届いた
株を買うときは、「ここまで下がったら売る(損切り)」と「ここまで上がったら売る(利確)」の2つの価格を決めておきます。買った翌日以降のある日に、値動きが大きく、1日の中で高値は利確の価格を上回り、安値は損切りの価格を下回った場合の話です。
実際の相場なら、先に届いたほうで売れて、その時点で取引は終わります。ところが日足には「高値」と「安値」が1つずつあるだけで、どちらを先に付けたかは記録されていません。

損切りが先とみなします。どちらが先かは日足では分からないため、成績が悪くなる側に倒しています。
2. 買ったその日に、損切りや利確の価格に届いた
1つ目は「すでに持っている株」の話でした。こちらは「その日に買った株」の話です。指値で買う注文は、1日の中のどこかで約定します。約定した後に損切りや利確の価格に届いたのか、それとも約定する前に届いていたのかが、日足では分かりません。
| 状況 | 扱い |
|---|---|
| 買った当日に損切りに届いた | 損切りする(買った時点から損切りの注文が有効) |
| 買った当日に利確に届いた | 利確しない(買う前に高値を付けた可能性があるため、翌日以降に判定する) |
損切りは当日から有効、利確は翌日から、という非対称な扱いです。これも成績が悪くなる側に倒した結果です。
3. ストップ高・ストップ安で値が付かない
高値と安値が同じ(四本値がすべて同じ)日は、値幅の制限に張り付いて売買がほとんど成立しなかった日とみなし、損切りも利確も買いも約定させません。翌日に持ち越します。
損切りの価格を下回ったまま売れない日に「損切りの価格で売れた」ことにすると、損が小さく見えるためです。
4. 価格の端数と、売買の単位
| 項目 | 決まり |
|---|---|
| 売買の単位 | 100株 |
| 呼値(価格の刻み) | 全銘柄に、刻みが粗いほうの表を使う(細かい刻みが適用される銘柄の過去の履歴がないため) |
| 端数の処理 | 買いの指値は切り下げ、利確の指値は切り上げ、損切りの価格は切り下げ(どれも約定しにくい側・損が大きい側) |
5. コスト
| 項目 | 値 |
|---|---|
| 売買手数料 | 0円(オンラインの国内株の取引を想定) |
| スリッページ | 成行と逆指値で、片道 0.1% |
| 税 | 年間の実現益に 20.315% をかけた「税引後」も計算する |
手数料が0円でも、注文を出してから約定するまでの価格のずれは避けられないため、スリッページを入れています。
無料のデータの偏りを、合格基準で割り引く
約定の決まりとは別に、データそのものにも成績が良く見える偏りがありました。
手元の銘柄の一覧は、今も上場している約3,700銘柄だけです。途中で倒産や上場廃止になった銘柄(その前に大きく下がった銘柄)の過去の株価は、無料では手に入りません。そのため、過去の相場から「生き残った銘柄」だけを選んで売買したことになり、成績が良く見えます。
この偏りの大きさを正確に測る方法はありません。そこで、合格基準に上乗せをしました。
| 基準 | 値 |
|---|---|
| TOPIX(配当込み)との差 | 年率で +2% 以上上回る(上乗せ分を含む) |
| 資産の最高値からの下落(最大ドローダウン) | −10% 以内 |
| プロフィットファクター(利益の合計 ÷ 損失の合計) | 1.3 以上 |
| 取引の回数 | 30回以上 |
あわせて、対象の銘柄を「その時点で売買代金が一定以上ある銘柄」(20日平均で5億円以上)に絞り、大型・中型株を中心にすることで、偏りの影響を小さくしています。残る偏りは、これから先の相場での仮想売買で確かめます。
実際にどう使っているか
決まりの1つ1つは、手で計算できる小さなデータで自動テストを書き、計算が合うことを確かめてから実データで動かしました。
日足しかないバックテストでは、決めなければならないことが想像より多くありました。1つ1つの影響は小さくても、すべてを良く見える側に倒すと、成績は大きく変わります。この連載の第6回で書く「8種類の戦略がすべて基準に届かなかった」という結果は、この厳しめの決まりで測ったものです。
この記事の内容に近い書籍
※ Amazon のアソシエイトリンクを含みます。
- 『システムトレード 基本と原則』(ブレント・ペンフォールド、Kindle版)
売買ルールの作り方と検証。この記事のバックテストの約定の決め方と近い本です
前回:Windows のタスクスケジューラで Python のジョブを毎日動かす|PowerShell 5.1・uv・Docker でつまずいた4点
次回:損失時に新規の売買を止める安全装置が、バックテストを無意味にしていた
当サイトは情報提供を目的としており、投資助言を行うものではありません。掲載している売買記録は仮想売買(ペーパートレード)であり、実際の取引の結果ではありません。投資判断はご自身の責任で行ってください。詳しくは免責事項をご覧ください。

