自動売買システム構築記録

国内株自動売買 発注未解禁

マーケットスピードIIのRSS経由で国内株の現物をスイング(数日〜2週)で扱う。リスク層とブリッジができ、判断層はインターフェースだけ定義した段階。株式は単元株・値幅制限・立会時間・差金決済規制と制約が多く、その大半をリスク層が担っている。

基本情報

証券会社
楽天証券 マーケットスピードII
連携方式
RSS(Excelのワークシート関数)
取引区分
現物のみ(信用は非対応)
想定保有期間
数日〜2週(スイング)
実行層
Excel VBA(未実装)
判断層
Python / FastAPI
現在のエンジン
未実装(常に待機を返すスタブ)
テスト
140 件
コード行数
3,157 行
コミット
1

ディレクトリ構成

backtest/
bridge/
config/
decision/
state/
tests/

構成

Excelが RSS で価格を読み、HTTPでブリッジに問い合わせる。売買判断とリスク判定は すべてPython側にあり、Excelは結果を実行するだけ。FX版のEAと同じ役割分担で、実行環境だけが違う。

Excel (RSS関数) ──HTTP──▶ ブリッジ ──▶ リスク層 ──▶ 判断層
    ▲                                                   │
    └──── buy / sell / hold / close_all ────────────────┘

マーケットスピードIIはDDEではなくワークシート関数でデータを渡す。 旧マーケットスピードの =RSS|'コード'!'項目' 形式は使えず、 =RssMarket("4755.T","現在値") のように呼ぶ。この違いに気づくまで、 Excelが存在しない旧DDEサーバーを起動しようとして失敗し続けた。

現物取引には法令上の回数制限がある

同一営業日・同一銘柄・同一資金で「買い→売り→買い」と回転させると 差金決済に該当し、金融商品取引法・取引所規則に抵触する。

操作可否
A買い → A売り問題なし
A買い → A売り → A買い差金決済に該当
A買い → A売り → B買い別銘柄なので対象外

銘柄単位の規制なので、複数銘柄を扱えば1日の取引回数自体は増やせる。 ただし本システムは数日保有のスイングなので、この制限は本来発動しない。 ロジックの不具合で同日に売買を繰り返した場合の歯止めとして設定に残している。

単元株が割れないので、買える株価に上限が出る

1トレードの許容損失額を固定し、そこから株数を逆算する設計にしている。 ところが株式は単元(多くは100株)単位でしか買えないため、 1単元でも許容損失を超える銘柄は、どうやっても発注できない

損切り幅買える株価の上限
3%約 2,000円
5%約 1,200円
8%約 750円

1トレード許容損失6,000円・単元100株での計算。株数を刻んで収めることができないため、 この場合は0株(発注しない)を返す。FXのように0.01ロット単位で調整できないことの帰結で、 銘柄選定がリスク設定に縛られるという株式固有の性質になっている。

同時保有数と日次損失上限は独立に決められない

複数銘柄を持つ場合、全銘柄が同じ日に損切りされる可能性を考える必要がある。 日本株は下げ日の相関が高く、これは想定すべきケース。

1トレード許容損失 × 同時保有数 ≤ 1日の損失上限

これが破れていると、1日の損失上限に達して停止する前に、上限を超える損失が確定してしまう。 設定の読み込み時に検証し、条件を満たさない組み合わせは起動を拒否する

実際、同時保有を3銘柄にした際に「1トレード1万円 × 3 = 3万円 > 日次上限2万円」となり、 許容損失を6,000円へ下げる必要が生じた。上限値は単独では決められない。

実装済みの関門

判断層が「買い」と言っても、以下のいずれかに触れれば発注しない。

状況挙動
1日の損失が上限到達全ポジション決済 + 新規建て停止
ブリッジ無応答新規建てを一切行わない
立会時間外・寄り5分以内・引け15分前新規建てしない(決済は通す)
ストップ高安に接近板が枯れて損切りが通らないため建てない
気配が5秒以上古い接続断を疑い、判断に使わない
単元株の倍数でない拒否
単元株・呼値が未登録の銘柄拒否
同一銘柄の積み増し拒否(建玉ごとの損失見積もりが崩れるため)
買付余力・1銘柄の投入額・合計建玉額の超過拒否

損切りと利確の指値は呼値の刻みに丸める。損切りはエントリー側へ切り上げ、利確は手前へ切り下げる。 逆向きに丸めると、損切り幅が想定より広がって許容損失を超えたり、 1刻み届かずに決済できなかったりする。

銘柄は事前に登録した固定リストのみ

単元株数と呼値の単位は銘柄ごとに違う。推測で設定に入れると、 単元違いで想定の10倍を発注したり、呼値違いで損切り指値が弾かれて 損切りのないポジションが残る

そのため、RSSで実値を確認した銘柄しか設定に入れない。未登録の銘柄が来たら発注せずに拒否する。 =RssMarket("4755.T","売買単位")=RssMarket("4755.T","呼値単位") で確認する。

この制約により、毎日入れ替わる銘柄リストを自動で取り込む構成は採れない。 候補を毎朝選ぶ仕組みと組み合わせるには、その日の銘柄の単元株と呼値を 発注前に検証する経路が別途要る。

未解決の課題

発注機能は解禁していません。バックテストが完了するまで、 マーケットスピードII側の「発注可能」には切り替えない方針です。

課題状態
判断ロジック未実装(常に待機を返すスタブ)
バックテスト未実施
寄りギャップへの備え未実装。スイングで持ち越すが、損切り指値はギャップダウンを防げない
制限値幅テーブルJPX公式表との照合が未了
買付余力の取得未取得。取得できないうちは全発注がブロックされる

3番目は特に未解決で、FX版が急変スリッページを想定して建玉を絞っているのに対し、 株式側にはまだ相当する仕組みがない。