An ML-driven EUR/USD strategy that treats the market as an information process: it measures the Shannon entropy of recent up/down returns (how “random” vs “structured” the tape looks), combines it with recent drift and volatility, and uses Zorro’s built-in adviseLong() machine learning to predict the next-day return and scale long/short exposure accordingly.

Code
// ============================================================================
// 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);
    }
}

Last edited by TipmyPip; Yesterday at 07:18.