ランダムウォークへの挑戦⑬ | 零号機に「相場の記憶」を与える(2026/8/2)

ランダムウォーク 未分類

はじめに

前回は、零号機の取引履歴をPythonで扱えるようにし、分析基盤を整えました。

しかし、それだけでは「勝った」「負けた」という結果しか分かりません。

人間のトレーダーなら、

「あの時はボラティリティが高かった」

「レンジ相場だった」

「ロンドン市場だった」

というように、その時の相場環境も一緒に覚えています。

今回は零号機にもその記憶を与えてみようと思います。

零号機に「記憶」を与える

そこで今回は、零号機が取引するたびに、分析用のCSVを保存するように変更します。

まず記録する内容は、

項目内容
注文番号取引識別
売買方向BUY / SELL
エントリー時間分析用
決済時間分析用
エントリー価格分析用
決済価格分析用
損益分析用
保有時間分析用

ここでは、あえてATRやADXなどのテクニカル指標は保存しません。

これらはPython側で後から自由に追加できるからです。零号機には事実だけを記録させます。

システム構成

Chapter2では、次の流れで分析を進めます。

MT4(EA)
↓
trade_log.csv(これから作成)
↓
Python
↓
trade_base.csv(これから作成)
↓
相場データと結合
↓
market_master.csv
↓
Python分析
↓
EA改善

Chapter1では、MT4のバックテスト結果だけを分析していましたが、Chapter2では分析専用のデータベースを構築します。

零号機を改修する

今回の目的は、零号機が取引履歴をCSVへ保存できるようにすることです。

1.グローバル変数を追加する

Buy_Exit_Signal などが定義されている付近に、次を追加します。

//+------------------------------------------------------------------+
//| EXIT時の状態を記録するフラグ
//+------------------------------------------------------------------+

int Buy_Exit_Band_Flag = 0;
int Buy_Exit_Reverse_Flag = 0;

int Sell_Exit_Band_Flag = 0;
int Sell_Exit_Reverse_Flag = 0;

これは「決済理由」という名前ではなく、決済時にどの条件が成立していたかを保存するための変数です。

2.CSVへ保存する関数を追加する

Order_Close_Indicater() より前に、次の関数を追加します。

追加したPythonコードを見る(クリックで開く)
//+------------------------------------------------------------------+
//| 決済済み取引をCSVへ保存する
//+------------------------------------------------------------------+

void Write_Trade_Log(
   int ticket,
   int band_flag,
   int reverse_flag
)
{
   // 決済済み注文をヒストリーから選択
   if(OrderSelect(ticket, SELECT_BY_TICKET, MODE_HISTORY) == false)
   {
      Print(
         "決済済み注文を選択できませんでした。ticket=",
         ticket,
         " error=",
         GetLastError()
      );

      return;
   }

   // CSVを開く
   int file_handle = FileOpen(
      "trade_log.csv",
      FILE_CSV |
      FILE_READ |
      FILE_WRITE |
      FILE_ANSI,
      ','
   );

   if(file_handle == INVALID_HANDLE)
   {
      Print(
         "trade_log.csvを開けませんでした。error=",
         GetLastError()
      );

      return;
   }

   // ファイルが空なら見出しを作成
   if(FileSize(file_handle) == 0)
   {
      FileWrite(
         file_handle,
         "ticket",
         "side",
         "entry_time",
         "exit_time",
         "entry_price",
         "exit_price",
         "lots",
         "profit",
         "holding_minutes",
         "band_condition",
         "reverse_condition"
      );
   }

   // ファイル末尾へ移動
   FileSeek(
      file_handle,
      0,
      SEEK_END
   );

   // BUY・SELLを文字列に変換
   string side = "UNKNOWN";

   if(OrderType() == OP_BUY)
   {
      side = "BUY";
   }
   else if(OrderType() == OP_SELL)
   {
      side = "SELL";
   }

   // 手数料・スワップを含む損益
   double total_profit =
      OrderProfit()
      + OrderSwap()
      + OrderCommission();

   // 保有時間を分単位で計算
   double holding_minutes =
      (OrderCloseTime() - OrderOpenTime()) / 60.0;

   // CSVへ1行追加
   FileWrite(
      file_handle,
      OrderTicket(),
      side,

      TimeToString(
         OrderOpenTime(),
         TIME_DATE | TIME_MINUTES
      ),

      TimeToString(
         OrderCloseTime(),
         TIME_DATE | TIME_MINUTES
      ),

      DoubleToString(
         OrderOpenPrice(),
         Digits
      ),

      DoubleToString(
         OrderClosePrice(),
         Digits
      ),

      DoubleToString(
         OrderLots(),
         2
      ),

      DoubleToString(
         total_profit,
         2
      ),

      DoubleToString(
         holding_minutes,
         1
      ),

      band_flag,
      reverse_flag
   );

   FileClose(file_handle);

   Print(
      "取引ログを保存しました。ticket=",
      ticket
   );
}

