Fix MQL5 compile: rename 'input' params in NeuralNet (keyword conflict), replace Orchestrator pointers with direct array access (MQL5 doesn't support struct pointers)
This commit is contained in:
@@ -498,9 +498,9 @@ for(int i = 0; i < m_hidden; i++) {
|
|||||||
first, last, best, bestEpoch+1, ArraySize(m_lossHistory));
|
first, last, best, bestEpoch+1, ArraySize(m_lossHistory));
|
||||||
}
|
}
|
||||||
|
|
||||||
int Predict(vector &input) {
|
int Predict(vector &inp) {
|
||||||
vector output;
|
vector output;
|
||||||
Forward(input, output);
|
Forward(inp, output);
|
||||||
int bestIdx = 0;
|
int bestIdx = 0;
|
||||||
double bestVal = output[0];
|
double bestVal = output[0];
|
||||||
for(int i = 1; i < m_outputs; i++) {
|
for(int i = 1; i < m_outputs; i++) {
|
||||||
@@ -512,9 +512,9 @@ for(int i = 0; i < m_hidden; i++) {
|
|||||||
return bestIdx;
|
return bestIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
double GetCombinedZ(vector &input) {
|
double GetCombinedZ(vector &inp) {
|
||||||
vector output;
|
vector output;
|
||||||
Forward(input, output);
|
Forward(inp, output);
|
||||||
return output[0] - output[2];
|
return output[0] - output[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -424,42 +424,41 @@ public:
|
|||||||
Print("ERROR: slot non disponibile nonostante capacity expansion");
|
Print("ERROR: slot non disponibile nonostante capacity expansion");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
TrackedTrade *t = &openTrades[idx];
|
openTrades[idx].ticket = ticket;
|
||||||
t.ticket = ticket;
|
openTrades[idx].entryPrice = price;
|
||||||
t.entryPrice = price;
|
openTrades[idx].entryATR = MathMax(atr, 1e-10);
|
||||||
t.entryATR = MathMax(atr, 1e-10);
|
openTrades[idx].entryZ = z;
|
||||||
t.entryZ = z;
|
openTrades[idx].isBuy = isBuy;
|
||||||
t.isBuy = isBuy;
|
openTrades[idx].highestPrice = price;
|
||||||
t.highestPrice = price;
|
openTrades[idx].lowestPrice = price;
|
||||||
t.lowestPrice = price;
|
openTrades[idx].barsHeld = 0;
|
||||||
t.barsHeld = 0;
|
openTrades[idx].maeATR = 0;
|
||||||
t.maeATR = 0;
|
openTrades[idx].mfeATR = 0;
|
||||||
t.mfeATR = 0;
|
openTrades[idx].active = true;
|
||||||
t.active = true;
|
|
||||||
|
|
||||||
for(int i=0; i<agentCount; i++)
|
for(int i=0; i<agentCount; i++)
|
||||||
t.entryZScores[i] = agents[i].lastZScore;
|
openTrades[idx].entryZScores[i] = agents[i].lastZScore;
|
||||||
|
|
||||||
// Feature vector per NN
|
// Feature vector per NN
|
||||||
for(int f = 0; f < NN_FEATURES; f++) t.entryFeatures[f] = 0.0;
|
for(int f = 0; f < NN_FEATURES; f++) openTrades[idx].entryFeatures[f] = 0.0;
|
||||||
for(int i=0; i<agentCount; i++) {
|
for(int i=0; i<agentCount; i++) {
|
||||||
if(agents[i].name == "Hurst") t.entryFeatures[0] = agents[i].lastZScore;
|
if(agents[i].name == "Hurst") openTrades[idx].entryFeatures[0] = agents[i].lastZScore;
|
||||||
else if(agents[i].name == "ADX") t.entryFeatures[1] = agents[i].lastZScore;
|
else if(agents[i].name == "ADX") openTrades[idx].entryFeatures[1] = agents[i].lastZScore;
|
||||||
else if(agents[i].name == "MA") t.entryFeatures[2] = agents[i].lastZScore;
|
else if(agents[i].name == "MA") openTrades[idx].entryFeatures[2] = agents[i].lastZScore;
|
||||||
else if(agents[i].name == "Momentum") t.entryFeatures[3] = agents[i].lastZScore;
|
else if(agents[i].name == "Momentum") openTrades[idx].entryFeatures[3] = agents[i].lastZScore;
|
||||||
else if(agents[i].name == "Consensus") t.entryFeatures[4] = agents[i].lastZScore;
|
else if(agents[i].name == "Consensus") openTrades[idx].entryFeatures[4] = agents[i].lastZScore;
|
||||||
else if(agents[i].name == "Hunter") t.entryFeatures[5] = agents[i].lastZScore;
|
else if(agents[i].name == "Hunter") openTrades[idx].entryFeatures[5] = agents[i].lastZScore;
|
||||||
}
|
}
|
||||||
t.entryFeatures[6] = SHARED_regimeAgreement;
|
openTrades[idx].entryFeatures[6] = SHARED_regimeAgreement;
|
||||||
t.entryFeatures[7] = SHARED_trendStrength;
|
openTrades[idx].entryFeatures[7] = SHARED_trendStrength;
|
||||||
|
|
||||||
// SL iniziale adattivo
|
// SL iniziale adattivo
|
||||||
double slWidth = AdaptiveSLWidth();
|
double slWidth = AdaptiveSLWidth();
|
||||||
t.slPrice = isBuy ? price - atr * slWidth : price + atr * slWidth;
|
openTrades[idx].slPrice = isBuy ? price - atr * slWidth : price + atr * slWidth;
|
||||||
|
|
||||||
Print("Trade #", ticket, " ", isBuy ? "BUY" : "SELL",
|
Print("Trade #", ticket, " ", isBuy ? "BUY" : "SELL",
|
||||||
" entry=", price, " z=", StringFormat("%+.3f", z),
|
" entry=", price, " z=", StringFormat("%+.3f", z),
|
||||||
" SL=", StringFormat("%.5f", t.slPrice),
|
" SL=", StringFormat("%.5f", openTrades[idx].slPrice),
|
||||||
" (", StringFormat("%.1f", slWidth), " ATR)");
|
" (", StringFormat("%.1f", slWidth), " ATR)");
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
@@ -476,26 +475,24 @@ void OnTradeClose(int ticket, double closePrice) {
|
|||||||
}
|
}
|
||||||
if(idx < 0) return;
|
if(idx < 0) return;
|
||||||
|
|
||||||
TrackedTrade *t = &openTrades[idx];
|
|
||||||
|
|
||||||
// Calcola MAE/MFE finali
|
// Calcola MAE/MFE finali
|
||||||
if(t.isBuy) {
|
if(openTrades[idx].isBuy) {
|
||||||
t.maeATR = (t.entryPrice - t.lowestPrice) / t.entryATR;
|
openTrades[idx].maeATR = (openTrades[idx].entryPrice - openTrades[idx].lowestPrice) / openTrades[idx].entryATR;
|
||||||
t.mfeATR = (t.highestPrice - t.entryPrice) / t.entryATR;
|
openTrades[idx].mfeATR = (openTrades[idx].highestPrice - openTrades[idx].entryPrice) / openTrades[idx].entryATR;
|
||||||
} else {
|
} else {
|
||||||
t.maeATR = (t.highestPrice - t.entryPrice) / t.entryATR;
|
openTrades[idx].maeATR = (openTrades[idx].highestPrice - openTrades[idx].entryPrice) / openTrades[idx].entryATR;
|
||||||
t.mfeATR = (t.entryPrice - t.lowestPrice) / t.entryATR;
|
openTrades[idx].mfeATR = (openTrades[idx].entryPrice - openTrades[idx].lowestPrice) / openTrades[idx].entryATR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ROI in ATR (positivo = profitto nella direzione del trade)
|
// ROI in ATR (positivo = profitto nella direzione del trade)
|
||||||
double actualReturn = t.isBuy
|
double actualReturn = openTrades[idx].isBuy
|
||||||
? (closePrice - t.entryPrice) / t.entryATR
|
? (closePrice - openTrades[idx].entryPrice) / openTrades[idx].entryATR
|
||||||
: (t.entryPrice - closePrice) / t.entryATR;
|
: (openTrades[idx].entryPrice - closePrice) / openTrades[idx].entryATR;
|
||||||
|
|
||||||
returnStats.Update(actualReturn);
|
returnStats.Update(actualReturn);
|
||||||
maeStats.Update(t.maeATR);
|
maeStats.Update(openTrades[idx].maeATR);
|
||||||
mfeStats.Update(t.mfeATR);
|
mfeStats.Update(openTrades[idx].mfeATR);
|
||||||
if(actualReturn > 0) maeWinStats.Update(t.maeATR);
|
if(actualReturn > 0) maeWinStats.Update(openTrades[idx].maeATR);
|
||||||
|
|
||||||
tradeReturns[tradeCount % ROLLING_TRADES] = actualReturn;
|
tradeReturns[tradeCount % ROLLING_TRADES] = actualReturn;
|
||||||
tradeCount++;
|
tradeCount++;
|
||||||
@@ -507,12 +504,12 @@ void OnTradeClose(int ticket, double closePrice) {
|
|||||||
if(dd > maxDrawdown) maxDrawdown = dd;
|
if(dd > maxDrawdown) maxDrawdown = dd;
|
||||||
double actualReturnZ = returnStats.RawZScore(actualReturn);
|
double actualReturnZ = returnStats.RawZScore(actualReturn);
|
||||||
|
|
||||||
Print("=== Learning: Trade #", ticket, " ", t.isBuy ? "BUY" : "SELL", " chiuso ===");
|
Print("=== Learning: Trade #", ticket, " ", openTrades[idx].isBuy ? "BUY" : "SELL", " chiuso ===");
|
||||||
Print(" Return: ", StringFormat("%+.2f ATR", actualReturn),
|
Print(" Return: ", StringFormat("%+.2f ATR", actualReturn),
|
||||||
" | MAE: ", StringFormat("%.2f", t.maeATR),
|
" | MAE: ", StringFormat("%.2f", openTrades[idx].maeATR),
|
||||||
" | MFE: ", StringFormat("%.2f", t.mfeATR),
|
" | MFE: ", StringFormat("%.2f", openTrades[idx].mfeATR),
|
||||||
" | bars: ", t.barsHeld);
|
" | bars: ", openTrades[idx].barsHeld);
|
||||||
Print(" Entry z=", StringFormat("%+.3f", t.entryZ),
|
Print(" Entry z=", StringFormat("%+.3f", openTrades[idx].entryZ),
|
||||||
" | SL width: ", StringFormat("%.2f ATR", AdaptiveSLWidth()));
|
" | SL width: ", StringFormat("%.2f ATR", AdaptiveSLWidth()));
|
||||||
|
|
||||||
double sigThr = combinedZStats.Ready()
|
double sigThr = combinedZStats.Ready()
|
||||||
@@ -521,19 +518,19 @@ void OnTradeClose(int ticket, double closePrice) {
|
|||||||
for(int i=0; i<agentCount; i++) {
|
for(int i=0; i<agentCount; i++) {
|
||||||
if(MathAbs(t.entryZScores[i]) < sigThr) continue;
|
if(MathAbs(t.entryZScores[i]) < sigThr) continue;
|
||||||
|
|
||||||
UpdateCorrelation(i, t.entryZScores[i], actualReturnZ);
|
UpdateCorrelation(i, openTrades[idx].entryZScores[i], actualReturnZ);
|
||||||
double rho = GetCorrelation(i);
|
double rho = GetCorrelation(i);
|
||||||
|
|
||||||
agents[i].weight = MathMax(weightMin, rho);
|
agents[i].weight = MathMax(weightMin, rho);
|
||||||
|
|
||||||
agents[i].Learn(t.entryZScores[i], actualReturnZ);
|
agents[i].Learn(openTrades[idx].entryZScores[i], actualReturnZ);
|
||||||
|
|
||||||
double bias = agents[i].predictionError.Mean();
|
double bias = agents[i].predictionError.Mean();
|
||||||
double biasStd = agents[i].predictionError.Std();
|
double biasStd = agents[i].predictionError.Std();
|
||||||
double rhoLearn = agents[i].predCorr.Ready() ? agents[i].predCorr.Correlation() : 0;
|
double rhoLearn = agents[i].predCorr.Ready() ? agents[i].predCorr.Correlation() : 0;
|
||||||
|
|
||||||
Print(" ", agents[i].name,
|
Print(" ", agents[i].name,
|
||||||
" | pred=", StringFormat("%+.2f", t.entryZScores[i]),
|
" | pred=", StringFormat("%+.2f", openTrades[idx].entryZScores[i]),
|
||||||
" | ρ=", StringFormat("%+.3f", rho),
|
" | ρ=", StringFormat("%+.3f", rho),
|
||||||
" | w=", StringFormat("%.3f", agents[i].weight),
|
" | w=", StringFormat("%.3f", agents[i].weight),
|
||||||
" | bias=", StringFormat("%+.4f", bias),
|
" | bias=", StringFormat("%+.4f", bias),
|
||||||
@@ -545,10 +542,10 @@ void OnTradeClose(int ticket, double closePrice) {
|
|||||||
if(m_trainMode && m_trainBuffer != NULL && m_neuralNet != NULL) {
|
if(m_trainMode && m_trainBuffer != NULL && m_neuralNet != NULL) {
|
||||||
double features[NN_FEATURES];
|
double features[NN_FEATURES];
|
||||||
double target[NN_TARGETS];
|
double target[NN_TARGETS];
|
||||||
for(int f = 0; f < NN_FEATURES; f++) features[f] = t.entryFeatures[f];
|
for(int f = 0; f < NN_FEATURES; f++) features[f] = openTrades[idx].entryFeatures[f];
|
||||||
|
|
||||||
target[0] = 0; target[1] = 0; target[2] = 0;
|
target[0] = 0; target[1] = 0; target[2] = 0;
|
||||||
int tradeDir = t.isBuy ? 1 : -1;
|
int tradeDir = openTrades[idx].isBuy ? 1 : -1;
|
||||||
|
|
||||||
if(actualReturn > 0) {
|
if(actualReturn > 0) {
|
||||||
if(tradeDir == 1) target[0] = 1;
|
if(tradeDir == 1) target[0] = 1;
|
||||||
@@ -591,10 +588,9 @@ void OnTradeClose(int ticket, double closePrice) {
|
|||||||
void UpdateOpenTrades(double high, double low) {
|
void UpdateOpenTrades(double high, double low) {
|
||||||
for(int i=0; i<maxOpenTrades; i++) {
|
for(int i=0; i<maxOpenTrades; i++) {
|
||||||
if(!openTrades[i].active) continue;
|
if(!openTrades[i].active) continue;
|
||||||
TrackedTrade *t = &openTrades[i];
|
if(high > openTrades[i].highestPrice) openTrades[i].highestPrice = high;
|
||||||
if(high > t.highestPrice) t.highestPrice = high;
|
if(low < openTrades[i].lowestPrice) openTrades[i].lowestPrice = low;
|
||||||
if(low < t.lowestPrice) t.lowestPrice = low;
|
openTrades[i].barsHeld++;
|
||||||
t.barsHeld++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,22 +598,21 @@ void OnTradeClose(int ticket, double closePrice) {
|
|||||||
void TrailStops() {
|
void TrailStops() {
|
||||||
for(int i=0; i<maxOpenTrades; i++) {
|
for(int i=0; i<maxOpenTrades; i++) {
|
||||||
if(!openTrades[i].active) continue;
|
if(!openTrades[i].active) continue;
|
||||||
TrackedTrade *t = &openTrades[i];
|
|
||||||
|
|
||||||
double profitATR = t.isBuy
|
double profitATR = openTrades[i].isBuy
|
||||||
? (t.highestPrice - t.entryPrice) / t.entryATR
|
? (openTrades[i].highestPrice - openTrades[i].entryPrice) / openTrades[i].entryATR
|
||||||
: (t.entryPrice - t.lowestPrice) / t.entryATR;
|
: (openTrades[i].entryPrice - openTrades[i].lowestPrice) / openTrades[i].entryATR;
|
||||||
|
|
||||||
double trigger = AdaptiveTrailTrigger();
|
double trigger = AdaptiveTrailTrigger();
|
||||||
if(profitATR > trigger) {
|
if(profitATR > trigger) {
|
||||||
double offset = AdaptiveTrailOffset();
|
double offset = AdaptiveTrailOffset();
|
||||||
double newSL;
|
double newSL;
|
||||||
if(t.isBuy) {
|
if(openTrades[i].isBuy) {
|
||||||
newSL = t.highestPrice - offset * t.entryATR;
|
newSL = openTrades[i].highestPrice - offset * openTrades[i].entryATR;
|
||||||
if(newSL > t.slPrice) t.slPrice = newSL;
|
if(newSL > openTrades[i].slPrice) openTrades[i].slPrice = newSL;
|
||||||
} else {
|
} else {
|
||||||
newSL = t.lowestPrice + offset * t.entryATR;
|
newSL = openTrades[i].lowestPrice + offset * openTrades[i].entryATR;
|
||||||
if(newSL < t.slPrice) t.slPrice = newSL;
|
if(newSL < openTrades[i].slPrice) openTrades[i].slPrice = newSL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user