void buildFeatLinear() { int idx = 0; for(int f=0; f<FEAT_N; f++){ for(int a=0; a<N_ASSETS; a++){ for(int t=0; t<FEAT_WINDOW; t++){ featLinear[idx] = (float)featSoA.get(f, a, t); idx++; } } } } void computeCorrelationMatrix() { if(openCL.ready) { buildFeatLinear(); for(int i=0;i<N_ASSETS*N_ASSETS;i++) corrLinear[i] = 0.0f; int ok = openCL.computeCorrelationMatrixCL( featLinear.data, corrLinear.data, N_ASSETS, FEAT_N, FEAT_WINDOW ); if(ok) { for(int i=0;i<N_ASSETS*N_ASSETS;i++) corrMatrix[i] = (fvar)0; for(int a=0; a<N_ASSETS; a++){ corrMatrix[a*N_ASSETS + a] = (fvar)1.0; for(int b=a+1; b<N_ASSETS; b++){ float c = corrLinear[a*N_ASSETS + b]; corrMatrix[a*N_ASSETS + b] = (fvar)c; corrMatrix[b*N_ASSETS + a] = (fvar)c; } } return; } printf("OpenCL: runtime fail -> CPU fallback\n"); openCL.ready = 0; } computeCorrelationMatrixCPU(); } void computeDistanceMatrix() { for(int i=0;i<N_ASSETS;i++){ for(int j=0;j<N_ASSETS;j++){ if(i == j) { distMatrix[i*N_ASSETS + j] = (fvar)0; } else { fvar corrDist = (fvar)1.0 - (fvar)fabs((double)corrMatrix[i*N_ASSETS + j]); fvar expDist = (fvar)exposureTable.getDist(i, j); fvar blended = (fvar)LAMBDA_META * corrDist + (fvar)(1.0 - (double)LAMBDA_META) * expDist; distMatrix[i*N_ASSETS + j] = blended; } } } } void floydWarshall() { fvar d[28][28]; for(int i=0;i<N_ASSETS;i++){ for(int j=0;j<N_ASSETS;j++){ d[i][j] = distMatrix[i*N_ASSETS + j]; if(i == j) d[i][j] = (fvar)0; if(d[i][j] < (fvar)0) d[i][j] = (fvar)INF; } } for(int k=0;k<N_ASSETS;k++){ for(int i=0;i<N_ASSETS;i++){ for(int j=0;j<N_ASSETS;j++){ if(d[i][k] < (fvar)INF && d[k][j] < (fvar)INF) { fvar nk = d[i][k] + d[k][j]; if(nk < d[i][j]) d[i][j] = nk; } } } } for(int i=0;i<N_ASSETS;i++){ fvar w = 0; for(int j=i+1;j<N_ASSETS;j++){ if(d[i][j] < (fvar)INF) w += d[i][j]; } if(w > (fvar)0) compactness[i] = (fvar)(1.0 / (1.0 + (double)w)); else compactness[i] = (fvar)0; } } void computeScores() { for(int i=0;i<N_ASSETS;i++){ fvar coupling = 0; int count = 0; for(int j=0;j<N_ASSETS;j++){ if(i != j && distMatrix[i*N_ASSETS + j] < (fvar)INF) { coupling += compactness[j]; count++; } } fvar pCouple = 0; if(count > 0) pCouple = coupling / (fvar)count; else pCouple = (fvar)0; fvar regime = featSoA.get(6, i, 0); fvar rawScore = (fvar)ALPHA * regime + (fvar)GAMMA * compactness[i] - (fvar)BETA * pCouple; if(rawScore > (fvar)30) rawScore = (fvar)30; if(rawScore < (fvar)-30) rawScore = (fvar)-30; scores[i] = (fvar)(1.0 / (1.0 + exp(-(double)rawScore))); } } LearningSnapshot buildSnapshot() { LearningSnapshot s; s.meanScore = 0; s.meanCompactness = 0; s.meanVol = 0; for(int i=0;i<N_ASSETS;i++) { s.meanScore += (double)scores[i]; s.meanCompactness += (double)compactness[i]; s.meanVol += (double)featSoA.get(2, i, 0); } s.meanScore /= (double)N_ASSETS; s.meanCompactness /= (double)N_ASSETS; s.meanVol /= (double)N_ASSETS; s.regime = 0; s.regimeConfidence = 0; return s; } void onBar() { barCount++; for(int i=0;i<N_ASSETS;i++) computeFeatures(i); if(barCount % UPDATE_EVERY == 0) { updateCount++; computeCorrelationMatrix(); computeDistanceMatrix(); #if USE_COMMUNITY hclust.update(distMatrix.data); #endif #if USE_COMMUNITY comm.update(corrMatrix.data, distMatrix.data); #endif floydWarshall(); computeScores(); controller.onUpdate(buildSnapshot(), scores.data, N_ASSETS, updateCount); #if USE_AE double aeState[AE_INPUT_DIM]; double ms=0, mc=0, mv=0; for(int i=0;i<N_ASSETS;i++){ ms += (double)scores[i]; mc += (double)compactness[i]; mv += (double)featSoA.get(2, i, 0); } ms /= (double)N_ASSETS; mc /= (double)N_ASSETS; mv /= (double)N_ASSETS; aeState[0] = ms; aeState[1] = mc; aeState[2] = mv; aeState[3] = controller.scoreScale; aeState[4] = (double)controller.dynamicTopK; aeState[5] = (double)barCount / (double)(LookBack + 1); aeState[6] = (double)updateCount / 1000.0; aeState[7] = (double)openCL.ready; double reconErr = ae.infer(aeState); novelty.update(reconErr); novelty.apply(&controller.dynamicTopK, &controller.scoreScale); for(int i=0;i<N_ASSETS;i++){{ double s = (double)scores[i] * novelty.riskScale; if(s > 1.0) s = 1.0; if(s < 0.0) s = 0.0; scores[i] = (fvar)s; }} #endif printTopK(); } } void printTopK() { int indices[N_ASSETS]; for(int i=0;i<N_ASSETS;i++) indices[i] = i; int topN = controller.dynamicTopK; #if USE_COMMUNITY if(comm.qSmooth < (fvar)COMM_Q_LOW && topN > 2) topN--; if(comm.qSmooth > (fvar)COMM_Q_HIGH && topN < TOP_K) topN++; #endif for(int i=0;i<topN;i++){ for(int j=i+1;j<N_ASSETS;j++){ if(scores[indices[j]] > scores[indices[i]]) { int tmp = indices[i]; indices[i] = indices[j]; indices[j] = tmp; } } } if(updateCount % 10 == 0) { printf("===CompactDominant_v13 Top-K(update#%d,OpenCL=%d)===\n", updateCount, openCL.ready); #if USE_COMMUNITY printf(" communities=%d Q=%.4f\n", comm.nCommunities, (double)comm.qSmooth); #endif int selected[N_ASSETS]; int selCount = 0; #if USE_COMMUNITY int coarseUsed[HCLUST_COARSE_K]; int fineTake[HCLUST_FINE_K]; int fineCap = (topN + HCLUST_FINE_K - 1) / HCLUST_FINE_K; for(int c=0;c<HCLUST_COARSE_K;c++) coarseUsed[c] = 0; for(int c=0;c<HCLUST_FINE_K;c++) fineTake[c] = 0; for(int i=0;i<topN;i++){ int idx = indices[i]; int cid = comm.clusterCoarse[idx]; if(cid < 0 || cid >= HCLUST_COARSE_K) cid = 0; if(coarseUsed[cid]) continue; coarseUsed[cid] = 1; selected[selCount++] = idx; int fid = comm.clusterFine[idx]; if(fid < 0 || fid >= HCLUST_FINE_K) fid = 0; fineTake[fid]++; } for(int i=0;i<topN && selCount<topN;i++){ int idx = indices[i]; int dup = 0; for(int k=0;k<selCount;k++) if(selected[k]==idx){ dup=1; break; } if(dup) continue; int fid = comm.clusterFine[idx]; if(fid < 0 || fid >= HCLUST_FINE_K) fid = 0; if(fineTake[fid] >= fineCap) continue; selected[selCount++] = idx; fineTake[fid]++; } #else for(int i=0;i<topN;i++) selected[selCount++] = indices[i]; #endif for(int i=0;i<selCount;i++){ int idx = selected[i]; printf(" %d.%s: score=%.4f, C=%.4f\n", i+1, ASSET_NAMES[idx], (double)scores[idx], (double)compactness[idx]); } } } }; // ---------------------------- Zorro DLL entry ---------------------------- static CompactDominantStrategy* S = NULL; DLLFUNC void run() { if(is(INITRUN)) { BarPeriod = 60; LookBack = max(LookBack, FEAT_WINDOW + 50); asset((char*)ASSET_NAMES[0]); if(!S) { S = new CompactDominantStrategy(); S->init(); } } if(is(EXITRUN)) { if(S) { S->shutdown(); delete S; S = NULL; } return; } if(!S || Bar < LookBack) return; S->onBar(); }