見出し画像

取引履歴分析の為のPythonの始め方とMT4用のEAの作り方

全くプログラミングを触った事がない、という裁量トレーダーは多いはず。取引履歴を分析したくてもどこから初めたら良いか分からないと思うので、今日は簡単に紹介をしたいと思う。

まずはChatGPTやCode Interpreterが得意とするPythonのインストール。それに関してはこちらが参考になるだろうか。
PythonのためのVisual Studio Codeのはじめ方 - ガンマソフト (gammasoft.jp)

PythonとVS Codeをインストールしたら、VS Codeを立ち上げよう。
そしてFile -> New FileからPython Fileを選択し、準備は完了する。

さてこれでコーディングを行う準備が出来た。
ChatGPTやCode Interpreterは優秀なので、ちゃんと何をして欲しいか明確に伝えれば簡単なタスクであればコーディングをしてくれる。
例として、デスクトップの"Trading"フォルダにあるトレード履歴 (csvファイル) を全て一つのcsvファイルとして統合するコードを書いてもらった。

こんな感じで具体的に必要な作業や条件を指定し、コーディングをしてもらう。そして”Copy code"をクリックして先程のVS Codeに戻って貼り付けてみよう。"C:\Users\Neko\Desktop\Trading"というのは私のPCのディレクトリなので、自分自身の環境やユーザーネームに合わせてディレクトリを変更するのを忘れずに。

貼り付けたら右上の再生ボタンをクリックし、このコード (.pyファイル) に名前を付けて保存されたら実行する。これでTradingフォルダに統合されたcsv結果が出力されたはずだ。

私はノンプログラマーなので難しいコーディングはまだ出来ないが、簡単なタスクであればChatGPTやCode Interpreterで出来る事が多い。Pythonは勿論の事、MT4の言語であるMQL、TradingViewの言語であるPineで取引アルゴリズムを作成してと頼んだらちゃんと作成してくれる。

//+------------------------------------------------------------------+
//|                                                      MA_Cross.mq4 |
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+ #property  copyright "2023, MetaQuotes Software Corp." #property  link      "https://www.mql5.com" #property  version   "1.00"

// Parameters
extern int    FastMA = 10; // Fast moving average period
extern int    SlowMA = 20; // Slow moving average period
extern double TakeProfit = 100.0; // Take profit in points
extern double StopLoss = 50.0; // Stop loss in points
extern string Currency = "EURUSD"; // Currency pair

// Global variables
double FastMAArray[];
double SlowMAArray[];

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
   // Initialize arrays
   ArrayResize(FastMAArray, FastMA + 1);
   ArrayResize(SlowMAArray, SlowMA + 1);

   return(0);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }

//+------------------------------------------------------------------+
//| Expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
   // Calculate moving averages
   iMA(Symbol(), 0, FastMA, 0, MODE_SMA, PRICE_CLOSE, FastMAArray);
   iMA(Symbol(), 0, SlowMA, 0, MODE_SMA, PRICE_CLOSE, SlowMAArray);

   double FastMA_current = FastMAArray[0];
   double SlowMA_current = SlowMAArray[0];
   double FastMA_previous = FastMAArray[1];
   double SlowMA_previous = SlowMAArray[1];

   // Check for MA crossover
   if (FastMA_current > SlowMA_current && FastMA_previous < SlowMA_previous) {
      // Fast MA crossed above Slow MA - Buy
      OrderSend(Symbol(), OP_BUY, 1.0, Ask, 3, Ask - StopLoss * Point, Ask + TakeProfit * Point);
   } else if (FastMA_current < SlowMA_current && FastMA_previous > SlowMA_previous) {
      // Fast MA crossed below Slow MA - Sell
      OrderSend(Symbol(), OP_SELL, 1.0, Bid, 3, Bid + StopLoss * Point, Bid - TakeProfit * Point);
   }

   return(0);
  }
//+------------------------------------------------------------------+

更に洗練したい場合、どんどん追加で頼んでみよう。ちゃんと何をしたいか明確に伝えるのが大事になる。

//+------------------------------------------------------------------+
//|                                                      MA_Cross.mq4 |
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+ #property  copyright "2023, MetaQuotes Software Corp." #property  link      "https://www.mql5.com" #property  version   "1.00"

// Parameters
extern int    FastMA = 10; // Fast moving average period
extern int    SlowMA = 20; // Slow moving average period
extern int    LongTermFastMA = 50; // Long-term fast moving average period
extern int    LongTermSlowMA = 100; // Long-term slow moving average period
extern double RiskPerTrade = 0.01; // Risk per trade as a proportion of account balance
extern double TrailingStop = 50.0; // Trailing stop in points
extern string Currency = "EURUSD"; // Currency pair
extern int    TradeHourStart = 9; // Start hour of trading period
extern int    TradeHourEnd = 18; // End hour of trading period

