// ============================================================================
// Shiller_EURUSD_EntropyML_HistoryBounds.c — Zorro / lite-C (EUR/USD)
// ============================================================================
function run()
{
// ------------------------------------------------------------------------
// SESSION / DATA SETTINGS (SET THESE BEFORE asset()!)
// ------------------------------------------------------------------------
BarPeriod = 1440; // 1 day bars
// "Use whatever history is available":
// StartDate earlier than history -> clamps to first bar.
// EndDate = 0 -> runs to end of available history by default.
StartDate = 20250101;
EndDate = 0;
LookBack = 250;
// RULES required for advise* ML training/loading
set(PLOTNOW|RULES);
asset("EUR/USD");
algo("EntropyML");
// ------------------------------------------------------------------------
// PRICE SERIES
// ------------------------------------------------------------------------
var eps = 1e-12;
vars P = series(priceClose());
vars R1 = series(log(max(eps,P[0]) / max(eps,P[1])));
// ------------------------------------------------------------------------
// "DIVIDEND" / CARRY PROXY (Part A)
// ------------------------------------------------------------------------
var carryDaily = 0.015/252.;
vars D = series(carryDaily);
// ------------------------------------------------------------------------
// Create feature series UNCONDITIONALLY (good practice)
// ------------------------------------------------------------------------
vars EntS = series(0);
vars StdevS = series(0);
vars MeanRS = series(0);
// =========================================================================
// PART A: Excess volatility illustration (scaled down)
// =========================================================================
int Kmax = 60;
var r_d = 0.0001;
vars Px = series(0);
if (Bar > LookBack)
{
var sumDisc = 0;
var disc = 1;
int k;
for (k = 1; k <= Kmax; k++)
{
disc /= (1 + r_d);
sumDisc += disc * D[k];
}
Px[0] = sumDisc;
int W = 80;
if (Bar > LookBack + Kmax + W)
{
var meanP = 0, meanPx = 0;
int i;
for (i = 0; i < W; i++) { meanP += P[i]; meanPx += Px[i]; }
meanP /= (var)W;
meanPx /= (var)W;
var varP = 0, varPx = 0;
for (i = 0; i < W; i++)
{
var a = P[i] - meanP;
var b = Px[i] - meanPx;
varP += a*a;
varPx += b*b;
}
varP /= (var)(W-1);
varPx /= (var)(W-1);
plot("Var(P)", varP, NEW, 0);
plot("Var(P*)", varPx, 0, 0);
if (Bar % 20 == 0)
printf("\n[EXCESS VOL] W=%d Var(P)=%.6g Var(P*)=%.6g ratio=%.3f",
W, varP, varPx, varP/(varPx + eps));
}
}
// =========================================================================
// PART B: ENTROPY + MACHINE LEARNING (adviseLong)
// =========================================================================
int Wml = 60;
if (Bar > LookBack + Wml + 5)
{
int up = 0, down = 0;
int i;
for (i = 1; i <= Wml; i++)
{
if (R1[i] > 0) up++;
else if (R1[i] < 0) down++;
}
var p_up = ifelse((up + down) > 0, (var)up / (var)(up + down), 0.5);
var p_dn = 1 - p_up;
var entropy = 0;
if (p_up > 0 && p_dn > 0)
entropy = -p_up*log(p_up) - p_dn*log(p_dn);
var meanR = 0;
for (i = 1; i <= Wml; i++) meanR += R1[i];
meanR /= (var)Wml;
var varR = 0;
for (i = 1; i <= Wml; i++)
{
var d = R1[i] - meanR;
varR += d*d;
}
var stdev = sqrt(max(eps, varR/(var)(Wml-1)));
EntS[0] = entropy;
StdevS[0] = stdev;
MeanRS[0] = meanR;
int Method = PERCEPTRON + FUZZY + BALANCED;
var Objective = R1[0];
int Offset = ifelse(Train, 1, 0);
var Prediction = adviseLong(Method, Objective,
EntS[Offset], StdevS[Offset], MeanRS[Offset]);
var Lev = clamp(Prediction * 10, -0.5, 0.5);
if (Lev > 0.05) { exitShort(); enterLong(); Lots = 1; }
else if (Lev < -0.05) { exitLong(); enterShort(); Lots = 1; }
else { exitLong(); exitShort(); }
plot("Entropy", entropy, NEW, 0);
plot("Pred", Prediction, 0, 0);
plot("Lev", Lev, 0, 0);
}
}