//+------------------------------------------------------------------+ //| Qwen3.7Max.mqh | //| Copyright 2026, Niquel Mendoza. | //| https://www.mql5.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2026, Niquel Mendoza." #property link "https://www.mql5.com/" #property strict //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // Same prompt claude\mql5 lite /* Primeras impresiones compilo a la primera... Ahora testeesmo.. Bien primer testeo y por lo visto errores 2026.06.28 21:21:08.983 Qwen3.7Max (EURUSD,H1) Unexpected character Parece que tendremos que corregir. Por lo visto era la vlidacion extra.. al final de terminar el parse ya lo quite.. Ahora probemos denuevo.. 2026.06.28 21:27:40.629 Qwen3.7Max (EURUSD,H1) true 2026.06.28 21:27:40.629 Qwen3.7Max (EURUSD,H1) 0 2026.06.28 21:27:41.401 Qwen3.7Max (EURUSD,H1) true 2026.06.28 21:27:41.401 Qwen3.7Max (EURUSD,H1) 0 Nada por lo visto Print(json.Parse()); Print(json["statuses"].Count()); Fnciona pero count da 0 deberia de dar 100 otra ia que falla aqui. Otra vez mas este modelo chino creo que es mas decente pero aun creo que queda por debajo de claude o gpt.. No da... sabe sintaxis pero creo aun le falta .. en total tardo 15 minutos daod que razono como 10 literalmente... Podria decirle que lo rehaga... */ //// Code ai start.. //+------------------------------------------------------------------+ //| Json.mqh | //| High Performance JSON Parser for MQL5 | //+------------------------------------------------------------------+ #property copyright "High Performance JSON Parser" #property version "1.00" #property strict #ifndef __JSON_MQH__ #define __JSON_MQH__ //--- Enumeraciones para tipos de datos y errores enum ENUM_JSON_TYPE { JSON_UNDEFINED = -1, JSON_OBJECT = 0, JSON_ARRAY, JSON_STRING, JSON_NUMBER, JSON_BOOL, JSON_NULL }; enum ENUM_JSON_ERROR { JSON_OK = 0, JSON_UNEXPECTED_CHARACTER, JSON_UNEXPECTED_END, JSON_INVALID_NUMBER, JSON_INVALID_STRING, JSON_INVALID_ESCAPE, JSON_INVALID_UNICODE, JSON_EXPECTED_COLON, JSON_EXPECTED_COMMA, JSON_EXPECTED_OBJECT, JSON_EXPECTED_ARRAY, JSON_EXPECTED_STRING, JSON_MAX_DEPTH, JSON_UNKNOWN }; //--- Declaración adelantada class CJsonNode; //+------------------------------------------------------------------+ //| Clase Principal del Parser (CJson) | //+------------------------------------------------------------------+ class CJson { public: // Buffer público para que el usuario pueda llenarlo directamente sin copias uchar Buffer[]; private: // --- Representación Interna (Structure of Arrays para máximo rendimiento y cache-friendly) --- int m_type[]; int m_start[]; // Offset de inicio en Buffer (o valor para bool) int m_end[]; // Offset de fin en Buffer int m_child[]; // Índice del primer hijo int m_next[]; // Índice del siguiente hermano int m_key_start[]; // Offset de inicio de la clave (para objetos) int m_key_end[]; // Offset de fin de la clave int m_node_count; int m_node_capacity; // --- Stack manual para parsing iterativo --- enum ENUM_STATE { STATE_ROOT, STATE_ARRAY_ITEM, STATE_ARRAY_NEXT, STATE_OBJECT_KEY, STATE_OBJECT_COLON, STATE_OBJECT_VALUE, STATE_OBJECT_NEXT }; int m_stack_state[]; int m_stack_node[]; int m_stack_last_child[]; int m_stack_key_start[]; int m_stack_key_end[]; int m_stack_top; int m_stack_capacity; // --- Estado del Parser --- int m_root; int m_pos; int m_len; // --- Manejo de Errores --- ENUM_JSON_ERROR m_error; int m_error_pos; int m_error_line; int m_error_col; // --- Métodos Internos --- void GrowNodes() { m_node_capacity = (m_node_capacity == 0) ? 1024 : m_node_capacity * 2; ArrayResize(m_type, m_node_capacity); ArrayResize(m_start, m_node_capacity); ArrayResize(m_end, m_node_capacity); ArrayResize(m_child, m_node_capacity); ArrayResize(m_next, m_node_capacity); ArrayResize(m_key_start, m_node_capacity); ArrayResize(m_key_end, m_node_capacity); } void GrowStack() { m_stack_capacity = (m_stack_capacity == 0) ? 128 : m_stack_capacity * 2; ArrayResize(m_stack_state, m_stack_capacity); ArrayResize(m_stack_node, m_stack_capacity); ArrayResize(m_stack_last_child, m_stack_capacity); ArrayResize(m_stack_key_start, m_stack_capacity); ArrayResize(m_stack_key_end, m_stack_capacity); } int AddNode(int type, int start, int end) { if(m_node_count >= m_node_capacity) GrowNodes(); int idx = m_node_count++; m_type[idx] = type; m_start[idx] = start; m_end[idx] = end; m_child[idx] = -1; m_next[idx] = -1; m_key_start[idx] = -1; m_key_end[idx] = -1; return idx; } void Error(ENUM_JSON_ERROR err) { if(m_error == JSON_OK) // Solo registrar el primer error { m_error = err; m_error_pos = m_pos; m_error_line = 1; m_error_col = 1; for(int i = 0; i < m_pos && i < m_len; i++) { if(Buffer[i] == '\n') { m_error_line++; m_error_col = 1; } else { m_error_col++; } } } } void SkipWhitespace() { while(m_pos < m_len) { uchar c = Buffer[m_pos]; if(c < 33) m_pos++; // MEJORADO POR LEO else break; } } bool ParseString(int &start, int &end) { m_pos++; // Saltar la comilla inicial '"' start = m_pos; while(m_pos < m_len) { uchar c = Buffer[m_pos]; if(c == '"') { end = m_pos; m_pos++; return true; } if(c == '\\') // MEJORADO POR LEO { m_pos += 2; } else { if(c < 32) { Error(JSON_INVALID_STRING); // Caracteres de control no escapados return false; } m_pos++; } } Error(JSON_UNEXPECTED_END); return false; } bool ParseNumber(int &start, int &end) { start = m_pos; if(Buffer[m_pos] == '-') m_pos++; if(m_pos >= m_len) { Error(JSON_INVALID_NUMBER); return false; } if(Buffer[m_pos] == '0') { m_pos++; } else if(Buffer[m_pos] >= '1' && Buffer[m_pos] <= '9') { while(m_pos < m_len && Buffer[m_pos] >= '0' && Buffer[m_pos] <= '9') m_pos++; } else { Error(JSON_INVALID_NUMBER); return false; } if(m_pos < m_len && Buffer[m_pos] == '.') { m_pos++; if(m_pos >= m_len || Buffer[m_pos] < '0' || Buffer[m_pos] > '9') { Error(JSON_INVALID_NUMBER); return false; } while(m_pos < m_len && Buffer[m_pos] >= '0' && Buffer[m_pos] <= '9') m_pos++; } if(m_pos < m_len && (Buffer[m_pos] == 'e' || Buffer[m_pos] == 'E')) { m_pos++; if(m_pos < m_len && (Buffer[m_pos] == '+' || Buffer[m_pos] == '-')) m_pos++; if(m_pos >= m_len || Buffer[m_pos] < '0' || Buffer[m_pos] > '9') { Error(JSON_INVALID_NUMBER); return false; } while(m_pos < m_len && Buffer[m_pos] >= '0' && Buffer[m_pos] <= '9') m_pos++; } end = m_pos; return true; } int ParseValue() { SkipWhitespace(); if(m_pos >= m_len) { Error(JSON_UNEXPECTED_END); return -1; } uchar c = Buffer[m_pos]; if(c == '"') { int start, end; if(!ParseString(start, end)) return -1; return AddNode(JSON_STRING, start, end); } else if(c == '{') { m_pos++; int node = AddNode(JSON_OBJECT, m_pos - 1, -1); PushState(STATE_OBJECT_KEY, node); return node; } else if(c == '[') { m_pos++; int node = AddNode(JSON_ARRAY, m_pos - 1, -1); PushState(STATE_ARRAY_ITEM, node); return node; } else if(c == 't') { if(m_pos + 4 <= m_len && Buffer[m_pos + 1] == 'r' && Buffer[m_pos + 2] == 'u' && Buffer[m_pos + 3] == 'e') { m_pos += 4; return AddNode(JSON_BOOL, 1, -1); // 1 = true } Error(JSON_UNEXPECTED_CHARACTER); return -1; } else if(c == 'f') { if(m_pos + 5 <= m_len && Buffer[m_pos + 1] == 'a' && Buffer[m_pos + 2] == 'l' && Buffer[m_pos + 3] == 's' && Buffer[m_pos + 4] == 'e') { m_pos += 5; return AddNode(JSON_BOOL, 0, -1); // 0 = false } Error(JSON_UNEXPECTED_CHARACTER); return -1; } else if(c == 'n') { if(m_pos + 4 <= m_len && Buffer[m_pos + 1] == 'u' && Buffer[m_pos + 2] == 'l' && Buffer[m_pos + 3] == 'l') { m_pos += 4; return AddNode(JSON_NULL, 0, -1); } Error(JSON_UNEXPECTED_CHARACTER); return -1; } else if(c == '-' || (c >= '0' && c <= '9')) { int start, end; if(!ParseNumber(start, end)) return -1; return AddNode(JSON_NUMBER, start, end); } Error(JSON_UNEXPECTED_CHARACTER); return -1; } void PushState(int state, int node_idx) { if(m_stack_top >= m_stack_capacity) GrowStack(); m_stack_state[m_stack_top] = state; m_stack_node[m_stack_top] = node_idx; m_stack_last_child[m_stack_top] = -1; m_stack_key_start[m_stack_top] = -1; m_stack_key_end[m_stack_top] = -1; m_stack_top++; } public: CJson() { m_node_count = 0; m_node_capacity = 0; m_stack_top = 0; m_stack_capacity = 0; m_root = -1; Reset(); } ~CJson() { Clear(); } bool Parse() { Reset(); m_len = ArraySize(Buffer); if(m_len == 0) { Error(JSON_UNEXPECTED_END); return false; } PushState(STATE_ROOT, -1); while(m_stack_top > 0) { int state = m_stack_state[m_stack_top - 1]; SkipWhitespace(); if(m_pos >= m_len && state != STATE_ROOT) { Error(JSON_UNEXPECTED_END); break; } uchar c = (m_pos < m_len) ? Buffer[m_pos] : 0; if(state == STATE_ROOT) { m_root = ParseValue(); if(m_root == -1) break; m_stack_top--; // Pop root } else if(state == STATE_ARRAY_ITEM || state == STATE_ARRAY_NEXT) { if(state == STATE_ARRAY_NEXT) { if(c == ',') { m_pos++; continue; } if(c == ']') { m_pos++; m_stack_top--; continue; } Error(JSON_EXPECTED_COMMA); break; } // STATE_ARRAY_ITEM if(c == ']') // Array vacío { m_pos++; m_stack_top--; continue; } int child = ParseValue(); if(child == -1) break; int arr_node = m_stack_node[m_stack_top - 1]; if(m_child[arr_node] == -1) { m_child[arr_node] = child; } else { m_next[m_stack_last_child[m_stack_top - 1]] = child; } m_stack_last_child[m_stack_top - 1] = child; m_stack_state[m_stack_top - 1] = STATE_ARRAY_NEXT; } else if(state == STATE_OBJECT_KEY || state == STATE_OBJECT_NEXT) { if(state == STATE_OBJECT_NEXT) { if(c == ',') { m_pos++; continue; } if(c == '}') { m_pos++; m_stack_top--; continue; } Error(JSON_EXPECTED_COMMA); break; } // STATE_OBJECT_KEY if(c == '}') // Objeto vacío { m_pos++; m_stack_top--; continue; } if(c != '"') { Error(JSON_EXPECTED_STRING); break; } int ks, ke; if(!ParseString(ks, ke)) break; m_stack_key_start[m_stack_top - 1] = ks; m_stack_key_end[m_stack_top - 1] = ke; m_stack_state[m_stack_top - 1] = STATE_OBJECT_COLON; } else if(state == STATE_OBJECT_COLON) { if(c != ':') { Error(JSON_EXPECTED_COLON); break; } m_pos++; m_stack_state[m_stack_top - 1] = STATE_OBJECT_VALUE; } else if(state == STATE_OBJECT_VALUE) { int child = ParseValue(); if(child == -1) break; int obj_node = m_stack_node[m_stack_top - 1]; m_key_start[child] = m_stack_key_start[m_stack_top - 1]; m_key_end[child] = m_stack_key_end[m_stack_top - 1]; if(m_child[obj_node] == -1) { m_child[obj_node] = child; } else { m_next[m_stack_last_child[m_stack_top - 1]] = child; } m_stack_last_child[m_stack_top - 1] = child; m_stack_state[m_stack_top - 1] = STATE_OBJECT_NEXT; } } /* if(m_error == JSON_OK) { SkipWhitespace(); if(m_pos < m_len) { Error(JSON_UNEXPECTED_CHARACTER); // Caracteres basura al final } }*/ return (m_error == JSON_OK); } void Reset() { m_node_count = 0; m_stack_top = 0; m_root = -1; m_pos = 0; m_error = JSON_OK; m_error_pos = 0; m_error_line = 0; m_error_col = 0; } void Clear() { Reset(); ArrayFree(m_type); ArrayFree(m_start); ArrayFree(m_end); ArrayFree(m_child); ArrayFree(m_next); ArrayFree(m_key_start); ArrayFree(m_key_end); ArrayFree(m_stack_state); ArrayFree(m_stack_node); ArrayFree(m_stack_last_child); ArrayFree(m_stack_key_start); ArrayFree(m_stack_key_end); m_node_capacity = 0; m_stack_capacity = 0; } // --- API de Errores --- ENUM_JSON_ERROR GetError() { return m_error; } bool HasError() { return m_error != JSON_OK; } int GetErrorPosition() { return m_error_pos; } int GetLine() { return m_error_line; } int GetColumn() { return m_error_col; } string GetErrorMessage() { switch(m_error) { case JSON_OK: return "OK"; case JSON_UNEXPECTED_CHARACTER: return "Unexpected character"; case JSON_UNEXPECTED_END: return "Unexpected end of JSON"; case JSON_INVALID_NUMBER: return "Invalid number"; case JSON_INVALID_STRING: return "Invalid string"; case JSON_INVALID_ESCAPE: return "Invalid escape sequence"; case JSON_INVALID_UNICODE: return "Invalid unicode escape"; case JSON_EXPECTED_COLON: return "Expected ':'"; case JSON_EXPECTED_COMMA: return "Expected ','"; case JSON_EXPECTED_OBJECT: return "Expected object"; case JSON_EXPECTED_ARRAY: return "Expected array"; case JSON_EXPECTED_STRING: return "Expected string"; case JSON_MAX_DEPTH: return "Maximum nesting depth exceeded"; default: return "Unknown error"; } } // --- API de Acceso (Internos) --- int GetRoot() { return m_root; } int GetNodeType(int idx) { return (idx >= 0 && idx < m_node_count) ? m_type[idx] : JSON_UNDEFINED; } int GetNodeChild(int idx) { return (idx >= 0) ? m_child[idx] : -1; } int GetNodeNext(int idx) { return (idx >= 0) ? m_next[idx] : -1; } int GetNodeStart(int idx) { return (idx >= 0) ? m_start[idx] : -1; } int GetNodeEnd(int idx) { return (idx >= 0) ? m_end[idx] : -1; } int GetNodeCount() { return m_node_count; } int GetKeyStart(int idx) { return (idx >= 0) ? m_key_start[idx] : -1; } int GetKeyEnd(int idx) { return (idx >= 0) ? m_key_end[idx] : -1; } // Conversión rápida de String (Decodificación bajo demanda) string GetStringValue(int start, int end) { if(start < 0 || end < start) return ""; bool has_escapes = false; for(int i = start; i < end; i++) { if(Buffer[i] == '\\') { has_escapes = true; break; } } if(!has_escapes) { return CharArrayToString(Buffer, start, end - start); } // Decodificación de escapes (Rama lenta) uchar decoded[]; ArrayResize(decoded, end - start); int dec_pos = 0; for(int i = start; i < end; i++) { if(Buffer[i] == '\\' && i + 1 < end) { i++; uchar esc = Buffer[i]; if(esc == '"') decoded[dec_pos++] = '"'; else if(esc == '\\') decoded[dec_pos++] = '\\'; else if(esc == '/') decoded[dec_pos++] = '/'; else if(esc == 'b') decoded[dec_pos++] = 8; else if(esc == 'f') decoded[dec_pos++] = 12; else if(esc == 'n') decoded[dec_pos++] = 10; else if(esc == 'r') decoded[dec_pos++] = 13; else if(esc == 't') decoded[dec_pos++] = 9; else if(esc == 'u' && i + 4 < end) { int hex = 0; for(int j = 0; j < 4; j++) { hex <<= 4; uchar h = Buffer[i + 1 + j]; if(h >= '0' && h <= '9') hex |= (h - '0'); else if(h >= 'a' && h <= 'f') hex |= (h - 'a' + 10); else if(h >= 'A' && h <= 'F') hex |= (h - 'A' + 10); } if(hex < 128) decoded[dec_pos++] = (uchar)hex; else if(hex < 0x800) { decoded[dec_pos++] = (uchar)(0xC0 | (hex >> 6)); decoded[dec_pos++] = (uchar)(0x80 | (hex & 0x3F)); } else { decoded[dec_pos++] = (uchar)(0xE0 | (hex >> 12)); decoded[dec_pos++] = (uchar)(0x80 | ((hex >> 6) & 0x3F)); decoded[dec_pos++] = (uchar)(0x80 | (hex & 0x3F)); } i += 4; } } else { decoded[dec_pos++] = Buffer[i]; } } return CharArrayToString(decoded, 0, dec_pos); } // Conversión rápida de Número (Matemática directa, sin StringToDouble) double GetNumberValue(int start, int end) { double val = 0.0; bool neg = false; int i = start; if(i < end && Buffer[i] == '-') { neg = true; i++; } while(i < end && Buffer[i] >= '0' && Buffer[i] <= '9') { val = val * 10.0 + (Buffer[i] - '0'); i++; } if(i < end && Buffer[i] == '.') { i++; double frac = 0.0, div = 1.0; while(i < end && Buffer[i] >= '0' && Buffer[i] <= '9') { frac = frac * 10.0 + (Buffer[i] - '0'); div *= 10.0; i++; } val += frac / div; } if(i < end && (Buffer[i] == 'e' || Buffer[i] == 'E')) { i++; bool exp_neg = false; if(i < end && Buffer[i] == '-') { exp_neg = true; i++; } else if(i < end && Buffer[i] == '+') { i++; } int exp = 0; while(i < end && Buffer[i] >= '0' && Buffer[i] <= '9') { exp = exp * 10 + (Buffer[i] - '0'); i++; } val = val * MathPow(10.0, exp_neg ? -exp : exp); } return neg ? -val : val; } bool CompareKey(int child_idx, const string key) { int ks = m_key_start[child_idx]; int ke = m_key_end[child_idx]; if(ks == -1 || ke == -1) return false; int len = ke - ks; if(len != StringLen(key)) return false; // Fast path para claves ASCII for(int i = 0; i < len; i++) { ushort ch = StringGetCharacter(key, i); if(ch > 127 || Buffer[ks + i] != (uchar)ch) { return (GetStringValue(ks, ke) == key); // Slow path } } return true; } // --- Operadores para acceso tipo diccionario --- CJsonNode operator[](const string key); CJsonNode operator[](const int index); }; //+------------------------------------------------------------------+ //| Clase Nodo (CJsonNode) - Wrapper para acceso fluido | //+------------------------------------------------------------------+ class CJsonNode { private: CJson* m_owner; int m_idx; public: CJsonNode() : m_owner(NULL), m_idx(-1) {} CJsonNode(CJson* owner, int idx) : m_owner(owner), m_idx(idx) {} bool IsValid() { return (m_owner != NULL && m_idx >= 0); } bool Exists() { return IsValid() && m_owner.GetNodeType(m_idx) != JSON_UNDEFINED; } CJsonNode operator[](const string key) { if(!IsValid()) return CJsonNode(); if(m_owner.GetNodeType(m_idx) != JSON_OBJECT) return CJsonNode(); int child = m_owner.GetNodeChild(m_idx); while(child != -1) { if(m_owner.CompareKey(child, key)) return CJsonNode(m_owner, child); child = m_owner.GetNodeNext(child); } return CJsonNode(); } CJsonNode operator[](const int index) { if(!IsValid()) return CJsonNode(); if(m_owner.GetNodeType(m_idx) != JSON_ARRAY) return CJsonNode(); int child = m_owner.GetNodeChild(m_idx); int i = 0; while(child != -1) { if(i == index) return CJsonNode(m_owner, child); child = m_owner.GetNodeNext(child); i++; } return CJsonNode(); } string AsString() { if(!IsValid() || m_owner.GetNodeType(m_idx) != JSON_STRING) return ""; return m_owner.GetStringValue(m_owner.GetNodeStart(m_idx), m_owner.GetNodeEnd(m_idx)); } double AsDouble() { if(!IsValid()) return 0.0; int t = m_owner.GetNodeType(m_idx); if(t == JSON_NUMBER) return m_owner.GetNumberValue(m_owner.GetNodeStart(m_idx), m_owner.GetNodeEnd(m_idx)); if(t == JSON_STRING) return StringToDouble(AsString()); return 0.0; } long AsLong() { return (long)AsDouble(); } bool AsBool() { if(!IsValid()) return false; int t = m_owner.GetNodeType(m_idx); if(t == JSON_BOOL) return m_owner.GetNodeStart(m_idx) == 1; if(t == JSON_NUMBER) return AsDouble() != 0.0; if(t == JSON_STRING) return AsString() != ""; return false; } int Size() { return Count(); } int Count() { if(!IsValid()) return 0; int t = m_owner.GetNodeType(m_idx); if(t != JSON_ARRAY && t != JSON_OBJECT) return 0; int count = 0; int child = m_owner.GetNodeChild(m_idx); while(child != -1) { count++; child = m_owner.GetNodeNext(child); } return count; } bool IsObject() { return IsValid() && m_owner.GetNodeType(m_idx) == JSON_OBJECT; } bool IsArray() { return IsValid() && m_owner.GetNodeType(m_idx) == JSON_ARRAY; } bool IsString() { return IsValid() && m_owner.GetNodeType(m_idx) == JSON_STRING; } bool IsNumber() { return IsValid() && m_owner.GetNodeType(m_idx) == JSON_NUMBER; } bool IsBool() { return IsValid() && m_owner.GetNodeType(m_idx) == JSON_BOOL; } bool IsNull() { return IsValid() && m_owner.GetNodeType(m_idx) == JSON_NULL; } string GetKey() { if(!IsValid()) return ""; int ks = m_owner.GetKeyStart(m_idx); int ke = m_owner.GetKeyEnd(m_idx); if(ks == -1) return ""; return m_owner.GetStringValue(ks, ke); } }; //+------------------------------------------------------------------+ //| Implementación de Operadores de CJson | //+------------------------------------------------------------------+ CJsonNode CJson::operator[](const string key) { if(m_root == -1 || m_type[m_root] != JSON_OBJECT) return CJsonNode(NULL, -1); int child = m_child[m_root]; while(child != -1) { if(CompareKey(child, key)) return CJsonNode(GetPointer(this), child); child = m_next[child]; } return CJsonNode(NULL, -1); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CJsonNode CJson::operator[](const int index) { if(m_root == -1 || m_type[m_root] != JSON_ARRAY) return CJsonNode(NULL, -1); int child = m_child[m_root]; int i = 0; while(child != -1) { if(i == index) return CJsonNode(GetPointer(this), child); child = m_next[child]; i++; } return CJsonNode(NULL, -1); } #endif // __JSON_MQH__ //+------------------------------------------------------------------+