![見出し画像](https://assets.st-note.com/production/uploads/images/113387717/rectangle_large_type_2_ea39dd5c9002dff2088a420890da9adb.png?width=1200)
Photo by
tzalam
EAの成績を確認するインジケーター ソースコード付き
![](https://assets.st-note.com/img/1692056564725-9aLDD5qyZt.png?width=1200)
EAの成績を一覧で表示するインジケーターです。
依頼品のEAの成績確認するインジケーター作りました。
— ホソノP (@hosono_p) August 6, 2023
ソースコード配布します。
ダウンロードリンクhttps://t.co/j9UAazSbI1 pic.twitter.com/8OoRjV1liR
ダウンロードリンク
indicatorのフォルダにいれて使ってください。
ソースコード
//+------------------------------------------------------------------+
//| EAの成績一覧表インジケーター.mq4 |
//| Copyright 2023, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#property indicator_chart_window
#include <WinUser32.mqh>
#import "user32.dll"
int GetAncestor(int,int);
int PostMessageA(int, int, int, int);
#import
input datetime StartDate = D'2000.01.01 00:00'; // ユーザーが開始日を入力できるようにします
input datetime EndDate = D'2038.01.18 23:59'; // ユーザーが終了日を入力できるようにします
struct TradeHistory {
int magicNumber;
string comment;
int tradeCount;
int winCount;
int lossCount;
double winRate;
double totalLossAmount;
double totalWinAmount;
double totalProfitLoss;
double profitFactor;
double totalPoints;
};
int magicNumbers[]; // マジックナンバーを保存するグローバル配列
TradeHistory tradeHistories[]; // TradeHistory構造体の配列をグローバルスコープに配置
//+------------------------------------------------------------------+
//| Custom function for extracting magic numbers |
//+------------------------------------------------------------------+
void ExtractMagicNumbers() {
int totalOrders = OrdersHistoryTotal(); // 過去の注文の合計数を取得
for(int i = 0; i < totalOrders; i++) {
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { // 注文を選択
datetime orderOpenTime = OrderOpenTime();
// 注文の開始時間が指定された期間内にあるかどうかを確認
if(orderOpenTime >= StartDate && orderOpenTime <= EndDate) {
int magicNumber = OrderMagicNumber(); // マジックナンバーを取得
// 既に同じマジックナンバーが配列に存在するかどうかを確認
bool isDuplicate = false;
for(int j = 0; j < ArraySize(magicNumbers); j++) {
if(magicNumbers[j] == magicNumber) {
isDuplicate = true;
break;
}
}
// マジックナンバーが配列にまだ存在しない場合のみ、配列に追加
if(!isDuplicate) {
ArrayResize(magicNumbers, ArraySize(magicNumbers) + 1); // 配列のサイズを増やす
magicNumbers[ArraySize(magicNumbers) - 1] = magicNumber; // マジックナンバーを配列に追加
}
}
}
}
}
void CalculateTradeHistory() {
ArrayResize(tradeHistories, ArraySize(magicNumbers)); // 配列のサイズをマジックナンバーの数に合わせて調整
for(int i = 0; i < ArraySize(magicNumbers); i++) {
tradeHistories[i].magicNumber = magicNumbers[i]; // マジックナンバーを設定
for(int j = OrdersHistoryTotal() - 1; j >= 0; j--) {
if(OrderSelect(j, SELECT_BY_POS, MODE_HISTORY)) {
datetime orderOpenTime = OrderOpenTime();
// 注文の開始時間が指定された期間内にあるかどうかを確認
if(orderOpenTime >= StartDate && orderOpenTime <= EndDate) {
if(OrderType() < 2){
if(OrderMagicNumber() == magicNumbers[i]) {
tradeHistories[i].comment = OrderComment();
tradeHistories[i].tradeCount++;
if(OrderProfit() > 0) {
tradeHistories[i].winCount++;
tradeHistories[i].totalWinAmount += OrderProfit();
} else {
tradeHistories[i].lossCount++;
tradeHistories[i].totalLossAmount += OrderProfit();
}
tradeHistories[i].totalPoints += OrderProfit();
}
}
}
}
}
// 勝率、トータル損益、プロフィットファクターを計算
if(tradeHistories[i].tradeCount > 0) {
tradeHistories[i].winRate = (double)tradeHistories[i].winCount / tradeHistories[i].tradeCount;
tradeHistories[i].totalProfitLoss = tradeHistories[i].totalWinAmount + tradeHistories[i].totalLossAmount;
if(tradeHistories[i].totalLossAmount != 0) {
tradeHistories[i].profitFactor = -tradeHistories[i].totalWinAmount / tradeHistories[i].totalLossAmount;
}
}
}
}
input int input_comment_width = 500;//コメントの幅の設定
input int input_sonota_width = 250;//その他の幅の設定
void CreateObject(string name, string text, int magic_number_list_index, int koumoku_index) {
ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, name, OBJPROP_XDISTANCE,input_sonota_width * koumoku_index);
if(koumoku_index!=0){
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, input_comment_width + input_sonota_width * koumoku_index);
}
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, 30 + magic_number_list_index * 25);
ObjectSetText(name, text, 12, "MS Gothic", clrWhite);
}
void DisplayTradeHistory() {
for(int i = 0; i < ArraySize(tradeHistories); i++) {
// コメント
string nameComment = "TradeHistoryComment" + IntegerToString(i);
CreateObject(nameComment, "Comment: " + tradeHistories[i].comment, i, 0);
// マジックナンバー
string nameMagicNumber = "TradeHistoryMagicNumber" + IntegerToString(i);
CreateObject(nameMagicNumber, "Magic Number: " + IntegerToString(tradeHistories[i].magicNumber), i, 1);
// トレード回数
string nameTradeCount = "TradeHistoryTradeCount" + IntegerToString(i);
CreateObject(nameTradeCount, "Trade Count: " + IntegerToString(tradeHistories[i].tradeCount), i, 2);
// 勝率
string nameWinRate = "TradeHistoryWinRate" + IntegerToString(i);
CreateObject(nameWinRate, "Win Rate: " + DoubleToString(tradeHistories[i].winRate, 2), i, 3);
// 損益額
string nameProfitLoss = "TradeHistoryProfitLoss" + IntegerToString(i);
CreateObject(nameProfitLoss, "損益額: " + DoubleToString(tradeHistories[i].totalProfitLoss, 2), i, 4);
// プロフィットファクター
string nameProfitFactor = "TradeHistoryProfitFactor" + IntegerToString(i);
CreateObject(nameProfitFactor, "Profit Factor: " + DoubleToString(tradeHistories[i].profitFactor, 2), i, 5);
}
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
input bool input_enable_zenrireki = true;//全履歴にする
input int taiki_jikan = 1;//表示までの待機秒
void OnInit()
{
if(input_enable_zenrireki){
if(!IsDllsAllowed()) {
Comment("全履歴の切り替えはDLLを許可してください。");
}else{
int main = GetAncestor(WindowHandle(Symbol(),Period()),2);
PostMessageA(main,WM_COMMAND,33058,0);
}
}
EventSetTimer(taiki_jikan);
}
void OnTimer(){
ExtractMagicNumbers(); // マジックナンバーの抽出関数を呼び出す
CalculateTradeHistory(); // 取引履歴の計算関数を呼び出す
DisplayTradeHistory(); // 取引履歴の表示関数を呼び出す
EventKillTimer();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//---
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
MagicNumberを主キーで表示したい場合
![](https://assets.st-note.com/img/1693449838400-0sKgQU2Dz5.png?width=1200)
//+------------------------------------------------------------------+
//| EAの成績一覧表インジケーター.mq4 |
//| Copyright 2023, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#property indicator_chart_window
#include <WinUser32.mqh>
#import "user32.dll"
int GetAncestor(int,int);
int PostMessageA(int, int, int, int);
#import
input datetime StartDate = D'2000.01.01 00:00'; // ユーザーが開始日を入力できるようにします
input datetime EndDate = D'2038.01.18 23:59'; // ユーザーが終了日を入力できるようにします
struct TradeHistory {
int magicNumber;
string comment;
int tradeCount;
int winCount;
int lossCount;
double winRate;
double totalLossAmount;
double totalWinAmount;
double totalProfitLoss;
double profitFactor;
double totalPoints;
};
int magicNumbers[]; // マジックナンバーを保存するグローバル配列
TradeHistory tradeHistories[]; // TradeHistory構造体の配列をグローバルスコープに配置
//+------------------------------------------------------------------+
//| Custom function for extracting magic numbers |
//+------------------------------------------------------------------+
void ExtractMagicNumbers() {
int totalOrders = OrdersHistoryTotal(); // 過去の注文の合計数を取得
for(int i = 0; i < totalOrders; i++) {
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { // 注文を選択
datetime orderOpenTime = OrderOpenTime();
// 注文の開始時間が指定された期間内にあるかどうかを確認
if(orderOpenTime >= StartDate && orderOpenTime <= EndDate) {
int magicNumber = OrderMagicNumber(); // マジックナンバーを取得
// 既に同じマジックナンバーが配列に存在するかどうかを確認
bool isDuplicate = false;
for(int j = 0; j < ArraySize(magicNumbers); j++) {
if(magicNumbers[j] == magicNumber) {
isDuplicate = true;
break;
}
}
// マジックナンバーが配列にまだ存在しない場合のみ、配列に追加
if(!isDuplicate) {
ArrayResize(magicNumbers, ArraySize(magicNumbers) + 1); // 配列のサイズを増やす
magicNumbers[ArraySize(magicNumbers) - 1] = magicNumber; // マジックナンバーを配列に追加
}
}
}
}
}
void CalculateTradeHistory() {
ArrayResize(tradeHistories, ArraySize(magicNumbers)); // 配列のサイズをマジックナンバーの数に合わせて調整
for(int i = 0; i < ArraySize(magicNumbers); i++) {
tradeHistories[i].magicNumber = magicNumbers[i]; // マジックナンバーを設定
for(int j = OrdersHistoryTotal() - 1; j >= 0; j--) {
if(OrderSelect(j, SELECT_BY_POS, MODE_HISTORY)) {
datetime orderOpenTime = OrderOpenTime();
// 注文の開始時間が指定された期間内にあるかどうかを確認
if(orderOpenTime >= StartDate && orderOpenTime <= EndDate) {
if(OrderType() < 2){
if(OrderMagicNumber() == magicNumbers[i]) {
tradeHistories[i].comment = OrderComment();
tradeHistories[i].tradeCount++;
if(OrderProfit() > 0) {
tradeHistories[i].winCount++;
tradeHistories[i].totalWinAmount += OrderProfit();
} else {
tradeHistories[i].lossCount++;
tradeHistories[i].totalLossAmount += OrderProfit();
}
tradeHistories[i].totalPoints += OrderProfit();
}
}
}
}
}
// 勝率、トータル損益、プロフィットファクターを計算
if(tradeHistories[i].tradeCount > 0) {
tradeHistories[i].winRate = (double)tradeHistories[i].winCount / tradeHistories[i].tradeCount;
tradeHistories[i].totalProfitLoss = tradeHistories[i].totalWinAmount + tradeHistories[i].totalLossAmount;
if(tradeHistories[i].totalLossAmount != 0) {
tradeHistories[i].profitFactor = -tradeHistories[i].totalWinAmount / tradeHistories[i].totalLossAmount;
}
}
}
}
input int input_sonota_width = 250;//行幅の設定
void CreateObject(string name, string text, int magic_number_list_index, int koumoku_index) {
ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, name, OBJPROP_XDISTANCE,input_sonota_width * koumoku_index);
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, 30 + magic_number_list_index * 25);
ObjectSetText(name, text, 12, "MS Gothic", clrWhite);
}
void DisplayTradeHistory() {
for(int i = 0; i < ArraySize(tradeHistories); i++) {
// マジックナンバー
string nameMagicNumber = "TradeHistoryMagicNumber" + IntegerToString(i);
CreateObject(nameMagicNumber, "Magic Number: " + IntegerToString(tradeHistories[i].magicNumber), i, 0);
// トレード回数
string nameTradeCount = "TradeHistoryTradeCount" + IntegerToString(i);
CreateObject(nameTradeCount, "Trade Count: " + IntegerToString(tradeHistories[i].tradeCount), i, 1);
// 勝率
string nameWinRate = "TradeHistoryWinRate" + IntegerToString(i);
CreateObject(nameWinRate, "Win Rate: " + DoubleToString(tradeHistories[i].winRate, 2), i, 2);
// 損益額
string nameProfitLoss = "TradeHistoryProfitLoss" + IntegerToString(i);
CreateObject(nameProfitLoss, "損益額: " + DoubleToString(tradeHistories[i].totalProfitLoss, 2), i, 3);
// プロフィットファクター
string nameProfitFactor = "TradeHistoryProfitFactor" + IntegerToString(i);
CreateObject(nameProfitFactor, "Profit Factor: " + DoubleToString(tradeHistories[i].profitFactor, 2), i, 4);
// コメント
string nameComment = "TradeHistoryComment" + IntegerToString(i);
CreateObject(nameComment, "Comment: " + tradeHistories[i].comment, i, 5);
}
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
input bool input_enable_zenrireki = true;//全履歴にする
input int taiki_jikan = 1;//表示までの待機秒
void OnInit()
{
if(input_enable_zenrireki){
if(!IsDllsAllowed()) {
Comment("全履歴の切り替えはDLLを許可してください。");
}else{
int main = GetAncestor(WindowHandle(Symbol(),Period()),2);
PostMessageA(main,WM_COMMAND,33058,0);
}
}
EventSetTimer(taiki_jikan);
}
void OnTimer(){
ExtractMagicNumbers(); // マジックナンバーの抽出関数を呼び出す
CalculateTradeHistory(); // 取引履歴の計算関数を呼び出す
DisplayTradeHistory(); // 取引履歴の表示関数を呼び出す
EventKillTimer();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//---
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
ここから先は
0字
![](https://assets.st-note.com/production/uploads/images/71149891/profile_b8c50857341c8c1f4490cb8d0c98a074.jpg?fit=bounds&format=jpeg&quality=85&width=330)
このマガジンで読み放題です。
FX自動売買開発入門サンプルコードセット
10,000円
EA開発者のためのサンプルコード集
この記事が気に入ったらサポートをしてみませんか?