見出しを英語にしているのは、MQL4から出力したCSVをPythonで読み込む際の文字化けを避けるためです。

Python側で後から日本語名に変更できます。

保存先は

trade_log.csv

です。

今後は、このCSVをPythonで読み込みます。

Python側の準備

続いてPython側です。まずはCSVを読み込み、分析しやすい形式へ変換します。

今回は分析は行いません。分析できる状態を作ることが目的です。

追加したPythonコードを見る(クリックで開く)
# ==========================================
# Chapter2
# trade_log.csv を分析用へ変換
# ==========================================

import os
import pandas as pd

os.makedirs("results", exist_ok=True)

df = pd.read_csv(
    "trade_log.csv",
    encoding="utf-8-sig"
)

print(df.head())

print(df.info())

# 日時型へ変換
date_columns = [
    "エントリー時間",
    "決済時間"
]

for col in date_columns:

    df[col] = pd.to_datetime(
        df[col],
        errors="coerce"
    )

# 数値型へ変換
numeric_columns = [
    "エントリー価格",
    "決済価格",
    "損益",
    "保有時間"
]

for col in numeric_columns:

    df[col] = pd.to_numeric(
        df[col],
        errors="coerce"
    )

print(df.describe())

df.to_csv(
    "results/trade_base.csv",
    index=False,
    encoding="utf-8-sig"
)

今回完成したもの

今回で分析基盤が完成しました。
Pythonがいつでも取引履歴を読み込み、分析できるようになりました。

次回は、今回作成した取引履歴に、EUR/USDの価格データを結合します。

ATRやボリンジャーバンド、曜日、時間帯など、「エントリーした瞬間の相場環境」を取引履歴へ追加し、零号機に「相場の記憶」を与えていきます。

関連記事

ランダムウォークへの挑戦⑬ | 零号機に「相場の記憶」を与える(2026/8/2)
ランダムウォークへの挑戦⑫ | Chapter2「学習」始動 ー零号機は何を学ぶべきなのかー(2026/8/2)
ランダムウォークへの挑戦⑪ | 零号機の性格診断──Chapter1「観測」 完結(2026/8/1)
ランダムウォークへの挑戦⑩ | 資産推移とドローダウンを分析する(2026/8/1)
ランダムウォークへの挑戦⑨ | 取引の連勝・連敗を分析する(2026/7/28)
ランダムウォークへの挑戦⑧ | 保有時間別の損益を分析する(2026/7/26)
ランダムウォークへの挑戦⑦ | 曜日別の損益を分析する(2026/7/23)
ランダムウォークへの挑戦⑥ | 時間帯別の損益を分析する(2026/7/22)
ランダムウォークへの挑戦⑤ | グラフ化(2026/7/5)
ランダムウォークへの挑戦④ |「零号機」の基本分析(2026/6/11)
ランダムウォークへの挑戦③ | 環境設定(2026/5/26)
ランダムウォークへの挑戦➁ | 小目標3つ設定(2026/5/25)
ランダムウォークへの挑戦① | はじめに(2026/5/25)

コメント

タイトルとURLをコピーしました