void rewireAdjacency_DTREE_range(int i0,int i1, var lambda, var mean, var energy, var power){
int i,d,c,best,cand;
if(i0<0) i0=0; if(i1>net.N) i1=net.N;
for(i=i0;i<i1;i++){
for(d=0; d<net.D; d++){
var bestScore = -2; best=-1;
for(c=0;c<CandNeigh;c++){
cand = (int)random(net.N);
if(cand==i) continue;
int clash=0,k;
for(k=0;k<d;k++){
int prev = net.Adj[i*net.D + k];
if(prev>=0 && prev==cand){ clash=1; break; }
}
if(clash) continue;
var s = scorePairSafe(i,cand,lambda,mean,energy,power);
if(s > bestScore){ bestScore=s; best=cand; }
}
if(best<0){ do{ best=(int)random(net.N);} while(best==i); }
net.Adj[i*net.D + d] = (i16)best;
}
}
}
// ---------------- coefficient synthesis (unchanged) -------------------
void synthesizeEquationFromDTREE(int i, var lambda, var mean, var energy, var power){
var seed = adviseSeed(i,lambda,mean,energy,power);
net.Mode[i] = (int)(abs(1000*seed)) & 3;
net.WSelf[i] = (fvar)mapA(mix01(seed, 11), 0.15, 0.85);
net.WN1[i] = (fvar)mapA(mix01(seed, 12), 0.05, 0.35);
net.WN2[i] = (fvar)mapA(mix01(seed, 13), 0.05, 0.35);
net.WGlob1[i] = (fvar)mapA(mix01(seed, 14), 0.05, 0.30);
net.WGlob2[i] = (fvar)mapA(mix01(seed, 15), 0.05, 0.30);
net.WMom[i] = (fvar)mapA(mix01(seed, 16), 0.02, 0.15);
net.WTree[i] = (fvar)mapA(mix01(seed, 17), 0.05, 0.35);
net.WAdv[i] = (fvar)mapA(mix01(seed, 18), 0.05, 0.35);
net.A1x[i] = (fvar)(randsign()*mapA(mix01(seed, 21), 0.6, 1.2));
net.A1lam[i] = (fvar)(randsign()*mapA(mix01(seed, 22), 0.05,0.35));
net.A1mean[i]= (fvar) mapA(mix01(seed, 23),-0.30,0.30);
net.A1E[i] = (fvar) mapA(mix01(seed, 24),-0.0015,0.0015);
net.A1P[i] = (fvar) mapA(mix01(seed, 25),-0.30,0.30);
net.A1i[i] = (fvar) mapA(mix01(seed, 26),-0.02,0.02);
net.A1c[i] = (fvar) mapA(mix01(seed, 27),-0.20,0.20);
net.A2x[i] = (fvar)(randsign()*mapA(mix01(seed, 31), 0.6, 1.2));
net.A2lam[i] = (fvar)(randsign()*mapA(mix01(seed, 32), 0.05,0.35));
net.A2mean[i]= (fvar) mapA(mix01(seed, 33),-0.30,0.30);
net.A2E[i] = (fvar) mapA(mix01(seed, 34),-0.0015,0.0015);
net.A2P[i] = (fvar) mapA(mix01(seed, 35),-0.30,0.30);
net.A2i[i] = (fvar) mapA(mix01(seed, 36),-0.02,0.02);
net.A2c[i] = (fvar) mapA(mix01(seed, 37),-0.20,0.20);
net.G1mean[i] = (fvar) mapA(mix01(seed, 41), 0.4, 1.6);
net.G1E[i] = (fvar) mapA(mix01(seed, 42),-0.004,0.004);
net.G2P[i] = (fvar) mapA(mix01(seed, 43), 0.1, 1.2);
net.G2lam[i] = (fvar) mapA(mix01(seed, 44), 0.05, 0.7);
net.TAlpha[i] = (fvar) mapA(mix01(seed, 51), 0.3, 1.5);
net.TBeta[i] = (fvar) mapA(mix01(seed, 52), 6.0, 50.0);
net.PropRaw[i] = (fvar)(0.01 + 0.99*(0.5*(seed+1.0)));
{ var boost = 0.75 + 0.5*(var)net.HitEW[i];
net.PropRaw[i] = (fvar)((var)net.PropRaw[i] * boost);
}
}
void synthesizeEquation_range(int i0,int i1, var lambda, var mean, var energy, var power){
if(i0<0) i0=0; if(i1>net.N) i1=net.N;
int i;
for(i=i0;i<i1;i++) synthesizeEquationFromDTREE(i,lambda,mean,energy,power);
}
// ------------------- DTREE ensemble term (unchanged) ------------------
var dtreeTerm(int i, int* outTopEq, var* outTopW){
int j;
int tid_i = dt.safeTreeIndexFromEq((int)net.EqTreeId[i], dt.TreeN);
Node* ti = dt.treeAt(tid_i);
int di = ti->d; var ri=ti->r;
var predI = dt.predByTid(tid_i);
var alpha = (var)net.TAlpha[i];
var beta = (var)net.TBeta[i];
var sumw=0, acc=0, bestW=-1; int bestJ=-1;
for(j=0;j<net.N;j++){
if(j==i) continue;
int tid_j = dt.safeTreeIndexFromEq((int)net.EqTreeId[j], dt.TreeN);
Node* tj=dt.treeAt(tid_j);
int dj=tj->d; var rj=tj->r;
var predJ = dt.predByTid(tid_j);
var w = exp(-alpha*abs(di-dj)) * exp(-beta*abs(ri-rj));
var predBoost = 0.5 + 0.5*(predI*predJ);
var propBoost = 0.5 + 0.5*( (net.Prop[i] + net.Prop[j]) );
w *= predBoost * propBoost;
var pairAdv = scorePairSafe(i,j,0,0,0,0);
var pairBoost = 0.75 + 0.25*(0.5*(pairAdv+1.0));
w *= pairBoost;
sumw += w;
acc += w*net.State[j];
if(w>bestW){ bestW=w; bestJ=j; }
}
if(outTopEq) *outTopEq = bestJ;
if(outTopW) *outTopW = ifelse(sumw>0, bestW/sumw, 0);
if(sumw>0) return acc/sumw;
return 0;
}
// ------------------- expression builder (optional) --------------------
void buildSymbolicExpr(int i, int n1, int n2){
if(!LOG_EXPR_TEXT) return;
if(!net.Sym) return;
string s = net.Sym[i];
s[0]=0;
string a1 = strf("(%.3f*x[%i] + %.3f*lam + %.3f*mean + %.5f*E + %.3f*P + %.3f*i + %.3f)",
(var)net.A1x[i], n1, (var)net.A1lam[i], (var)net.A1mean[i], (var)net.A1E[i], (var)net.A1P[i], (var)net.A1i[i], (var)net.A1c[i]);
string a2 = strf("(%.3f*x[%i] + %.3f*lam + %.3f*mean + %.5f*E + %.3f*P + %.3f*i + %.3f)",
(var)net.A2x[i], n2, (var)net.A2lam[i], (var)net.A2mean[i], (var)net.A2E[i], (var)net.A2P[i], (var)net.A2i[i], (var)net.A2c[i]);
Alpha12Logger::strlcat_safe(s, "x[i]_next = ", EXPR_MAXLEN);
Alpha12Logger::strlcat_safe(s, strf("%.3f*x[i] + ", (var)net.WSelf[i]), EXPR_MAXLEN);
if(net.Mode[i]==1){
Alpha12Logger::strlcat_safe(s, strf("%.3f*tanh%s + ", (var)net.WN1[i], a1), EXPR_MAXLEN);
Alpha12Logger::strlcat_safe(s, strf("%.3f*sin%s + ", (var)net.WN2[i], a2), EXPR_MAXLEN);
} else if(net.Mode[i]==2){
Alpha12Logger::strlcat_safe(s, strf("%.3f*cos%s + ", (var)net.WN1[i], a1), EXPR_MAXLEN);
Alpha12Logger::strlcat_safe(s, strf("%.3f*tanh%s + ", (var)net.WN2[i], a2), EXPR_MAXLEN);
} else {
Alpha12Logger::strlcat_safe(s, strf("%.3f*sin%s + ", (var)net.WN1[i], a1), EXPR_MAXLEN);
Alpha12Logger::strlcat_safe(s, strf("%.3f*cos%s + ", (var)net.WN2[i], a2), EXPR_MAXLEN);
}
Alpha12Logger::strlcat_safe(s, strf("%.3f*tanh(%.3f*mean + %.5f*E) + ",
(var)net.WGlob1[i], (var)net.G1mean[i], (var)net.G1E[i]), EXPR_MAXLEN);
Alpha12Logger::strlcat_safe(s, strf("%.3f*sin(%.3f*P + %.3f*lam) + ",
(var)net.WGlob2[i], (var)net.G2P[i], (var)net.G2lam[i]), EXPR_MAXLEN);
Alpha12Logger::strlcat_safe(s, strf("%.3f*(x[i]-x_prev[i]) + ", (var)net.WMom[i]), EXPR_MAXLEN);
Alpha12Logger::strlcat_safe(s, strf("Prop[i]=%.4f; ", (var)net.Prop[i]), EXPR_MAXLEN);
Alpha12Logger::strlcat_safe(s, strf("%.3f*DT(i) + ", (var)net.WTree[i]), EXPR_MAXLEN);
Alpha12Logger::strlcat_safe(s, strf("%.3f*DTREE(i)", (var)net.WAdv[i]), EXPR_MAXLEN);
}
void buildSymbolicExpr_range(int i0,int i1){
if(!LOG_EXPR_TEXT) return;
if(i0<0) i0=0; if(i1>net.N) i1=net.N;
int i;
for(i=i0;i<i1;i++){
int n1 = net.adjSafe(i,0);
int n2 = ifelse(net.D>=2, net.adjSafe(i,1), n1);
buildSymbolicExpr(i,n1,n2);
}
}
// ------------------- chunked rewire orchestrator ----------------------
int rewireEpochChunk(var lambda, var mean, var energy, var power, int batch){
if(net.N <= 0) return 0;
if(batch < REWIRE_MIN_BATCH) batch = REWIRE_MIN_BATCH;
if(RewirePos >= net.N) RewirePos = 0;
int i0 = RewirePos;
int i1 = i0 + batch; if(i1 > net.N) i1 = net.N;
CandNeigh = ifelse(MH.Entropy < 0.45, CAND_NEIGH+4, CAND_NEIGH);
rewireAdjacency_DTREE_range(i0,i1, lambda,mean,energy,power);
net.sanitizeAdjacency();
synthesizeEquation_range(i0,i1, lambda,mean,energy,power);
buildSymbolicExpr_range(i0,i1);
RewirePos = i1;
if(RewirePos >= net.N){
RewirePos = 0;
RewirePasses++;
return 1;
}
return 0;
}
void rewireEpoch(var lambda, var mean, var energy, var power){
int done=0;
while(!done){
done = rewireEpochChunk(lambda,mean,energy,power, REWIRE_BATCH_EQ_H1);
}
net.normalizeProportions();
{
int D = net.D, i, total = net.N*D;
unsigned int h = 2166136261u;
for(i=0;i<total;i++){
unsigned int x = (unsigned int)net.Adj[i];
h ^= x + 0x9e3779b9u + (h<<6) + (h>>2);
}
CtxID = (int)((h ^ ((unsigned int)Epoch<<8)) & 0x7fffffff);
}
}
// ------------------- coarse net projection -> gamma -------------------
var projectNet(){
int i;
var sum=0,sumsq=0,cross=0;
for(i=0;i<net.N;i++){
sum += net.State[i];
sumsq += net.State[i]*net.State[i];
if(i+1<net.N) cross += net.State[i]*net.State[i+1];
}
var mean = sum/net.N;
var corr = cross/(net.N-1);
return 0.6*tanh(mean + 0.001*sumsq) + 0.4*sin(corr);
}
// ------------------- heavy update chunk (CUDA-batched) ----------------
var nonlin1(int i, int n1, var lam, var mean, var E, var P){
var x = net.State[n1];
var arg = (var)net.A1x[i]*x + (var)net.A1lam[i]*lam + (var)net.A1mean[i]*mean + (var)net.A1E[i]*E + (var)net.A1P[i]*P + (var)net.A1i[i]*i + (var)net.A1c[i];
return arg;
}
var nonlin2(int i, int n2, var lam, var mean, var E, var P){
var x = net.State[n2];
var arg = (var)net.A2x[i]*x + (var)net.A2lam[i]*lam + (var)net.A2mean[i]*mean + (var)net.A2E[i]*E + (var)net.A2P[i]*P + (var)net.A2i[i]*i + (var)net.A2c[i];
return arg;
}
int heavyUpdateChunk(var lambda, var mean, var energy, var power, int batch){
if(net.N <= 0) return 0;
if(batch < UPDATE_MIN_BATCH) batch = UPDATE_MIN_BATCH;
if(UpdatePos >= net.N) UpdatePos = 0;
int i0 = UpdatePos;
int i1 = i0 + batch; if(i1 > net.N) i1 = net.N;
net.computeProjection();
// ---- NEW: precompute advice for this chunk in ONE GPU call ----
if(CudaReady) {
computeAdviceBatchRange(i0, i1, lambda, mean, energy, power);
} else {
resetAdvCacheForBar();
}
int i;
for(i=i0;i<i1;i++){
int n1 = net.adjSafe(i,0);
int n2 = ifelse(net.D>=2, net.adjSafe(i,1), n1);
int topEq=-1; var topW=0;
var treeT = dtreeTerm(i, &topEq, &topW);
net.TreeTerm[i] = (fvar)treeT;
net.TopEq[i] = (i16)topEq;
net.TopW[i] = (fvar)topW;
// adviseEq now returns from cache (no GPU launch here)
var adv = adviseEq(i, lambda, mean, energy, power);
var a1 = nonlin1(i,n1,lambda,mean,energy,power);
var a2 = nonlin2(i,n2,lambda,mean,energy,power);
var t1,t2;
if(net.Mode[i]==1){ t1=tanh(a1); t2=sin(a2); }
else if(net.Mode[i]==2){ t1=cos(a1); t2=tanh(a2); }
else { t1=sin(a1); t2=cos(a2); }
var glob1 = tanh((var)net.G1mean[i]*mean + (var)net.G1E[i]*energy);
var glob2 = sin ((var)net.G2P[i]*power + (var)net.G2lam[i]*lambda);
var mom = (net.State[i] - net.Prev[i]);
var xnext =
(var)net.WSelf[i]*net.State[i]
+ (var)net.WN1[i]*t1
+ (var)net.WN2[i]*t2
+ (var)net.WGlob1[i]*glob1
+ (var)net.WGlob2[i]*glob2
+ (var)net.WMom[i]*mom
+ (var)net.WTree[i]*treeT
+ (var)net.WAdv[i]*adv;
xnext = clamp(xnext, -10., 10.);
net.Prev[i] = net.State[i];
net.State[i] = xnext;
net.StateSq[i] = xnext*xnext;
net.AdvPrev[i] = (fvar)adv;
// ---- logging block (unchanged) ----
if(!rt.LogsOff && (Bar % LOG_EVERY)==0 && (i < LOG_EQ_SAMPLE)){
int tid = dt.safeTreeIndexFromEq((int)net.EqTreeId[i], dt.TreeN);
Node* tnode = dt.treeAt(tid);
int nodeDepth = (tnode ? tnode->d : 0);
var rate = (var)net.TBeta[i];
var pred = dt.predByTid(tid);
string expr = 0;
if(LOG_EXPR_TEXT && net.Sym) expr = net.Sym[i];
log.appendEqMetaLine(Bar, Epoch, CtxID,
i, n1, n2, tid, nodeDepth, rate, pred, adv, net.Prop[i], (int)net.Mode[i],
(var)net.WAdv[i], (var)net.WTree[i], MH.PBullNext, MH.Entropy, (int)MH.Cur,
expr);
}
}
UpdatePos = i1;
if(UpdatePos >= net.N){
UpdatePos = 0;
UpdatePasses++;
return 1;
}
return 0;
}
// ------------------- hit-rate scorer (unchanged) ----------------------
void updateHitRates(){
if(is(INITRUN)) return;
if(Bar <= LookBack) return;
var r = net.Ret1;
var sgnR = sign(r);
int i;
for(i=0;i<net.N;i++){
var a = (var)net.AdvPrev[i];
var sgnA = ifelse(a > 0.0001, 1, ifelse(a < -0.0001, -1, 0));
var hit = ifelse(sgnR == 0, 0.5, ifelse(sgnA == sgnR, 1.0, 0.0));
net.HitEW[i] = (fvar)((1.0 - 0.02)*(var)net.HitEW[i] + 0.02*hit);
net.HitN[i] += 1;
}
}
// ------------------- blend lambda/gamma & accuracy --------------------
var blendLambdaGamma(var lambda_raw, var gamma_raw){
var w = clamp(FB_W + 0.15*(0.5 - MH.Entropy), 0.4, 0.9);
var x = w*lambda_raw + (1.0 - w)*gamma_raw;
rt.acc_update(lambda_raw, gamma_raw);
return x;
}
// ------------------- rewire scheduler (unchanged logic) ----------------
void maybeRewireNow(var lambda, var mean, var energy, var power){
int mb = mem_mb_est();
if(mb >= UPDATE_MEM_HARD) return;
int batch = ifelse(is_H1_close(), REWIRE_BATCH_EQ_H1, REWIRE_BATCH_EQ_5M);
if(mb >= REWIRE_MEM_SOFT) batch = (batch>>1);
if(batch < REWIRE_MIN_BATCH) batch = REWIRE_MIN_BATCH;
int finished = rewireEpochChunk(lambda,mean,energy,power,batch);
if(finished && (RewirePasses % REWIRE_NORM_EVERY) == 0){
net.normalizeProportions();
log.writeEqHeaderOnce();
if((RewirePasses % META_EVERY) == 0){
int D = net.D, i, total = net.N*D;
unsigned int h = 2166136261u;
for(i=0;i<total;i++){
unsigned int x = (unsigned int)net.Adj[i];
h ^= x + 0x9e3779b9u + (h<<6) + (h>>2);
}
CtxID = (int)((h ^ ((unsigned int)Epoch<<8)) & 0x7fffffff);
}
}
}
// ------------------- heavy update scheduler (unchanged) ---------------
void runHeavyUpdates(var lambda, var mean, var energy, var power){
int mb = mem_mb_est();
if(mb >= UPDATE_MEM_HARD) return;
int batch = ifelse(is_H1_close(), UPDATE_BATCH_EQ_H1, UPDATE_BATCH_EQ_5M);
if(mb >= UPDATE_MEM_SOFT) batch = (batch>>1);
if(batch < UPDATE_MIN_BATCH) batch = UPDATE_MIN_BATCH;
heavyUpdateChunk(lambda,mean,energy,power,batch);
}
// ------------------- main engine step (unchanged) ---------------------
void alpha12_step(var ret1_now){
if(!ready) return;
updateAllMarkov();
if(Bar < LookBack){
net.computeProjection();
net.Ret1 = ret1_now;
var h=0; int i;
for(i=0;i<net.N;i++) h += (var)net.HitEW[i];
if(net.N > 0) h /= (var)net.N; else h=0.5;
var target = MC_ACT + 0.15*(0.55 - h) + 0.10*(MH.Entropy - 0.5);
target = clamp(target, 0.20, 0.50);
MC_ACT_dyn = 0.95*MC_ACT_dyn + 0.05*target;
return;
}
net.computeProjection();
int Keff = net.keffClamped();
int k;
var e=0, pwr=0;
for(k=0;k<Keff;k++){ var z=(var)net.Z[k]; e+=z; pwr+=z*z; }
var mean=0, power=0;
if(Keff > 0){ mean = e/(var)Keff; power = pwr/(var)Keff; }
var energy = pwr;
var lambda = 0.7*tanh(mean) + 0.3*tanh(0.05*power);
maybeRewireNow(lambda,mean,energy,power);
runHeavyUpdates(lambda,mean,energy,power);
var gamma = projectNet();
var x = blendLambdaGamma(lambda,gamma);
(void)x;
dt.updateEquationCycle(net.Prop, net.N);
net.Ret1 = ret1_now;
updateHitRates();
int beforeDepth = rt.RT_TreeMaxDepth;
rt.depth_manager_runtime(dt);
if(rt.RT_TreeMaxDepth != beforeDepth){
reindexTreeAndMap();
}
{
var h=0; int i;
for(i=0;i<net.N;i++) h += (var)net.HitEW[i];
if(net.N > 0) h /= (var)net.N; else h=0.5;
var target = MC_ACT + 0.15*(0.55 - h) + 0.10*(MH.Entropy - 0.5);
target = clamp(target, 0.20, 0.50);
MC_ACT_dyn = 0.9*MC_ACT_dyn + 0.1*target;
}
}
// ------------------- realized 1-bar return (unchanged) ----------------
var realizedRet1(){
vars C = series(priceClose(0));
if(Bar <= LookBack) return 0;
return C[0] - C[1];
}
// ------------------- trading signal (unchanged) -----------------------
var tradeSignal(){
if(!ready) return 0;
if(!net.RP || !net.Z || !net.StateSq) return 0;
net.computeProjection();
int Keff = net.keffClamped();
if(Keff <= 0) return 0;
int k;
var e=0, pwr=0;
for(k=0;k<Keff;k++){ var z=(var)net.Z[k]; e+=z; pwr+=z*z; }
var mean=0, power=0;
if(Keff > 0){ mean = e/(var)Keff; power = pwr/(var)Keff; }
var lambda = 0.7*tanh(mean) + 0.3*tanh(0.05*power);
var gamma = projectNet();
var x = blendLambdaGamma(lambda,gamma);
LastSig = x;
var gLong=0, gShort=0;
if(MH.PBullNext >= PBULL_LONG_TH) gLong = 1.0;
if(MH.PBullNext <= PBULL_SHORT_TH) gShort= 1.0;
var s=0;
if(x > 0) s = x*gLong;
else s = x*gShort;
var conf = 1.0 - 0.5*(MR.Entropy);
s *= conf;
return clamp(s,-1.,1.);
}
// ------------------- position sizing & orders (unchanged) -------------
var posSizeFromSignal(var s){
var base = 1;
var scale = 2.0*abs(s);
return base * (0.5 + 0.5*scale);
}
void placeOrders(var s){
if(s > 0){
if(NumOpenShort) exitShort();
if(!NumOpenLong){
Lots = posSizeFromSignal(s);
enterLong();
}
} else if(s < 0){
if(NumOpenLong) exitLong();
if(!NumOpenShort){
Lots = posSizeFromSignal(s);
enterShort();
}
}
}
// ------------------- plotting guard -------------------
void plotSafe(string name, var v){
if(ENABLE_PLOTS && !rt.ChartsOff) plot(name, v, NEW|LINE, 0);
}
// ------------------- per-bar wrapper -------------------
void onBar(){
var r1 = realizedRet1();
alpha12_step(r1);
var s = tradeSignal();
placeOrders(s);
plotSafe("PBull(1H)", 100*(MH.PBullNext-0.5));
plotSafe("PBull(5M)", 100*(ML.PBullNext-0.5));
plotSafe("PBull(Rel)", 100*(MR.PBullNext-0.5));
plotSafe("Entropy(1H)", 100*(MH.Entropy));
plotSafe("Sig", 100*LastSig);
}
};
// ======================================================================
// ========================= Zorro DLL entry (bridge) ====================
DLLFUNC void run()
{
if(is(INITRUN)) {
if(!gAlpha12) gAlpha12 = new Alpha12Strategy();
gAlpha12->init();
}
if(!gAlpha12 || !gAlpha12->ready)
return;
// warmup behavior: keep Markov updated and projection alive
if(is(LOOKBACK) || Bar < LookBack) {
gAlpha12->updateAllMarkov();
gAlpha12->net.computeProjection();
return;
}
gAlpha12->onBar();
if(is(EXITRUN)) {
gAlpha12->cleanup();
delete gAlpha12;
gAlpha12 = nullptr;
}
}