// ----------------------------------------------------------------------
// J) Tighten updateNet (local pred, no G_AdvScore, log directly)
// ----------------------------------------------------------------------
void updateNet(var driver, var* outMean, var* outEnergy, var* outPower, int writeMeta)
{
int N = G_N, D = G_D, i;
var sum = 0, sumsq = 0;
for(i = 0; i < N; i++){ sum += G_State[i]; sumsq += G_State[i]*G_State[i]; }
var mean = sum / N;
var energy = sumsq;
var power = sumsq / N;
for(i = 0; i < N; i++){
int n1, n2;
n1 = adjSafe(i,0);
if(D >= 2) n2 = adjSafe(i,1); else n2 = n1;
var xi = G_State[i];
var xn1 = G_State[n1];
var xn2 = G_State[n2];
var mom = xi - G_Prev[i];
// --- EW hit-rate update from previous bar's advice vs this bar's realized return (PATCH H)
{
int canScore = 1;
if(is(INITRUN)) canScore = 0;
if(Bar <= LookBack) canScore = 0;
if(abs((var)G_AdvPrev[i]) <= HIT_EPS) canScore = 0;
if(canScore){
int sameSign = 0;
if( ( (var)G_AdvPrev[i] > 0 && G_Ret1 > 0 ) || ( (var)G_AdvPrev[i] < 0 && G_Ret1 < 0 ) )
sameSign = 1;
G_HitEW[i] = (fvar)((1.0 - HIT_ALPHA)*(var)G_HitEW[i] + HIT_ALPHA*(var)sameSign);
if(G_HitN[i] < 0x7fffffff) G_HitN[i] += 1;
}
}
int topEq = -1; var topW = 0;
var dt = dtreeTerm(i, &topEq, &topW);
G_TreeTerm[i] = (fvar)dt;
#ifdef KEEP_TOP_META
G_TopEq[i] = (i16)topEq;
G_TopW[i] = (fvar)topW;
#endif
{
int tid = safeTreeIndexFromEq(G_EqTreeId[i]);
var pred = predByTid(tid); // local predictability if you need it for features
var adv = 0;
if(allowAdvise(i))
adv = adviseEq(i, driver, mean, energy, power);
// Reliability gating of advisor by hit-rate (0.5..1.0) (PATCH H)
var wHit = 0.5 + 0.5*(var)G_HitEW[i];
var advEff = adv * wHit;
var arg1 = (var)(A1x[i])*xn1 + (var)(A1lam[i])*driver + (var)(A1mean[i])*mean + (var)(A1E[i])*energy + (var)(A1P[i])*power + (var)(A1i[i])*i + (var)(A1c[i]);
var arg2 = (var)(A2x[i])*xn2 + (var)(A2lam[i])*driver + (var)(A2mean[i])*mean + (var)(A2E[i])*energy + (var)(A2P[i])*power + (var)(A2i[i])*i + (var)(A2c[i]);
var nl1, nl2;
if(G_Mode[i] == 0){ nl1 = sin(arg1); nl2 = cos(arg2); }
else if(G_Mode[i] == 1){ nl1 = tanh(arg1); nl2 = sin(arg2); }
else if(G_Mode[i] == 2){ nl1 = cos(arg1); nl2 = tanh(arg2); }
else { nl1 = sin(arg1); nl2 = cos(arg2); }
var glob1 = tanh((var)G1mean[i]*mean + (var)G1E[i]*energy);
var glob2 = sin ((var)G2P[i]*power + (var)G2lam[i]*driver);
var xNew =
(var)G_WSelf[i]*xi +
(var)G_WN1[i]*nl1 +
(var)G_WN2[i]*nl2 +
(var)G_WGlob1[i]*glob1 +
(var)G_WGlob2[i]*glob2 +
(var)G_WMom[i]*mom +
(var)G_WTree[i]*dt +
(var)G_WAdv[i]*advEff; // <-- changed to advEff (PATCH H)
G_Prev[i] = xi;
G_State[i] = clamp(xNew, -10, 10);
// Keep last advisor output for next-bar scoring (PATCH H)
G_AdvPrev[i] = (fvar)adv;
}
if(writeMeta && (G_Epoch % META_EVERY == 0) && !G_LogsOff){
int tid2, nn1, nn2;
Node* t2;
tid2 = safeTreeIndexFromEq(G_EqTreeId[i]);
t2 = treeAt(tid2);
nn1 = adjSafe(i,0);
if(G_D >= 2) nn2 = adjSafe(i,1); else nn2 = nn1;
if(LOG_EQ_TO_ONE_FILE){
string expr = "";
if(LOG_EXPR_TEXT) expr = G_Sym[i];
appendEqMetaLine(
Bar, G_Epoch, G_CtxID, i, nn1, nn2, tid2, t2->d, t2->r,
predByTid(tid2), 0, G_Prop[i], G_Mode[i], G_WAdv[i], G_WTree[i],
MC_PBullNext, MC_Entropy, MC_Cur, expr
);
} else {
char fname[64];
buildEqFileName(i, fname);
string expr2 = "";
if(LOG_EXPR_TEXT) expr2 = G_Sym[i];
#ifdef LOG_FLOAT_TRIM
file_append(fname,
strf("META,%i,%i,%i,%i,%i,%i,%i,%i,%.4f,Pred=%.4f,Adv=%.4f,Prop=%.4f,Mode=%i,WAdv=%.3f,WTree=%.3f,PBull=%.4f,Ent=%.4f,State=%i,\"%s\"\n",
G_Epoch, G_CtxID, NET_EQNS, i, nn1, nn2, tid2, t2->d, t2->r,
predByTid(tid2), 0.0, (var)G_Prop[i], G_Mode[i], (var)G_WAdv[i], (var)G_WTree[i],
MC_PBullNext, MC_Entropy, MC_Cur, expr2));
#else
file_append(fname,
strf("META,%i,%i,%i,%i,%i,%i,%i,%i,%.6f,Pred=%.4f,Adv=%.4f,Prop=%.6f,Mode=%i,WAdv=%.3f,WTree=%.3f,PBull=%.4f,Ent=%.4f,State=%i,\"%s\"\n",
G_Epoch, G_CtxID, NET_EQNS, i, nn1, nn2, tid2, t2->d, t2->r,
predByTid(tid2), 0.0, (var)G_Prop[i], G_Mode[i], (var)G_WAdv[i], (var)G_WTree[i],
MC_PBullNext, MC_Entropy, MC_Cur, expr2));
#endif
}
}
}
// refresh squared state once per bar for projection (upgrade #3)
int jj; for(jj=0; jj<N; jj++) G_StateSq[jj] = G_State[jj]*G_State[jj];
if(outMean) *outMean = mean;
if(outEnergy) *outEnergy = energy;
if(outPower) *outPower = power;
}
// ----------------- MAIN -----------------
function run()
{
static int initialized = 0;
static var lambda;
static int fileInit = 0;
BarPeriod = BAR_PERIOD;
if(LookBack < NWIN) LookBack = NWIN;
if(Train) Hedge = 2;
// Plots are opt-in via ENABLE_PLOTS
set(RULES|LEAN);
if(ENABLE_PLOTS) set(PLOTNOW);
asset(ASSET_SYMBOL);
// --- 1-bar realized return for scoring (Close_t - Close_{t-1}) (PATCH F)
{
static var *S_Close;
S_Close = series(priceClose());
if(Bar > LookBack)
G_Ret1 = S_Close[0] - S_Close[1];
else
G_Ret1 = 0;
}
if(is(INITRUN) && !initialized){
// init dummy node
G_DummyNode.v = 0;
G_DummyNode.r = 0;
G_DummyNode.c = 0;
G_DummyNode.n = 0;
G_DummyNode.d = 0;
// allocate Markov matrices (zeroed)
MC_Count = (int*)malloc(MC_STATES*MC_STATES*sizeof(int));
MC_RowSum = (int*)malloc(MC_STATES*sizeof(int));
{
int k;
for(k=0;k<MC_STATES*MC_STATES;k++) MC_Count[k]=0;
for(k=0;k<MC_STATES;k++) MC_RowSum[k]=0;
}
// Candlestick list (names not needed)
buildCDL_TA61(0, 0);
// build tree + network
// Pre-warm node pool so first allocation is guaranteed aligned & ready
if(!G_ChunkHead){
NodeChunk* ch0 = (NodeChunk*)malloc(sizeof(NodeChunk));
if(!ch0) quit("Alpha12: OOM preallocating NodeChunk");
memset(ch0, 0, sizeof(NodeChunk));
ch0->next = 0; ch0->used = 0;
G_ChunkHead = ch0;
}
Root = createNode(MAX_DEPTH);
recalcTreeBytes();
allocateNet();
// ---- depth LUT allocation (heap) ----
G_DepthW = (var*)malloc(DEPTH_LUT_SIZE * sizeof(var));
{ int d; for(d=0; d<DEPTH_LUT_SIZE; d++) G_DepthW[d] = 0; }
G_DepthExpLast = -1.0; // force first refresh
// engine params
G_DTreeExp = 1.10 + random(0.50); // [1.10..1.60)
G_FB_A = 0.60 + random(0.25); // [0.60..0.85)
G_FB_B = 1.0 - G_FB_A;
refreshDepthW(); // prefill LUT
randomizeRP();
computeProjection();
rewireInit();
G_Epoch = 0;
rewireEpoch(0,0,0,0);
// Header setup (consolidated vs legacy)
if(LOG_EQ_TO_ONE_FILE){
writeEqHeaderOnce();
} else {
char fname[64];
int i2;
for(i2=0;i2<NET_EQNS;i2++){
buildEqFileName(i2,fname);
file_append(fname,
"Bar,lambda,gamma,i,State,n1,n2,mean,energy,power,Vel,Mode,WAdv,WSelf,WN1,WN2,WGlob1,WGlob2,WMom,WTree,Pred,Adv,Prop,TreeTerm,TopEq,TopW,TreeId,Depth,Rate,PBull,Entropy,MCState\n");
}
}
// Markov CSV header
if(!fileInit){
file_append("Log\\Alpha12_markov.csv","Bar,State,PBullNext,Entropy,RowSum\n");
fileInit=1;
}
// initial META dump (consolidated or legacy)
{
int i;
for(i=0;i<G_N;i++){
int n1, n2, tid;
Node* t;
var pred, adv;
n1 = adjSafe(i,0);
if(G_D >= 2) n2 = adjSafe(i,1); else n2 = n1;
tid = safeTreeIndexFromEq(G_EqTreeId[i]);
t = treeAt(tid);
pred = predByTid(tid);
adv = 0; // no advising during INITRUN
if(LOG_EQ_TO_ONE_FILE){
string expr = "";
if(LOG_EXPR_TEXT) expr = G_Sym[i];
appendEqMetaLine(
Bar, G_Epoch, G_CtxID, i, n1, n2, tid, t->d, t->r,
pred, adv, G_Prop[i], G_Mode[i], G_WAdv[i], G_WTree[i],
MC_PBullNext, MC_Entropy, MC_Cur, expr
);
} else {
char fname2[64];
buildEqFileName(i,fname2);
string expr2 = "";
if(LOG_EXPR_TEXT) expr2 = G_Sym[i];
#ifdef LOG_FLOAT_TRIM
file_append(fname2,
strf("META,%i,%i,%i,%i,%i,%i,%i,%i,%.4f,Pred=%.4f,Adv=%.4f,Prop=%.4f,Mode=%i,WAdv=%.3f,WTree=%.3f,PBull=%.4f,Ent=%.4f,State=%i,\"%s\"\n",
G_Epoch, G_CtxID, NET_EQNS, i, n1, n2, tid, t->d, t->r,
pred, adv, (var)G_Prop[i], G_Mode[i], (var)G_WAdv[i], (var)G_WTree[i],
MC_PBullNext, MC_Entropy, MC_Cur, expr2));
#else
file_append(fname2,
strf("META,%i,%i,%i,%i,%i,%i,%i,%i,%.6f,Pred=%.4f,Adv=%.4f,Prop=%.6f,Mode=%i,WAdv=%.3f,WTree=%.3f,PBull=%.4f,Ent=%.4f,State=%i,\"%s\"\n",
G_Epoch, G_CtxID, NET_EQNS, i, n1, n2, tid, t->d, t->r,
pred, adv, (var)G_Prop[i], G_Mode[i], (var)G_WAdv[i], (var)G_WTree[i],
MC_PBullNext, MC_Entropy, MC_Cur, expr2));
#endif
}
}
}
initialized=1;
printf("\nRoot nodes: %i | Net equations: %i (degree=%i, kproj=%i)",
countNodes(Root), G_N, G_D, G_K);
}
// early zero-cost shedding when approaching cap
if(mem_mb_est() >= MEM_BUDGET_MB - 2*MEM_HEADROOM_MB && G_ShedStage == 0)
shed_zero_cost_once();
// ==== Runtime memory / depth manager (acts only when near the cap)
depth_manager_runtime();
// ====== Per bar: Candles ? Markov (with optional cadence)
{
static var CDL[MC_NPAT];
if((Bar % MC_EVERY) == 0){
buildCDL_TA61(CDL,0);
MC_Cur = MC_stateFromCDL(CDL, G_MC_ACT);
if(Bar > LookBack) MC_update(MC_Prev, MC_Cur);
MC_Prev = MC_Cur;
{
var rs = (var)MC_RowSum[MC_Cur];
G_MC_Alpha = clamp(1.0 / (1.0 + rs/256.0), 0.05, 1.0);
}
// one-pass stats (upgrade #6)
MC_rowStats(MC_Cur, &MC_PBullNext, &MC_Entropy);
}
// expose Markov features
G_MCF_PBull = MC_PBullNext;
G_MCF_Entropy = MC_Entropy;
G_MCF_State = (var)MC_Cur;
// adaptive acceptance rate ? adjust threshold
{
var aEW = 0.01; // ~100-bar half-life
G_AccRate = (1 - aEW)*G_AccRate + aEW*(MC_Cur != 0);
{
var target = 0.35; // aim for ~35% nonzero states
G_MC_ACT = clamp(G_MC_ACT + 0.02*(G_AccRate - target), 0.15, 0.60);
}
}
}
// ====== Tree driver lambda
lambda = evaluateNode(Root);
// ====== Rewire cadence (4) + epoch work
{
int doRewire = ((Bar % REWIRE_EVERY) == 0);
// --- Patch N: If reliability is weak, allow a light early rewire
{
var HitAvg = 0; int ii;
for(ii=0; ii<G_N; ii++) HitAvg += (var)G_HitEW[ii] * (var)G_Prop[ii];
if(G_N <= 0) HitAvg = 0.5;
// At most 1/4 the normal cadence, only when weak
if(HitAvg < 0.46 && (Bar % (REWIRE_EVERY/4)) == 0) doRewire = 1;
}
// (4) early rewire when utility falls
{
static var U_prev = 0;
var U_now = util_now();
if(U_now + 0.01 < U_prev) doRewire = 1;
U_prev = U_now;
}
if(doRewire){
G_Epoch++;
{
int ii;
var sum=0;
for(ii=0;ii<G_N;ii++) sum += G_State[ii];
{
var mean = sum/G_N;
var energy=0;
for(ii=0;ii<G_N;ii++) energy += G_State[ii]*G_State[ii];
var power = energy/G_N;
rewireEpoch(lambda,mean,energy,power);
}
}
}
// (8/9) adapt effective projection K each bar and recompute projection once
G_Keff = ifelse(MC_Entropy < 0.45, KPROJ, KPROJ/2);
computeProjection();
// (3) dynamic advisor budget per bar (before updateNet so it applies now)
{
int tight = (mem_mb_est() >= MEM_BUDGET_MB - MEM_HEADROOM_MB);
G_AdviseMax = ifelse(tight, 12, ifelse(MC_Entropy < 0.45, 32, 16));
}
// Update net this bar (write META only if rewired and not shedding logs)
{
var meanB, energyB, powerB;
updateNet(lambda, &meanB, &energyB, &powerB, doRewire);
var gamma = 0;
// Feedback: compute ensemble projection
{
gamma = projectNet();
// --- Accuracy sentinel update & elastic depth controller ---
acc_update(lambda, gamma);
edc_runtime();
// (1) Adaptive feedback blend toward the more informative component
{
var w = 0.5 + 0.5*G_AccCorr; // 0..1
G_FB_W = clamp(0.9*G_FB_W + 0.1*w, 0.2, 0.9);
lambda = G_FB_W*lambda + (1.0 - G_FB_W)*gamma;
}
}
// Plot/log gating
{
int doPlot = (ENABLE_PLOTS && !G_ChartsOff);
int doLog = ifelse(G_LogsOff, ((Bar % (LOG_EVERY*4)) == 0), ((Bar % LOG_EVERY) == 0));
// Plots
if(doPlot){
plot("lambda", lambda, LINE, 0);
plot("gamma", gamma, LINE, 0);
plot("P_win", powerB, LINE, 0);
plot("PBullNext", MC_PBullNext, LINE, 0);
plot("MC_Entropy", MC_Entropy, LINE, 0);
plot("MemMB", memory(0)/(1024.*1024.), LINE, 0);
plot("Allocs", (var)memory(2), LINE, 0);
plot("HitEW_7", (var)G_HitEW[7], LINE, 0); // (PATCH K) watch eq #7
}
// Markov CSV log (decimated; further decimated when shedding)
if(doLog){
#ifdef LOG_FLOAT_TRIM
file_append("Log\\Alpha12_markov.csv",
strf("%i,%i,%.4f,%.4f,%i\n", Bar, MC_Cur, MC_PBullNext, MC_Entropy, MC_RowSum[MC_Cur]));
#else
file_append("Log\\Alpha12_markov.csv",
strf("%i,%i,%.6f,%.6f,%i\n", Bar, MC_Cur, MC_PBullNext, MC_Entropy, MC_RowSum[MC_Cur]));
#endif
// Optional: per-eq hit snapshot (throttled by LOG_EQ_SAMPLE) (PATCH J)
{
int ii;
for(ii=0; ii<G_N && ii<LOG_EQ_SAMPLE; ii++){
file_append("Log\\Alpha12_hits.csv",
strf("%i,%i,%.4f,%i,%.3f,%.6f\n",
Bar, ii, (var)G_HitEW[ii], G_HitN[ii], (var)G_AdvPrev[ii], G_Ret1));
// Columns: Bar,i,HitEW,HitN,PrevAdv,Ret1
}
}
}
}
}
// --- Patch M: reliability-weighted ensemble hit ? position sizing
{
var HitAvg = 0;
int ii;
for(ii=0; ii<G_N; ii++) HitAvg += (var)G_HitEW[ii] * (var)G_Prop[ii];
if(G_N <= 0) HitAvg = 0.5;
// Map 0..1 -> 0.5..2.0 lots, gently
Lots = clamp(1.0 + 2.0*(HitAvg - 0.5), 0.5, 2.0);
}
// ====== Entries (Markov-gated) ======
if( MC_PBullNext > PBULL_LONG_TH && lambda > 0.7 ) enterLong();
if( MC_PBullNext < PBULL_SHORT_TH && lambda < -0.7 ) enterShort();
}
}
// Clean up memory
function cleanup()
{
if(Root) freeTree(Root);
freeNodePool(); // upgrade #2: release pool chunks
if(MC_Count) free(MC_Count);
if(MC_RowSum) free(MC_RowSum);
if(G_DepthW) free(G_DepthW); // free LUT
freeNet();
}