// Global variables
double FastMAArray[];
double SlowMAArray[];
double LongTermFastMAArray[];
double LongTermSlowMAArray[];

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
   // Initialize arrays
   ArrayResize(FastMAArray, FastMA + 1);
   ArrayResize(SlowMAArray, SlowMA + 1);
   ArrayResize(LongTermFastMAArray, LongTermFastMA + 1);
   ArrayResize(LongTermSlowMAArray, LongTermSlowMA + 1);

   return(0);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }

//+------------------------------------------------------------------+
//| Expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
   // Calculate moving averages
   iMA(Symbol(), 0, FastMA, 0, MODE_SMA, PRICE_CLOSE, FastMAArray);
   iMA(Symbol(), 0, SlowMA, 0, MODE_SMA, PRICE_CLOSE, SlowMAArray);
   iMA(Symbol(), 0, LongTermFastMA, 0, MODE_SMA, PRICE_CLOSE, LongTermFastMAArray);
   iMA(Symbol(), 0, LongTermSlowMA, 0, MODE_SMA, PRICE_CLOSE, LongTermSlowMAArray);

   double FastMA_current = FastMAArray[0];
   double SlowMA_current = SlowMAArray[0];
   double FastMA_previous = FastMAArray[1];
   double SlowMA_previous = SlowMAArray[1];

   double LongTermFastMA_current = LongTermFastMAArray[0];
   double LongTermSlowMA_current = LongTermSlowMAArray[0];

   // Check current time
   datetime current_time = TimeCurrent();
   int current_hour = TimeHour(current_time);

   // Check if within trading hours
   if (current_hour >= TradeHourStart && current_hour <= TradeHourEnd) {
     // Calculate position size based on risk
     double lotSize = RiskPerTrade * AccountBalance() / (StopLoss * Point * MarketInfo(Symbol(), MODE_TICKVALUE));

     // Check for MA crossover
     if (FastMA_current > SlowMA_current && FastMA_previous < SlowMA_previous && LongTermFastMA_current > LongTermSlowMA_current) {
        // Fast MA crossed above Slow MA and long-term trend is up - Buy
        int ticket = OrderSend(Symbol(), OP_BUY, lotSize, Ask, 3, Ask - StopLoss * Point, Ask + TakeProfit * Point);

        if (ticket > 0) {
          // Set trailing stop
          OrderSelect(ticket, SELECT_BY_TICKET);
          OrderModify(ticket, OrderOpenPrice(), Bid - TrailingStop * Point, OrderTakeProfit(), 0);
        }
     } else if (FastMA_current < SlowMA_current && FastMA_previous > SlowMA_previous && LongTermFastMA_current < LongTermSlowMA_current) {
        // Fast MA crossed below Slow MA and long-term trend is down - Sell
        int ticket = OrderSend(Symbol(), OP_SELL, lotSize, Bid, 3, Bid + StopLoss * Point, Bid - TakeProfit * Point);

        if (ticket > 0) {
          // Set trailing stop
          OrderSelect(ticket, SELECT_BY_TICKET);
          OrderModify(ticket, OrderOpenPrice(), Ask + TrailingStop * Point, OrderTakeProfit(), 0);
        }
     }
   }

   return(0);
  }
//+------------------------------------------------------------------+

さて作成したらMT4からMetaEditorを開き、Compilesしてみよう。きっとエラーが出るはずだ。(それくらいエラーは当たり前で都度修正してもらう事が必要になる。)

MetaEditor
やはりエラーが出たのでエラーの詳細をコピペしてもう一度修正してもらう
まだエラーが出るのでもう一度
まだエラーが出たので、出なくなるまで修正を続ける
//+------------------------------------------------------------------+
//|                                                      MA_Cross.mq4 |
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+ #property  copyright "2023, MetaQuotes Software Corp." #property  link      "https://www.mql5.com" #property  version   "1.00"

// Parameters
extern int    FastMA = 10; // Fast moving average period
extern int    SlowMA = 20; // Slow moving average period
extern int    LongTermFastMA = 50; // Long-term fast moving average period
extern int    LongTermSlowMA = 100; // Long-term slow moving average period
extern double StopLoss = 50.0; // Stop loss in points
extern double TakeProfit = 100.0; // Take profit in points
extern double RiskPerTrade = 0.01; // Risk per trade as a proportion of account balance
extern double TrailingStop = 50.0; // Trailing stop in points
extern string Currency = "EURUSD"; // Currency pair
extern int    TradeHourStart = 9; // Start hour of trading period
extern int    TradeHourEnd = 18; // End hour of trading period

