GroupOfHistory
Download scriptThis script is designed for MetaTrader users who need to organize and export their trading history into a structured, readable report. Instead of looking at a raw list of every individual trade, this tool allows you to group your past transactions based on specific categories and calculate key performance metrics for each group automatically.
Core Functionality
The primary purpose of the script is to scan your account's historical data and consolidate multiple trades into distinct groups. It then calculates several pieces of information for each group and saves the final summary into a CSV file, which can be opened in programs like Microsoft Excel or Google Sheets.
How the Grouping Works
You can choose one specific "identifier" to determine how your trades are grouped. The tool offers four different ways to categorize your history:
- Type: Groups trades by whether they were "Buy" or "Sell" orders.
- Symbol: Groups trades by the specific currency pair or asset (e.g., all EURUSD trades together).
- Magic Number: Groups trades based on their unique identification number (useful for distinguishing between different automated trading robots).
- Comment: Groups trades based on the text comments you entered when opening them. It is smart enough to ignore specific technical terms like "[sl]" or "[tp]" in your comments to keep the data clean.
Data Calculations & Reporting
For every group identified, the script performs a series of calculations to provide a comprehensive overview:
- Total Profit/Loss: Calculates the net result for the entire group (you can choose to see this in "Points" or "Actual Currency Value").
- Individual Profit and Loss: Breaks down the specific gains and losses separately.
- Maximum Drawdown & Current Floating: Tracks how much the account dipped at its lowest point relative to the group's profit and calculates the current "floating" difference.
- Trade Count: Counts exactly how many trades belong to that specific group.
- Timeframes: Records the date of the very first trade opened in the group and the date of the most recent trade closed.
Workflow Summary
- Scan: The script reads your entire account history.
- Filter: It ignores "pending" orders and only looks at completed Buy or Sell operations.
- Consolidate: It identifies all trades that match your chosen group (e.g., all "Buy" trades).
- Analyze: It calculates the totals, maximum dips, and dates for those specific trades.
- Export: It generates a clean CSV file containing a header row and a summary line for every group found, making it easy to analyze your trading strategy's performance at a glance.
//+----------------------------------------------------------------------------+
//| GroupOfHistory.mq4 |
//| Êèì Èãîðü Â. aka KimIV |
//| http://www.kimiv.ru |
//| 27.02.2006 Ãðóïïèðîâêà èñòîðèè ñ÷¸òà (Group of History). |
//| Ñêðèïò âûïîëíÿåò ÷òåíèå ñïèñêà ñäåëîê èç èñòîðèè ñ÷¸òà, ãðóïïèðóåò |
//| äàííûå ïî óêàçàííîìó â ïàðàìåòðàõ ïðèçíàêó è çàïèñûâàåò â ôàéë. |
//| 02.02.2006 Äîáàâèë ñòîëáåö ÌàêñÄÄ è ðàñøèðèë ïåðå÷åíü äîïóñòèìûõ |
//| çíà÷åíèé ïàðàìåòðà gohGroup: |
//| 1-òèï, 2-ñèìâîë, 3-ìàãèê, 4-êîììåíòàðèé |
//| 06.02.2006 Ïî ïðîñüáå alextur'à Äîáàâèë ñòîëáåö ÒåêÄÄ. |
//| 15.12.2006 Ïî ïðîñüáå Alfa äîáàâèë êîëîíêè ñ äàòîé ïåðâîãî îòêðûòîãî |
//| îðäåðà è äàòîé ïîñëåäíåãî çàêðûòîãî. |
//+----------------------------------------------------------------------------+
#property copyright "Êèì Èãîðü Â. aka KimIV"
#property link "http://www.kimiv.ru"
#property show_inputs
//------- Âíåøíèå ïàðàìåòðû ñêðèïòà --------------------------------------------
extern string gohOutFileName = "GroupOfHistory.csv";
extern int gohGroup = 3; // 1-òèï, 2-ñèìâîë, 3-ìàãèê, 4-êîììåíòàðèé
extern int gohProfit = 1; // 1-ïóíêòû, 2-âàëþòà îðäåðà
//+----------------------------------------------------------------------------+
//| script program start function |
//+----------------------------------------------------------------------------+
void start()
{
int i; // Ñ÷¸ò÷èê ñäåëîê
int n; // Èíäåêñ ýëåìåíòà ìàññèâà, íîìåð ñòðîêè
int ot; // Òèï îïåðàöèè
int ks[]; // Êîëè÷åñòâî ñäåëîê
string nm[]; // Íàèìåíîâàíèå ãðóïïû
double op[], ou[]; // Îáùèå ïðèáûëü è óáûòîê
double mb[]; // Ìàêñèìóì áàëàíñà
double dd[]; // Ïðîñàäêà, ÌàêñÄÄ
double td[]; // Òåêóùàÿ ïðîñàäêà
datetime od[]; // Äàòà ïåðâîãî îòêðûòîãî îðäåðà
datetime cd[]; // Äàòà ïîñëåäíåãî çàêðûòîãî
string st, text="";
FileDelete(gohOutFileName);
switch (gohGroup)
{
case 1: text = "Òèï";
break;
case 2: text = "Ñèìâîë";
break;
case 3: text = "Ìàãèê";
break;
case 4: text = "Êîììåíòàðèé";
break;
}
text = text + ";×èñò.ïðèá.;Îáù.ïðèá.;Îáù.óá.;ÌàêñÄÄ;ÒåêÄÄ;Ñäåëîê;Ïåðâàÿ;Ïîñëåäíÿÿ";
WritingLineInFile(gohOutFileName, text);
for(i = 0; i < HistoryTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
{
ot = OrderType();
if(ot == OP_BUY || ot == OP_SELL)
{
switch(gohGroup)
{
case 1: if(ot == OP_BUY)
st = "Buy";
else
st = "Sell";
break;
case 2: st = OrderSymbol();
break;
case 3: if(OrderMagicNumber() == 0)
st = "";
else
st = OrderMagicNumber();
break;
case 4: st = StrTran(OrderComment(), "[sl]", "");
st = StrTran(st, "[tp]", "");
break;
}
n = ArrayFind(nm, st);
if(n + 1 > ArraySize(op))
{
ArrayResize(op, n + 1);
ArrayResize(ou, n + 1);
ArrayResize(mb, n + 1);
ArrayResize(dd, n + 1);
ArrayResize(td, n + 1);
ArrayResize(ks, n + 1);
ArrayResize(od, n + 1);
ArrayResize(cd, n + 1);
}
if(OrderProfit() > 0)
{
if(gohProfit == 2)
op[n] += OrderProfit();
else
op[n] += MathAbs(OrderOpenPrice() - OrderClosePrice()) /
MarketInfo(OrderSymbol(), MODE_POINT);
}
else
{
if(gohProfit == 2)
ou[n] += OrderProfit();
else
ou[n] -= MathAbs(OrderOpenPrice() - OrderClosePrice()) /
MarketInfo(OrderSymbol(), MODE_POINT);
}
if(gohProfit == 2)
op[n] += OrderSwap();
if(mb[n] < op[n] + ou[n])
mb[n] = op[n] + ou[n];
td[n] = mb[n] - op[n] - ou[n];
if(dd[n] < td[n])
dd[n] = td[n];
if(od[n] == 0)
od[n] = OrderOpenTime();
if(cd[n] < OrderCloseTime())
cd[n] = OrderCloseTime();
ks[n]++;
}
}
}
for(i = 0; i < ArraySize(nm); i++)
{
text = nm[i] + ";" + StrTran(DoubleToStr(op[i] + ou[i], 2), ".", ",") + ";" +
StrTran(DoubleToStr(op[i], 2), ".", ",") + ";" +
StrTran(DoubleToStr(ou[i], 2), ".", ",") + ";" +
StrTran(DoubleToStr(dd[i], 2), ".", ",") + ";" +
StrTran(DoubleToStr(td[i], 2), ".", ",") + ";" +
StrTran(DoubleToStr(ks[i], 0), ".", ",") + ";" +
TimeToStr(od[i], TIME_DATE) + ";" +
TimeToStr(cd[i], TIME_DATE);
WritingLineInFile(gohOutFileName, text);
}
text = "Ñôîðìèðîâàí ôàéë " + gohOutFileName;
Comment(text);
Print(text);
}
//+----------------------------------------------------------------------------+
//| Èùåò ýëåìåíò ìàññèâà òèïà STRING è âîçâðàùàåò åãî èíäåêñ. |
//| Ïðè îòñóòñòâèè èñêîìîãî ýëåìåíòà äîáàâëÿåò íîâûé. |
//| Ïàðàìåòðû: |
//| nm - ìàññèâ ýëåìåíòîâ òèïà STRING (ïåðåäà¸òñÿ ïî ññûëêå) |
//| st - èñêîìîå çíà÷åíèå ýëåìåíòà |
//+----------------------------------------------------------------------------+
int ArrayFind(string& nm[], string st)
{
int i, p;
for(i = 0; i < ArraySize(nm); i++)
{
if(StringLen(st) > 0)
{
p = StringFind(nm[i], st);
if(p >= 0)
return(i);
}
else
if(StringLen(nm[i]) == 0)
return(i);
}
i = ArrayResize(nm, ArraySize(nm) + 1) - 1;
nm[i] = st;
return(i);
}
//+----------------------------------------------------------------------------+
//| Çàìåíà ïîäñòðîêè |
//| Ïàðàìåòðû: |
//| str - òåêñòîâàÿ ñòðîêà, â êîòîðîé ïðîèçâîäèòñÿ çàìåíà |
//| strfrom - çàìåíÿåìàÿ ïîäñòðîêà |
//| strto - çàìåíÿþùàÿ ïîäñòðîêà |
//+----------------------------------------------------------------------------+
string StrTran(string str, string strfrom, string strto)
{
int n;
string outstr = "", tempstr;
for(n = 0; n < StringLen(str); n++)
{
tempstr = StringSubstr(str, n, StringLen(strfrom));
if(tempstr == strfrom)
{
outstr = outstr + strto;
n = n + StringLen(strfrom) - 1;
}
else
outstr = outstr + StringSubstr(str, n, 1);
}
return(outstr);
}
//+----------------------------------------------------------------------------+
//| Çàïèñü ñòðîêè â ôàéë |
//+----------------------------------------------------------------------------+
void WritingLineInFile(string FileName, string text)
{
int file_handle = FileOpen(FileName, FILE_READ|FILE_WRITE, " ");
if(file_handle > 0)
{
FileSeek(file_handle, 0, SEEK_END);
FileWrite(file_handle, text);
FileClose(file_handle);
}
}
//+----------------------------------------------------------------------------+
Comments