239 lines
9.9 KiB
MQL5
239 lines
9.9 KiB
MQL5
//+------------------------------------------------------------------+
| |
//| ExportSymbols.mq5 |
| |
//| Exports symbol information to JSON |
| |
//+------------------------------------------------------------------+
| |
#property script_show_inputs
| |
| |
input string OutputFileName = "symbols.json";
| |
input bool ExportOnlyVisibleSymbols = true;
| |
input bool PrettyPrintJson = true;
| |
| |
//+------------------------------------------------------------------+
| |
//| Escape JSON string |
| |
//+------------------------------------------------------------------+
| |
string JsonEscape(const string value) {
| |
string result = value;
| |
| |
StringReplace(result, "\\", "\\\\");
| |
StringReplace(result, "\"", "\\\"");
| |
StringReplace(result, "\r", "\\r");
| |
StringReplace(result, "\n", "\\n");
| |
StringReplace(result, "\t", "\\t");
| |
| |
return result;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Convert bool to JSON |
| |
//+------------------------------------------------------------------+
| |
string JsonBool(const bool value) {
| |
return value ? "true" : "false";
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Get indentation |
| |
//+------------------------------------------------------------------+
| |
string Indent(const int level) {
| |
if(!PrettyPrintJson)
| |
return "";
| |
| |
string spaces = "";
| |
for(int i = 0; i < level; i++)
| |
spaces += " ";
| |
| |
return spaces;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Get newline |
| |
//+------------------------------------------------------------------+
| |
string NewLine() {
| |
return PrettyPrintJson ? "\n" : "";
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Add JSON field helpers |
| |
//+------------------------------------------------------------------+
| |
string JsonFieldString(const string key, const string value, const int level, const bool comma = true) {
| |
return Indent(level) + "\"" + key + "\": \"" + JsonEscape(value) + "\"" + (comma ? "," : "") + NewLine();
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
string JsonFieldDouble(const string key, const double value, const int level, const bool comma = true) {
| |
return Indent(level) + "\"" + key + "\": " + DoubleToString(value, 10) + (comma ? "," : "") + NewLine();
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
string JsonFieldInteger(const string key, const long value, const int level, const bool comma = true) {
| |
return Indent(level) + "\"" + key + "\": " + (string)value + (comma ? "," : "") + NewLine();
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
string JsonFieldBool(const string key, const bool value, const int level, const bool comma = true) {
| |
return Indent(level) + "\"" + key + "\": " + JsonBool(value) + (comma ? "," : "") + NewLine();
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Build one symbol JSON object |
| |
//+------------------------------------------------------------------+
| |
string BuildSymbolJson(const string symbolName) {
| |
string description = SymbolInfoString(symbolName, SYMBOL_DESCRIPTION);
| |
string path = SymbolInfoString(symbolName, SYMBOL_PATH);
| |
string currencyBase = SymbolInfoString(symbolName, SYMBOL_CURRENCY_BASE);
| |
string currencyProfit = SymbolInfoString(symbolName, SYMBOL_CURRENCY_PROFIT);
| |
string currencyMargin = SymbolInfoString(symbolName, SYMBOL_CURRENCY_MARGIN);
| |
| |
long digits = (long)SymbolInfoInteger(symbolName, SYMBOL_DIGITS);
| |
long spread = (long)SymbolInfoInteger(symbolName, SYMBOL_SPREAD);
| |
long spreadFloat = (long)SymbolInfoInteger(symbolName, SYMBOL_SPREAD_FLOAT);
| |
long tradeMode = (long)SymbolInfoInteger(symbolName, SYMBOL_TRADE_MODE);
| |
long calcMode = (long)SymbolInfoInteger(symbolName, SYMBOL_TRADE_CALC_MODE);
| |
long swapMode = (long)SymbolInfoInteger(symbolName, SYMBOL_SWAP_MODE);
| |
long orderMode = (long)SymbolInfoInteger(symbolName, SYMBOL_ORDER_MODE);
| |
long fillingMode = (long)SymbolInfoInteger(symbolName, SYMBOL_FILLING_MODE);
| |
long expirationMode = (long)SymbolInfoInteger(symbolName, SYMBOL_EXPIRATION_MODE);
| |
| |
double point = SymbolInfoDouble(symbolName, SYMBOL_POINT);
| |
double tickSize = SymbolInfoDouble(symbolName, SYMBOL_TRADE_TICK_SIZE);
| |
double tickValue = SymbolInfoDouble(symbolName, SYMBOL_TRADE_TICK_VALUE);
| |
double tickValueProfit = SymbolInfoDouble(symbolName, SYMBOL_TRADE_TICK_VALUE_PROFIT);
| |
double tickValueLoss = SymbolInfoDouble(symbolName, SYMBOL_TRADE_TICK_VALUE_LOSS);
| |
double contractSize = SymbolInfoDouble(symbolName, SYMBOL_TRADE_CONTRACT_SIZE);
| |
| |
double volumeMin = SymbolInfoDouble(symbolName, SYMBOL_VOLUME_MIN);
| |
double volumeMax = SymbolInfoDouble(symbolName, SYMBOL_VOLUME_MAX);
| |
double volumeStep = SymbolInfoDouble(symbolName, SYMBOL_VOLUME_STEP);
| |
double volumeLimit = SymbolInfoDouble(symbolName, SYMBOL_VOLUME_LIMIT);
| |
| |
double bid = SymbolInfoDouble(symbolName, SYMBOL_BID);
| |
double ask = SymbolInfoDouble(symbolName, SYMBOL_ASK);
| |
double last = SymbolInfoDouble(symbolName, SYMBOL_LAST);
| |
| |
double swapLong = SymbolInfoDouble(symbolName, SYMBOL_SWAP_LONG);
| |
double swapShort = SymbolInfoDouble(symbolName, SYMBOL_SWAP_SHORT);
| |
| |
bool selected = (bool)SymbolInfoInteger(symbolName, SYMBOL_SELECT);
| |
bool visible = (bool)SymbolInfoInteger(symbolName, SYMBOL_VISIBLE);
| |
bool custom = (bool)SymbolInfoInteger(symbolName, SYMBOL_CUSTOM);
| |
// Clean the path (remove symbol from end)
| |
string cleanPath = path;
| |
| |
int start_pos = StringFind(path, symbolName);
| |
| |
if(start_pos > 0)
| |
{
| |
cleanPath = StringSubstr(path, 0, start_pos);
| |
| |
if(StringGetCharacter(cleanPath, StringLen(cleanPath) - 1) == '\\')
| |
cleanPath = StringSubstr(cleanPath, 0, StringLen(cleanPath) - 1);
| |
}
| |
| |
Print(cleanPath);
| |
| |
| |
| |
string json = "";
| |
json += Indent(1) + "{" + NewLine();
| |
| |
json += JsonFieldString("symbol", symbolName, 2);
| |
json += JsonFieldString("description", description, 2);
| |
json += JsonFieldString("path", cleanPath, 2);
| |
json += JsonFieldString("currencyBase", currencyBase, 2);
| |
json += JsonFieldString("currencyProfit", currencyProfit, 2);
| |
json += JsonFieldString("currencyMargin", currencyMargin, 2);
| |
| |
json += JsonFieldInteger("digits", digits, 2);
| |
json += JsonFieldDouble("point", point, 2);
| |
json += JsonFieldDouble("tickSize", tickSize, 2);
| |
json += JsonFieldDouble("tickValue", tickValue, 2);
| |
json += JsonFieldDouble("tickValueProfit", tickValueProfit, 2);
| |
json += JsonFieldDouble("tickValueLoss", tickValueLoss, 2);
| |
json += JsonFieldDouble("contractSize", contractSize, 2);
| |
| |
json += JsonFieldDouble("volumeMin", volumeMin, 2);
| |
json += JsonFieldDouble("volumeMax", volumeMax, 2);
| |
json += JsonFieldDouble("volumeStep", volumeStep, 2);
| |
json += JsonFieldDouble("volumeLimit", volumeLimit, 2);
| |
| |
json += JsonFieldInteger("spread", spread, 2);
| |
json += JsonFieldBool("spreadFloat", spreadFloat != 0, 2);
| |
| |
json += JsonFieldDouble("bid", bid, 2);
| |
json += JsonFieldDouble("ask", ask, 2);
| |
json += JsonFieldDouble("last", last, 2);
| |
| |
json += JsonFieldInteger("tradeMode", tradeMode, 2);
| |
json += JsonFieldInteger("calcMode", calcMode, 2);
| |
json += JsonFieldInteger("swapMode", swapMode, 2);
| |
json += JsonFieldInteger("orderMode", orderMode, 2);
| |
json += JsonFieldInteger("fillingMode", fillingMode, 2);
| |
json += JsonFieldInteger("expirationMode", expirationMode, 2);
| |
| |
json += JsonFieldDouble("swapLong", swapLong, 2);
| |
json += JsonFieldDouble("swapShort", swapShort, 2);
| |
| |
json += JsonFieldBool("selected", selected, 2);
| |
json += JsonFieldBool("visible", visible, 2);
| |
json += JsonFieldBool("custom", custom, 2, false);
| |
| |
json += Indent(1) + "}";
| |
| |
return json;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Script entry |
| |
//+------------------------------------------------------------------+
| |
void OnStart() {
| |
int total = SymbolsTotal(false);
| |
if(total <= 0) {
| |
Print("No symbols found.");
| |
return;
| |
}
| |
| |
string json = "[" + NewLine();
| |
int exportedCount = 0;
| |
| |
for(int i = 0; i < total; i++) {
| |
string symbolName = SymbolName(i, false);
| |
if(symbolName == "")
| |
continue;
| |
| |
bool visible = (bool)SymbolInfoInteger(symbolName, SYMBOL_VISIBLE);
| |
bool selected = (bool)SymbolInfoInteger(symbolName, SYMBOL_SELECT);
| |
| |
if(ExportOnlyVisibleSymbols) {
| |
if(!visible && !selected)
| |
continue;
| |
}
| |
| |
string symbolJson = BuildSymbolJson(symbolName);
| |
| |
if(exportedCount > 0)
| |
json += "," + NewLine();
| |
| |
json += symbolJson;
| |
exportedCount++;
| |
}
| |
| |
json += NewLine() + "]";
| |
| |
int handle = FileOpen(OutputFileName, FILE_WRITE | FILE_TXT | FILE_ANSI);
| |
if(handle == INVALID_HANDLE) {
| |
Print("Failed to open file for writing: ", OutputFileName, " Error: ", GetLastError());
| |
return;
| |
}
| |
| |
FileWriteString(handle, json);
| |
FileClose(handle);
| |
| |
Print("Export complete. Symbols exported: ", exportedCount);
| |
Print("Saved to: MQL5\\Files\\", OutputFileName);
| |
}
| |
//+------------------------------------------------------------------+
|