// TGr01.cpp - Zorro64 Strategy DLL (C++) - Markov Graph Wiener-like Index demo
#include <zorro.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define INF 1e30
struct Graph {
int n;
double* d;
};
static int Graph_pos(const Graph* g, int r, int c) { return r*g->n + c; }
static Graph* Graph_create(int n) {
Graph* g = (Graph*)malloc(sizeof(Graph));
if(!g) return 0;
g->n = n;
g->d = (double*)malloc(n*n*sizeof(double));
if(!g->d) { free(g); return 0; }
return g;
}
static void Graph_destroy(Graph* g) {
if(!g) return;
if(g->d) free(g->d);
free(g);
}
static void Graph_reset(Graph* g) {
for(int r=0; r<g->n; r++)
for(int c=0; c<g->n; c++)
g->d[Graph_pos(g,r,c)] = (r==c) ? 0.0 : INF;
}
static double probToDist(double p) {
if(p <= 0.0) return INF;
if(p > 1.0) p = 1.0;
return -log(p);
}
static void Graph_linkProb(Graph* g, int i, int j, double p) {
g->d[Graph_pos(g,i,j)] = probToDist(p);
}
static void Graph_allPairsShortest(Graph* g) {
for(int k=0; k<g->n; k++)
for(int i=0; i<g->n; i++)
for(int j=0; j<g->n; j++) {
int ij = Graph_pos(g,i,j);
int ik = Graph_pos(g,i,k);
int kj = Graph_pos(g,k,j);
double cand = g->d[ik] + g->d[kj];
if(cand < g->d[ij]) g->d[ij] = cand;
}
}
static double Graph_wienerUndirectedLike(const Graph* g) {
double W = 0.0;
for(int i=0; i<g->n; i++)
for(int j=i+1; j<g->n; j++) {
double dij = g->d[Graph_pos(g,i,j)];
double dji = g->d[Graph_pos(g,j,i)];
W += 0.5*(dij + dji);
}
return W;
}
static void Graph_dump(const Graph* g, const char* title) {
printf("\n%s", title);
for(int r=0; r<g->n; r++) {
printf("\n");
for(int c=0; c<g->n; c++) {
double v = g->d[Graph_pos(g,r,c)];
if(v > 1e20) printf(" INF ");
else printf("%5.2f ", v);
}
}
}
static void buildDirectional(Graph* g) {
Graph_reset(g);
Graph_linkProb(g,0,0,0.65); Graph_linkProb(g,0,1,0.30); Graph_linkProb(g,0,2,0.04); Graph_linkProb(g,0,3,0.01);
Graph_linkProb(g,1,0,0.25); Graph_linkProb(g,1,1,0.60); Graph_linkProb(g,1,2,0.12); Graph_linkProb(g,1,3,0.03);
Graph_linkProb(g,2,0,0.03); Graph_linkProb(g,2,1,0.12); Graph_linkProb(g,2,2,0.60); Graph_linkProb(g,2,3,0.25);
Graph_linkProb(g,3,0,0.01); Graph_linkProb(g,3,1,0.04); Graph_linkProb(g,3,2,0.30); Graph_linkProb(g,3,3,0.65);
}
static void buildChoppy(Graph* g) {
Graph_reset(g);
Graph_linkProb(g,0,0,0.28); Graph_linkProb(g,0,1,0.24); Graph_linkProb(g,0,2,0.25); Graph_linkProb(g,0,3,0.23);
Graph_linkProb(g,1,0,0.23); Graph_linkProb(g,1,1,0.27); Graph_linkProb(g,1,2,0.26); Graph_linkProb(g,1,3,0.24);
Graph_linkProb(g,2,0,0.24); Graph_linkProb(g,2,1,0.26); Graph_linkProb(g,2,2,0.27); Graph_linkProb(g,2,3,0.23);
Graph_linkProb(g,3,0,0.25); Graph_linkProb(g,3,1,0.23); Graph_linkProb(g,3,2,0.24); Graph_linkProb(g,3,3,0.28);
}
static void printRiskSwitch(double Wdir, double Wchop, double Wnow) {
double thr = 0.5*(Wdir + Wchop);
printf("\n\nRisk switch example:");
printf("\nDirectional W = %.3f", Wdir);
printf("\nChoppy W = %.3f", Wchop);
printf("\nThreshold W = %.3f", thr);
printf("\nCurrent W = %.3f", Wnow);
if(Wnow <= thr)
printf("\nDecision: COMPACT regime -> higher risk / trend bias.");
else
printf("\nDecision: DIFFUSE regime -> reduce risk / mean-revert or flat.");
}
static int doMain()
{
const int STATES = 4;
Graph* Gdir = Graph_create(STATES);
if(!Gdir) { printf("\nOOM creating directional graph"); return 1; }
buildDirectional(Gdir);
Graph_allPairsShortest(Gdir);
double Wdir = Graph_wienerUndirectedLike(Gdir);
Graph* Gch = Graph_create(STATES);
if(!Gch) { printf("\nOOM creating choppy graph"); Graph_destroy(Gdir); return 1; }
buildChoppy(Gch);
Graph_allPairsShortest(Gch);
double Wchop = Graph_wienerUndirectedLike(Gch);
double Wnow = Wchop; // demo choice
Graph_dump(Gdir, "\nDirectional graph shortest distances (-log p) after Floyd:");
printf("\n\nWiener-like index (directional) = %.3f\n", Wdir);
Graph_dump(Gch, "\nChoppy graph shortest distances (-log p) after Floyd:");
printf("\n\nWiener-like index (choppy) = %.3f\n", Wchop);
printRiskSwitch(Wdir, Wchop, Wnow);
Graph_destroy(Gdir);
Graph_destroy(Gch);
return 0;
}
// Zorro DLL entry point
DLLFUNC void run()
{
if(is(INITRUN)) {
doMain();
quit("Done.");
}
}