// Global variables
double FastMAArray[];
double SlowMAArray[];
double LongTermFastMAArray[];
double LongTermSlowMAArray[];

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
   // Initialize arrays
   ArrayResize(FastMAArray, Bars);
   ArrayResize(SlowMAArray, Bars);
   ArrayResize(LongTermFastMAArray, Bars);
   ArrayResize(LongTermSlowMAArray, Bars);

   return(0);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }

//+------------------------------------------------------------------+
//| Expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
   // Calculate moving averages
   iMAOnArray(FastMAArray, Bars, FastMA, 0, MODE_SMA, 0);
   iMAOnArray(SlowMAArray, Bars, SlowMA, 0, MODE_SMA, 0);
   iMAOnArray(LongTermFastMAArray, Bars, LongTermFastMA, 0, MODE_SMA, 0);
   iMAOnArray(LongTermSlowMAArray, Bars, LongTermSlowMA, 0, MODE_SMA, 0);

   double FastMA_current = FastMAArray[FastMA - 1];
   double SlowMA_current = SlowMAArray[SlowMA - 1];
   double FastMA_previous = FastMAArray[FastMA - 2];
   double SlowMA_previous = SlowMAArray[SlowMA - 2];

   double LongTermFastMA_current = LongTermFastMAArray[LongTermFastMA - 1];
   double LongTermSlowMA_current = LongTermSlowMAArray[LongTermSlowMA - 1];

   // Check current time
   datetime current_time = TimeCurrent();
   int current_hour = TimeHour(current_time);

   // Check if within trading hours
   if (current_hour >= TradeHourStart && current_hour <= TradeHourEnd) {
     // Calculate position size based on risk
     double lotSize = RiskPerTrade * AccountBalance() / (StopLoss * Point * MarketInfo(Symbol(), MODE_TICKVALUE));

     // Check for MA crossover
     if (FastMA_current > SlowMA_current && FastMA_previous < SlowMA_previous && LongTermFastMA_current > LongTermSlowMA_current) {
        // Fast MA crossed above Slow MA and long-term trend is up - Buy
        int ticketBuy = OrderSend(Symbol(), OP_BUY, lotSize, Ask, 3, Ask - StopLoss * Point, Ask + TakeProfit * Point);
        if (ticketBuy > 0) {
          if(OrderSelect(ticketBuy, SELECT_BY_TICKET, MODE_TRADES)) {
            // Set trailing stop
            bool resBuy = OrderModify(OrderTicket(), OrderOpenPrice(), Bid - TrailingStop * Point, OrderTakeProfit(), 0, CLR_NONE);
            if (!resBuy) {
              Print("OrderModify failed, error ", GetLastError());
            }
          }
        }
     } else if (FastMA_current < SlowMA_current && FastMA_previous > SlowMA_previous && LongTermFastMA_current < LongTermSlowMA_current) {
        // Fast MA crossed below Slow MA and long-term trend is down - Sell
        int ticketSell = OrderSend(Symbol(), OP_SELL, lotSize, Bid, 3, Bid + StopLoss * Point, Bid - TakeProfit * Point);
        if (ticketSell > 0) {
          if(OrderSelect(ticketSell, SELECT_BY_TICKET, MODE_TRADES)) {
            // Set trailing stop
            bool resSell = OrderModify(OrderTicket(), OrderOpenPrice(), Ask + TrailingStop * Point, OrderTakeProfit(), 0, CLR_NONE);
            if (!resSell) {
              Print("OrderModify failed, error ", GetLastError());
            }
          }
        }
     }
   }

   return(0);
  }
//+------------------------------------------------------------------+

やっとエラーがなくなり実行する事が出来た。しかしバックテストをしてもトレードの履歴が確認出来なかったので、どこか修正が必要な箇所があるのかも知れない。このコードはあくまでもサンプルなので、こんな条件で自動売買したら良いのでは、というアイディアがある方はぜひ試してみて欲しい。

このようにシンプルなコードであれば簡単に作ってもらえるし、修正してもらう事も出来る。これを機に一度試してみるのはいかがだろうか。(黒猫アイランド)


【コミックマーケットで販売する新刊について】
8/13のコミックマーケットで久々に新刊を出します。トレーダー目線のなかなかマニアックな本に仕上げました。今後も定期的に内容をチラ見せしていきたいと思います。

この記事が気に入ったらサポートをしてみませんか?