2025-12-31

自動売買への道 (2025-12-31)

楽天証券の口座でデイトレの自動売買に挑戦しようと Windows / Excel 上で利用できる マーケットスピード II RSS を活用して Python であれこれ取り組んでいます。この「自動売買への道」のトピックでは、プログラミングの話題にも踏み込んで、日々の活動をまとめています。

デイトレ用自作アプリ

以下は株価・取引に関連する情報の流れを示しています。

株価データ・取引の流れ(Windows 11)

楽天証券では、Python からネットワーク越しに直接取引できるような API が提供されていないので、マーケットスピード II RSS を介して取引をする構成を取っています。

移動平均差のクロスシグナル

年末年始にいろいろ試せるので、以前から評価をしたかったことを片付けます。まずは、移動平均のクロスシグナルで、短周期の移動平均 MA1 に一定以上の傾きがあればエントリできるという条件を評価してみました。

昨日収集したティックデータで試しました。下記のように Time 列のタイムスタンプを時刻形式に直してインデックスにした Pandas のデータフレーム df を利用します。

2025-12-30 のティックデータ (7011)

 

移動平均のクロスシグナルを求めて、短周期の移動平均 MA1 がクロス時に一定以上の傾きがあればエントリできるという条件を設定しました。

自作の MovingAverage クラスはコードの掲載を割愛してしまいましたが、周期を引数にして生成する引導平均のインスタンスで、株価を引数に update メソッドを実行すれば最新の移動平均が得られます。

以下、Jupyter Lab 上のコードをかいつまんで紹介します。

# 2つの移動平均
n_1 = 60
ma_1 = MovingAverage(window_size=n_1)
df["MA1"] = [ma_1.update(v) for v in df["Price"]]
n_2 = 900
ma_2 = MovingAverage(window_size=n_2)
df["MA2"] = [ma_2.update(v) for v in df["Price"]]
# 2つの MA の差分
df["DMA"] = df["MA1"] - df["MA2"]
# ============================
# 1. クロス検出(+1 / -1 / 0)
# ============================
golden = ((df["DMA"].shift(1) < 0) & (df["DMA"] > 0)).astype(int)
dead = ((df["DMA"].shift(1) > 0) & (df["DMA"] < 0)).astype(int) * -1
df["Cross"] = (golden + dead).astype("int8")  # 軽量で扱いやすい
# ============================
# 2. 傾き(diff → 軽い平滑化)
# ============================
df["Slope_MA1"] = df["MA1"].diff().rolling(5).mean()
# ============================
# 3. 傾きの強さフィルタ(MA1)
# ============================
threshold = 0.025
df["Strong_Slope"] = df["Slope_MA1"].abs() > threshold
# ============================
# 4. 最終エントリー条件
# ============================
df["Entry"] = (
    (df["Cross"] != 0)
    & df["Strong_Slope"]
)

Matplotlib でプロットしてみます。

fig = plt.figure(figsize=(6, 4))
n = 2
ax = dict()
gs = fig.add_gridspec(
    n, 1, wspace=0.0, hspace=0.0, height_ratios=[2 if i == 0 else 1 for i in range(n)]
)
for i, axis in enumerate(gs.subplots(sharex="col")):
    ax[i] = axis

ax[0].plot(df["Price"], linewidth=0.5, color="gray", alpha=0.5)
ax[0].plot(df["MA1"], linewidth=0.75)
ax[0].plot(df["MA2"], linewidth=0.75)
ax[0].set_ylabel("Price")
ax[0].xaxis.set_major_formatter(mdates.DateFormatter("%H:%M"))
ax[0].set_title(f"{excel}, {code}")
ax[0].grid(axis="y")

ax[1].plot(df["DMA"], linewidth=0.5)
ax[1].axhline(0, linewidth=0.25, color="black")
ax[1].set_ylabel("delta MA")

entry_times = df.index[df["Entry"]]
for t in entry_times:
    ax[0].axvline(t, color="red", linewidth=0.5, alpha=0.6)
    ax[1].axvline(t, color="red", linewidth=0.5, alpha=0.6)

plt.tight_layout()
plt.show()
2025-12-30, 7011 のティックデータと移動平均のプロット例

どのぐらい利益を上げられるか評価する必要がありますが、クロスシグナルでエントリ可能な箇所(縦の赤線)を見る限りまずまずです。移動平均の短周期と長周期の組み合わせの探索はやり直しになってしまいますが、収益改善の方向であれば手間を厭いません。良さそうであればリアルタイムで利用できるように実装し直して、来年の大発会までには間に合わせたいです。

他にも評価したい指標があるので、年末年始の休みの間に可能な限り確認したいと思います。

参考サイト

  1. マーケットスピード II RSS | 楽天証券のトレーディングツール
  2. マーケットスピード II RSS 関数マニュアル
  3. 注文 | マーケットスピード II RSS オンラインヘルプ | 楽天証券のトレーディングツール
  4. Gymnasium Documentation
  5. Stable-Baselines3 Docs - Reliable Reinforcement Learning Implementations
  6. Maskable PPO — Stable Baselines3 - documentation
  7. PyTorch documentation
  8. PythonでGUIを設計 | Qtの公式Pythonバインディング
  9. Python in Excel alternative: Open. Self-hosted. No limits.
  10. Book - xlwings Documentation
にほんブログ村 株ブログ 株日記へ
PVアクセスランキング にほんブログ村

0 件のコメント:

コメントを投稿