
取引履歴分析の為の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してみよう。きっとエラーが出るはずだ。(それくらいエラーは当たり前で都度修正してもらう事が必要になる。)





//+------------------------------------------------------------------+
//| 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のコミックマーケットで久々に新刊を出します。トレーダー目線のなかなかマニアックな本に仕上げました。今後も定期的に内容をチラ見せしていきたいと思います。

