Warrior_EA/Scripts/DumpSymbolSpecs.mq5
AnimateDread 035a4920bc docs(research): pipeline analysis, and the two scripts the research depended on
DumpSymbolSpecs exports symbol specifications and deal history so the research
cost model uses the account's real commission and swap rather than assumptions.
ExportIndicatorBuffers dumps every AD/Wyckoff indicator buffer over full history,
so the research conditions on the PRODUCTION detectors rather than a Python
re-implementation of them - which is what made the Wyckoff verdict a verdict on
the indicators rather than on my approximation of them.

Both are read-only: handles, CopyBuffer, and writes under Common\Files. No orders,
no chart changes, no writes to any model or AltData file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 01:57:18 -04:00

132 lines
7.2 KiB
MQL5

//+------------------------------------------------------------------+
//| DumpSymbolSpecs.mq5 |
//| Write every Market Watch symbol's contract and SWAP specification |
//| to Common\Files\Warrior_EA\symbol_specs.csv, for the research |
//| cost model. Read-only: no orders, no chart changes. |
//| |
//| Swap is the reason this exists. Bar history carries no swap, and |
//| the research policy is to charge the CURRENT swap, negative on |
//| both sides, every night, with the 3-day rollover applied. Whether |
//| SYMBOL_SWAP_LONG/SHORT is the per-night figure or already the |
//| tripled one is NOT answered by the API; this dump records what |
//| the spec says together with SYMBOL_SWAP_ROLLOVER3DAYS so the |
//| research side can compare it against a real deal's DEAL_SWAP. |
//+------------------------------------------------------------------+
#property script_show_inputs
#property strict
input bool AllSymbols = true; // true = every symbol the server offers, false = Market Watch only
string Q(const string s) { return "\"" + s + "\""; }
void OnStart()
{
string dir = "Warrior_EA";
FolderCreate(dir, FILE_COMMON);
string path = dir + "\\symbol_specs.csv";
int h = FileOpen(path, FILE_WRITE | FILE_TXT | FILE_ANSI | FILE_COMMON | FILE_SHARE_READ | FILE_SHARE_WRITE);
if(h == INVALID_HANDLE)
{
Print("DumpSymbolSpecs: cannot open ", path, " err=", GetLastError());
return;
}
FileWriteString(h, "symbol,path,digits,point,contract_size,tick_size,tick_value,calc_mode,trade_mode,"
"swap_mode,swap_long,swap_short,swap_3days,spread_now,spread_float,"
"currency_base,currency_profit,currency_margin,volume_min,volume_step,volume_max,"
"session_deals,server_time\n");
int total = SymbolsTotal(!AllSymbols);
int written = 0;
for(int i = 0; i < total; i++)
{
string s = SymbolName(i, !AllSymbols);
if(s == "")
continue;
//--- SymbolInfo* on a symbol that is not selected returns stale zeros for some fields;
//--- select it for the read and leave the Market Watch as we found it.
bool wasSelected = SymbolInfoInteger(s, SYMBOL_SELECT) != 0;
if(!wasSelected)
SymbolSelect(s, true);
string line = Q(s) + "," + Q(SymbolInfoString(s, SYMBOL_PATH)) + ","
+ IntegerToString(SymbolInfoInteger(s, SYMBOL_DIGITS)) + ","
+ DoubleToString(SymbolInfoDouble(s, SYMBOL_POINT), 8) + ","
+ DoubleToString(SymbolInfoDouble(s, SYMBOL_TRADE_CONTRACT_SIZE), 4) + ","
+ DoubleToString(SymbolInfoDouble(s, SYMBOL_TRADE_TICK_SIZE), 8) + ","
+ DoubleToString(SymbolInfoDouble(s, SYMBOL_TRADE_TICK_VALUE), 6) + ","
+ IntegerToString(SymbolInfoInteger(s, SYMBOL_TRADE_CALC_MODE)) + ","
+ IntegerToString(SymbolInfoInteger(s, SYMBOL_TRADE_MODE)) + ","
+ IntegerToString(SymbolInfoInteger(s, SYMBOL_SWAP_MODE)) + ","
+ DoubleToString(SymbolInfoDouble(s, SYMBOL_SWAP_LONG), 6) + ","
+ DoubleToString(SymbolInfoDouble(s, SYMBOL_SWAP_SHORT), 6) + ","
+ IntegerToString(SymbolInfoInteger(s, SYMBOL_SWAP_ROLLOVER3DAYS)) + ","
+ IntegerToString(SymbolInfoInteger(s, SYMBOL_SPREAD)) + ","
+ IntegerToString(SymbolInfoInteger(s, SYMBOL_SPREAD_FLOAT)) + ","
+ Q(SymbolInfoString(s, SYMBOL_CURRENCY_BASE)) + ","
+ Q(SymbolInfoString(s, SYMBOL_CURRENCY_PROFIT)) + ","
+ Q(SymbolInfoString(s, SYMBOL_CURRENCY_MARGIN)) + ","
+ DoubleToString(SymbolInfoDouble(s, SYMBOL_VOLUME_MIN), 4) + ","
+ DoubleToString(SymbolInfoDouble(s, SYMBOL_VOLUME_STEP), 4) + ","
+ DoubleToString(SymbolInfoDouble(s, SYMBOL_VOLUME_MAX), 4) + ","
+ IntegerToString(SymbolInfoInteger(s, SYMBOL_SESSION_DEALS)) + ","
+ TimeToString(TimeTradeServer(), TIME_DATE | TIME_SECONDS) + "\n";
FileWriteString(h, line);
written++;
if(!wasSelected)
SymbolSelect(s, false);
}
FileClose(h);
Print("DumpSymbolSpecs: wrote ", written, " symbols to Common\\Files\\", path,
" (swap_mode: 0=disabled 1=points 2=base currency 3=margin currency 4=deposit currency "
"5=% annual current price 6=% annual open price 7=points reopen 8=% reopen)");
DumpDeals(dir);
}
//+------------------------------------------------------------------+
//| The account's own deal history - the only ground truth for what a |
//| swap "point" and a commission actually cost. DEAL_SWAP is booked |
//| on the closing deal for the whole life of the position; paired |
//| with the opening deal of the same position id it yields the swap |
//| per lot per night that the spec's figure has to reproduce. |
//+------------------------------------------------------------------+
void DumpDeals(const string dir)
{
datetime to = TimeCurrent();
datetime from = to - 400 * 86400;
if(!HistorySelect(from, to))
{
Print("DumpSymbolSpecs: HistorySelect failed err=", GetLastError());
return;
}
string path = dir + "\\deal_history.csv";
int h = FileOpen(path, FILE_WRITE | FILE_TXT | FILE_ANSI | FILE_COMMON | FILE_SHARE_READ | FILE_SHARE_WRITE);
if(h == INVALID_HANDLE)
{
Print("DumpSymbolSpecs: cannot open ", path, " err=", GetLastError());
return;
}
FileWriteString(h, "ticket,position_id,symbol,time,type,entry,volume,price,swap,commission,profit,magic,comment\n");
int n = HistoryDealsTotal();
int written = 0;
for(int i = 0; i < n; i++)
{
ulong t = HistoryDealGetTicket(i);
if(t == 0)
continue;
string line = IntegerToString((long)t) + ","
+ IntegerToString((long)HistoryDealGetInteger(t, DEAL_POSITION_ID)) + ","
+ Q(HistoryDealGetString(t, DEAL_SYMBOL)) + ","
+ TimeToString((datetime)HistoryDealGetInteger(t, DEAL_TIME), TIME_DATE | TIME_SECONDS) + ","
+ IntegerToString((long)HistoryDealGetInteger(t, DEAL_TYPE)) + ","
+ IntegerToString((long)HistoryDealGetInteger(t, DEAL_ENTRY)) + ","
+ DoubleToString(HistoryDealGetDouble(t, DEAL_VOLUME), 4) + ","
+ DoubleToString(HistoryDealGetDouble(t, DEAL_PRICE), 8) + ","
+ DoubleToString(HistoryDealGetDouble(t, DEAL_SWAP), 4) + ","
+ DoubleToString(HistoryDealGetDouble(t, DEAL_COMMISSION), 4) + ","
+ DoubleToString(HistoryDealGetDouble(t, DEAL_PROFIT), 4) + ","
+ IntegerToString((long)HistoryDealGetInteger(t, DEAL_MAGIC)) + ","
+ Q(HistoryDealGetString(t, DEAL_COMMENT)) + "\n";
FileWriteString(h, line);
written++;
}
FileClose(h);
Print("DumpSymbolSpecs: wrote ", written, " deals (last 400 days) to Common\\Files\\", path);
}
//+------------------------------------------------------------------+