forked from animatedread/Warrior_EA
63 lines
3.1 KiB
MQL5
63 lines
3.1 KiB
MQL5
//+------------------------------------------------------------------+
| |||
//| TradeLog.mqh |
| |||
//| AnimateDread |
| |||
//| |
| |||
//| ONE ROW PER CLOSED POSITION of this symbol and magic, written to |
| |||
//| the common folder at deinit: <prefix>_trades_<SYMBOL>.csv. The |
| |||
//| columns are WarriorDipZ's journal, so research/reconcile.py and |
| |||
//| grid_summary.py read either EA's output - which is how Warrior |
| |||
//| was checked trade for trade against the reference implementation. |
| |||
//+------------------------------------------------------------------+
| |||
#ifndef WARRIOR_TRADELOG_MQH
| |||
#define WARRIOR_TRADELOG_MQH
| |||
| |||
void WriteTradeLog(const string prefix, const string symbol, const long magic)
| |||
{
| |||
if(!HistorySelect(0, TimeCurrent() + 86400))
| |||
return;
| |||
const int h = FileOpen(prefix + "_trades_" + symbol + ".csv",
| |||
FILE_WRITE | FILE_CSV | FILE_ANSI | FILE_COMMON, ',');
| |||
if(h == INVALID_HANDLE)
| |||
return;
| |||
FileWrite(h, "position", "symbol", "entry_time", "entry_price", "volume",
| |||
"exit_time", "exit_price", "net_profit", "exit_reason",
| |||
"gross_profit", "swap", "commission");
| |||
const int deals = HistoryDealsTotal();
| |||
for(int i = 0; i < deals; i++)
| |||
{
| |||
const ulong d = HistoryDealGetTicket(i);
| |||
if(HistoryDealGetInteger(d, DEAL_MAGIC) != magic ||
| |||
HistoryDealGetInteger(d, DEAL_ENTRY) != DEAL_ENTRY_OUT ||
| |||
HistoryDealGetString(d, DEAL_SYMBOL) != symbol)
| |||
continue;
| |||
const long pos = HistoryDealGetInteger(d, DEAL_POSITION_ID);
| |||
datetime et = 0;
| |||
double ep = 0, vol = 0, gross = 0, swp = 0, com = 0;
| |||
for(int j = 0; j < deals; j++)
| |||
{
| |||
const ulong e = HistoryDealGetTicket(j);
| |||
if(HistoryDealGetInteger(e, DEAL_POSITION_ID) != pos)
| |||
continue;
| |||
gross += HistoryDealGetDouble(e, DEAL_PROFIT);
| |||
swp += HistoryDealGetDouble(e, DEAL_SWAP);
| |||
com += HistoryDealGetDouble(e, DEAL_COMMISSION);
| |||
if(HistoryDealGetInteger(e, DEAL_ENTRY) == DEAL_ENTRY_IN)
| |||
{
| |||
et = (datetime)HistoryDealGetInteger(e, DEAL_TIME);
| |||
ep = HistoryDealGetDouble(e, DEAL_PRICE);
| |||
vol = HistoryDealGetDouble(e, DEAL_VOLUME);
| |||
}
| |||
}
| |||
const long rsn = HistoryDealGetInteger(d, DEAL_REASON);
| |||
const string why = (rsn == DEAL_REASON_SL ? "stop" : (rsn == DEAL_REASON_SO ? "stopout" : "expert"));
| |||
FileWrite(h, (string)pos, symbol,
| |||
TimeToString(et, TIME_DATE | TIME_MINUTES), DoubleToString(ep, 5),
| |||
DoubleToString(vol, 2),
| |||
TimeToString((datetime)HistoryDealGetInteger(d, DEAL_TIME), TIME_DATE | TIME_MINUTES),
| |||
DoubleToString(HistoryDealGetDouble(d, DEAL_PRICE), 5),
| |||
DoubleToString(gross + swp + com, 2), why, DoubleToString(gross, 2),
| |||
DoubleToString(swp, 2), DoubleToString(com, 2));
| |||
}
| |||
FileClose(h);
| |||
}
| |||
#endif // WARRIOR_TRADELOG_MQH
|