Vizion-Trading-EA/NeuralNet.mqh

190 lines
4.3 KiB
MQL5
Raw Permalink Normal View History

#ifndef NEURAL_NET_MQH
#define NEURAL_NET_MQH
#include "NNFeatures.mqh"
string NN_Trim(const string s)
{
string x = s;
StringTrimLeft(x);
StringTrimRight(x);
return x;
}
string NN_BuildPayload(const double &feat[])
{
string tf = EnumToString((ENUM_TIMEFRAMES)Period());
string json = "{";
json += "\"symbol\":\"" + _Symbol + "\",";
json += "\"tf\":\"" + tf + "\",";
json += "\"features\":{";
int n = ArraySize(feat);
for(int i = 0; i < n; i++)
{
json += "\"f" + IntegerToString(i) + "\":" + DoubleToString(feat[i], 8);
if(i < n - 1) json += ",";
}
json += "},";
json += "\"feature_vector\":[";
for(int j = 0; j < n; j++)
{
json += DoubleToString(feat[j], 8);
if(j < n - 1) json += ",";
}
json += "]}";
return json;
}
bool NN_ExtractNumber(const string &json, const string &key, double &out)
{
int k = StringFind(json, "\"" + key + "\"");
if(k < 0) return false;
int colon = StringFind(json, ":", k);
if(colon < 0) return false;
int endComma = StringFind(json, ",", colon);
int endBrace = StringFind(json, "}", colon);
int end = endComma;
if(end < 0 || (endBrace >= 0 && endBrace < end)) end = endBrace;
if(end < 0) return false;
string val = StringSubstr(json, colon + 1, end - (colon + 1));
val = NN_Trim(val);
out = StringToDouble(val);
return true;
}
bool NN_ExtractInt(const string &json, const string &key, int &out)
{
double tmp = 0.0;
if(!NN_ExtractNumber(json, key, tmp)) return false;
out = (int)MathRound(tmp);
return true;
}
bool NN_ExtractString(const string &json, const string &key, string &out)
{
int k = StringFind(json, "\"" + key + "\"");
if(k < 0) return false;
int colon = StringFind(json, ":", k);
if(colon < 0) return false;
int q1 = StringFind(json, "\"", colon + 1);
if(q1 < 0) return false;
int q2 = StringFind(json, "\"", q1 + 1);
if(q2 < 0) return false;
out = StringSubstr(json, q1 + 1, q2 - q1 - 1);
return true;
}
bool NN_WebPredict(const string url, const string jsonPayload, string &response)
{
char post[], result[];
string headers = "Content-Type: application/json\r\n";
int timeout = NN_TimeoutMs;
StringToCharArray(jsonPayload, post);
ResetLastError();
string result_headers;
int res = WebRequest("POST", url, headers, timeout, post, result, result_headers);
if(res == -1)
{
if(NN_DebugPrint)
Print("NN WebRequest failed. Error=", GetLastError(), " | URL=", url);
return false;
}
response = CharArrayToString(result);
return true;
}
bool InitializeNeuralNet()
{
if(!Use_NeuralNet) return false;
NN_Initialized = true;
NN_LastRun = 0;
NN_Bias = 0;
NN_Confidence = 0.0;
NN_RiskScore = 50.0;
NN_Explain = "NN init ok";
return true;
}
bool UpdateNeuralNetSignal()
{
NN_UsedLastTick = false;
if(!Use_NeuralNet || !NN_Initialized)
return false;
datetime now = TimeCurrent();
if(NN_LastRun > 0 && (now - NN_LastRun) < NN_CooldownSeconds)
return false;
double feat[];
int n = BuildNNFeatures(feat);
if(n <= 0)
return false;
string payload = NN_BuildPayload(feat);
string resp;
if(!NN_WebPredict(NN_ServerURL, payload, resp))
{
NN_Explain = "NN request failed";
return false;
}
int bias = 0;
double conf = 0.0, risk = 50.0;
string explain = "";
bool ok1 = NN_ExtractInt(resp, "bias", bias);
bool ok2 = NN_ExtractNumber(resp, "confidence", conf);
bool ok3 = NN_ExtractNumber(resp, "risk", risk);
NN_ExtractString(resp, "explain", explain);
if(!(ok1 && ok2 && ok3))
{
NN_Explain = "NN parse failed: " + resp;
return false;
}
if(bias > 1) bias = 1;
if(bias < -1) bias = -1;
NN_Bias = bias;
NN_Confidence = NN_Clamp(conf, 0.0, 100.0);
NN_RiskScore = NN_Clamp(risk, 0.0, 100.0);
NN_Explain = (explain == "" ? "ok" : explain);
NN_LastRun = now;
NN_UsedLastTick = true;
if(NN_DebugPrint)
Print("NN => bias=", NN_Bias,
" conf=", DoubleToString(NN_Confidence, 1),
" risk=", DoubleToString(NN_RiskScore, 1),
" | ", NN_Explain);
return true;
}
bool NN_IsUsable()
{
if(!Use_NeuralNet || !NN_Initialized) return false;
if(NN_Confidence < NN_MinConfidenceToUse) return false;
if(NN_RiskScore > NN_MaxRiskToUse) return false;
return true;
}
#endif