楽天証券の口座でデイトレの自動売買に挑戦しようと Windows / Excel 上で利用できる マーケットスピード II RSS を活用して Python であれこれ取り組んでいます。この「自動売買への道」のトピックでは、プログラミングの話題にも踏み込んで、日々の活動をまとめていきます。
デイトレ用自作アプリ
以下は株価に関連する情報の流れを示しています。
楽天証券では、Python からネットワーク越しに直接取引できるような API が提供されていないので、マーケットスピード II RSS を介して取引をする構成を取っています。
強化学習のシステム作成
生成 AI との対話が続く
GPT-5 とチャットを続けていると、過去のチャットの内容も拾いだしてうまくまとめてくれるときがあります。環境クラスについてやり取りをしているときに具体的な情報を補足したところ、きれいにシステム構成をまとめてくれたので、重要な部分を拾ってまとめ直しました。
構成(楽天証券 Market Speed II RSS + xlwings 前提)
- 🖥 学習 PC (Fedora Linux)
- 役割: 大量データ処理 + 強化学習
- モジュール:
- データ前処理
- Windows 側で収集したティックデータ(Excel 形式)の読込
- pandas / TA-Lib / pandas-ta でテクニカル指標算出
- 特徴量付与済みのデータセットを構築
- 環境クラス (TradingEnv)
- gymnasium 準拠
- 特徴量付きデータを observation として返す
- PnL / 制約違反のペナルティを reward に反映
- エージェント (PPO など)
- PyTorch 実装で学習
- 学習済みモデルを .pt ファイルで保存
- モデル管理
- 推論 PC に転送しやすい形で保存(例: model_latest.pt)
- データ前処理
- ⚡ 推論 PC (Windows 11)
- 役割: リアルタイム取引判断
- モジュール:
- ティック取得
- Market Speed II RSS + xlwings で Excel 経由のティックデータを取得
- 定期的に Python (Windows) から xlwings API で読み取り
- 前処理モジュール
- 学習 PC で使った前処理クラスと同じロジックを移植
- 新しいティック到着時にテクニカル指標を「直近のみ更新」
- 特徴量ベクトルを生成
- 推論モジュール
- 学習済み PyTorch モデル (model_latest.pt) をロード
- obs → model → action でアクションを推論
- 制約チェックモジュール(既に仕組みで実現できている)
- ナンピン禁止(そもそもナンピンができない仕組みになっている)
- 建玉は 1 単位まで(期待通りの動作が確認できてから増やせばよい)
- 大引けで強制クローズ(実際にはクロージング・オークション直前 15:24:50 で終了)
- → モデルの出力を必ずここでフィルタリング(既に仕組みでブロックできている)
- 注文モジュール
- Market Speed II RSS 経由で発注
- Fill / Reject を監視し、約定データを保存(最初は成行売買で)
- ロギング & データ保存
- 全ティック + 特徴量 + アクション + 結果をExcel 形式で保存
- 学習 PC に転送可能
- ティック取得
環境クラスの自作
強化学習の威力を実感したいけれど、取引は固定した建玉でやりくりして欲しい、つまりナンピンを禁止することが現在の絶対条件です。さもないと、とんでもない取引になりそうです。
しかし、詳細に記載したプロンプトを用意しても、生成 AI が提案してくれるコードは毎回微妙に違うので、その確認に時間を取られます。そして、こちらの意図がうまく伝わっていないことが判ると、次第にやり場のない怒りが蓄積してしまって、そのストレスに耐えられなくなります。😅
生成 AI(GPT-5 だけでなく、Gemini, Copilot, Perplexity などと利用できる生成 AI を試しまくっています)に似たようなコードを山ほど提案してもらったので、そろそろ、想定する通りに動く環境クラスを自分でコーディングする段階ではないか…、そう思って週末は基本的な取引用環境クラスの作成に取り組みました。
動作確認できた、ナンピンしない環境クラスです。リアルタイムで取得するデータは、Time(タイムスタンプ:秒)、Price(株価:円)、Volume(累計出来高:株数)の 3 種類です。
環境クラス TradingEnv に加えて、自分が想定しているようにナンピンをしない売買ができるように TransactionManager クラスを別に用意しました (trading_view_20250907.py)。ここでモデルの報酬設計もしています。また、モデルがナンピンしようとした場合にはペナルティを与えるようにしています。
スモークテスト
売買アクションに対して意図したどおりの動作をするかを確認するために下記のようなプログラムを用意しました。
以下が実行例です。
Time Price Volume 0 0 1097.0 47600 1 1 1106.0 66400 2 2 1109.0 112800 3 3 1111.0 139900 4 4 1126.0 158900 5 5 1132.0 203500 6 6 1129.0 221000 7 7 1139.0 265600 8 8 1152.0 270700 9 9 1153.0 307100 10 10 1164.0 312600 11 11 1171.0 337000 12 12 1173.0 369000 13 13 1190.0 382100 14 14 1196.0 430600 15 15 1196.0 461300 16 16 1205.0 474800 📈 初期観測: [1.097e+03 0.000e+00 1.000e+00 0.000e+00 0.000e+00] 🕒 Step 00: Obs=[1097.0, 0.00, 1, 0, 0], Action=HOLD, Reward=0.00, Done=False 🕒 Step 01: Obs=[1106.0, 9.84, 0, 1, 0], Action=BUY, Reward=0.00, Done=False 🕒 Step 02: Obs=[1109.0, 10.75, 0, 1, 0], Action=HOLD, Reward=0.03, Done=False 🕒 Step 03: Obs=[1111.0, 10.21, 0, 1, 0], Action=HOLD, Reward=0.05, Done=False 🕒 Step 04: Obs=[1126.0, 9.85, 0, 1, 0], Action=BUY, Reward=-1.00, Done=False 🕒 Step 05: Obs=[1132.0, 10.71, 0, 1, 0], Action=SELL, Reward=-1.00, Done=False 🕒 Step 06: Obs=[1129.0, 9.77, 0, 1, 0], Action=BUY, Reward=-1.00, Done=False 🕒 Step 07: Obs=[1139.0, 10.71, 0, 1, 0], Action=HOLD, Reward=0.33, Done=False 🕒 Step 08: Obs=[1152.0, 8.54, 1, 0, 0], Action=REPAY, Reward=46.00, Done=False 🕒 Step 09: Obs=[1153.0, 10.50, 0, 0, 1], Action=SELL, Reward=0.00, Done=False 🕒 Step 10: Obs=[1164.0, 8.61, 0, 0, 1], Action=HOLD, Reward=-0.11, Done=False 🕒 Step 11: Obs=[1171.0, 10.10, 0, 0, 1], Action=SELL, Reward=-1.00, Done=False 🕒 Step 12: Obs=[1173.0, 10.37, 0, 0, 1], Action=HOLD, Reward=-0.20, Done=False 🕒 Step 13: Obs=[1190.0, 9.48, 0, 0, 1], Action=BUY, Reward=-1.00, Done=False 🕒 Step 14: Obs=[1196.0, 10.79, 0, 0, 1], Action=SELL, Reward=-1.00, Done=False 🕒 Step 15: Obs=[1196.0, 10.33, 0, 0, 1], Action=HOLD, Reward=-0.43, Done=False 🕒 Step 16: Obs=[1205.0, 9.51, 1, 0, 0], Action=REPAY, Reward=-52.00, Done=True プロセスは終了コード 0 で終了しました
モデルに対する報酬の大きさが妥当かどうかはともかくとして、売買アクションに対して想定通りの動作になっていることを確認できました。
なお、最初は建玉のポジション (PositionType) を整数(スカラー)にして obs(観測ベクトル)へ追加していたのですが、環境クラス TradingEnv および関連コードを Copilot と共有したところ、下記の提案をもらったので採用してみることにしました。
現在は 0, 1, 2 の整数ですが、学習の安定性を考慮して
pos_onehot = np.eye(3)[self.transman.position.value].astype(np.float32)のようにしても良いかもしれません。
PositionType | .value | One-hot ベクトル |
---|---|---|
NONE | 0 | [1.0, 0.0, 0.0] |
LONG | 1 | [0.0, 1.0, 0.0] |
SHORT | 2 | [0.0, 0.0, 1.0] |
このベクトルは、エージェントにとって「現在のポジションが何か」を明示的に伝える手段になります。整数値 0, 1, 2 よりも、one-hot の方が学習において「順序性のないカテゴリ」として扱いやすく、誤解が生じにくいです。
生成 AI は自分が考えてもみなかった改善提案をいろいろ出してくれるのですが、納得できる良さげなアイデアは採用するようにしています。
この環境クラスには、さらにテクニカル指標をいくつか特徴量として加えた方が良いのですが、ひとまず、簡単な PPO エージェントを用意して、学習が進むかどうかの確認を優先させようと考えています。
いままでたくさんの PPO エージェントで試してきましたが、ナンピンルールのペナルティが厳しすぎるのか、なかなかモデルの学習が進みませんでした。少しでもモデルの学習が進むようなパラメータを探索する方が優先度が高いと思うのです。
課 題
現在、課題と考えていることを下記にまとめました[随時更新〗。
- マーケットスピード II RSS による売買
- Excel VBA, Python 側で実際の売買を試す。
- 売買のためのサンプルワーク
- PyTorch を利用した強化学習モデルの実用化
- 環境クラス(gymnasium 準拠)の作成 ✓
参考サイト
- マーケットスピード II RSS | 楽天証券のトレーディングツール
- マーケットスピード II RSS 関数マニュアル
- 注文 | マーケットスピード II RSS オンラインヘルプ | 楽天証券のトレーディングツール
- PythonでGUIを設計 | Qtの公式Pythonバインディング
- PyQtGraph - Scientific Graphics and GUI Library for Python
- Python in Excel alternative: Open. Self-hosted. No limits.
- Book - xlwings Documentation


0 件のコメント:
コメントを投稿