| //+------------------------------------------------------------------+
|
| //| 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
|