|
2 registered members (Petra, 1 invisible),
6,118
guests, and 2
spiders. |
|
Key:
Admin,
Global Mod,
Mod
|
|
|
Decision Making Graph Geometry
[Re: TipmyPip]
#489205
Yesterday at 19:15
Yesterday at 19:15
|
Joined: Sep 2017
Posts: 207
TipmyPip
OP
Member
|
OP
Member
Joined: Sep 2017
Posts: 207
|
This strategy is an abstract example of decision-making from coupled graph geometry. It models the market using two different weighted graphs that represent two distinct kinds of structure: 1) A regime dynamics graph (Graph A)Graph A represents the market as a finite set of latent regimes (states). A directed edge from state ???? to state ???? encodes the likelihood that the market transitions from ???? to ????. Probabilities ???????????? are converted into edge “lengths” using an information-geometric map: wij =?log(pij) This turns the transition system into a metric-like space where likely transitions are short and unlikely transitions are long. Once edge lengths are defined, Floyd–Warshall computes shortest path distances between all state pairs, allowing indirect multi-step transitions to determine effective connectivity. The strategy then summarizes the global geometry of the regime space using a Wiener-like index—the sum of distances across all unordered state pairs. Conceptually, this measures whether the regime system is compact (states are mutually reachable through short, high-probability pathways) or diffuse (states are separated by long or improbable paths). A compact regime graph corresponds to more orderly, predictable evolution; a diffuse one corresponds to fragmented, noisy evolution. 2) An asset coupling graph (Graph B) Graph B represents relationships among assets as an undirected weighted graph. Here, edge weights are derived from correlation: wij ?=1?? corrij ?? Strongly correlated assets are “close” (small distance), while weakly related assets are “far.” Again, shortest paths produce an effective distance structure, and a Wiener-like sum over all asset pairs becomes a scalar measure of system-wide coupling. Low Wiener (tight graph) means assets behave as a single cluster—diversification is weak, and portfolio risk concentrates. Higher Wiener implies more separation and potentially better diversification. 3) Coupling the graphs into a single control variable The strategy’s mathematical core is a coupling rule that treats: Regime compactness as a proxy for signal quality / predictability, and Asset coupling as a proxy for systemic risk / lack of diversification. It combines them through a logistic squashing function: Score=?(??Compactness(StateGraph)???Coupling(AssetGraph)) The sigmoid ?(?) maps the result into [0,1], producing a risk throttle. Abstractly, the throttle increases when the regime space is geometrically “tight” (predictable transitions) and decreases when the asset space is geometrically “tight” (high correlation concentration). The outcome is not a specific entry/exit rule, but a mathematically grounded allocator: a mechanism that scales risk based on two interacting notions of structure—temporal structure in regime evolution and cross-sectional structure in asset dependence. In short, the code demonstrates how global graph metrics (via shortest-path geometry and Wiener-like sums) can be used as compact, interpretable features to modulate trading aggressiveness in a principled, system-level way. // TGr05.cpp - Zorro64 Strategy DLL (C++) - Two coupled graphs for algo trading
#include <zorro.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define INF 1e30
// =============================== Graph (OO) ===============================
class WeightedGraph {
public:
int n = 0;
double* d = 0; // adjacency/shortest-path matrix (n*n)
WeightedGraph(int N) { init(N); }
~WeightedGraph() { shutdown(); }
void init(int N) {
shutdown();
n = N;
d = (double*)malloc((size_t)n*(size_t)n*sizeof(double));
if(!d) quit("OOM: WeightedGraph matrix");
reset();
}
void shutdown() {
if(d) free(d);
d = 0;
n = 0;
}
inline int pos(int r,int c) const { return r*n + c; }
void reset() {
for(int r=0;r<n;r++)
for(int c=0;c<n;c++)
d[pos(r,c)] = (r==c) ? 0.0 : INF;
}
// Floyd-Warshall shortest paths
void allPairsShortest() {
for(int k=0;k<n;k++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++) {
double cand = d[pos(i,k)] + d[pos(k,j)];
if(cand < d[pos(i,j)]) d[pos(i,j)] = cand;
}
}
// Wiener-like sum over unordered pairs (symmetrized)
double wienerUndirectedLike() const {
double W = 0.0;
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++) {
double dij = d[pos(i,j)];
double dji = d[pos(j,i)];
W += 0.5*(dij + dji);
}
return W;
}
void dump(const char* title) const {
printf("\n%s", title);
for(int r=0;r<n;r++) {
printf("\n");
for(int c=0;c<n;c++) {
double v = d[pos(r,c)];
if(v > 1e20) printf(" INF ");
else printf("%5.2f ", v);
}
}
}
};
// ========================== Graph A: Markov State Graph ===================
// Edge weight = -log(p_ij) (probability -> distance)
class RegimeMarkovGraph {
public:
WeightedGraph G;
RegimeMarkovGraph(int states) : G(states) {}
static double probToDist(double p) {
if(p <= 0.0) return INF;
if(p > 1.0) p = 1.0;
return -log(p);
}
void setTransitionProb(int i,int j,double p) {
G.d[G.pos(i,j)] = probToDist(p);
}
// Example presets: directional vs choppy (toy)
void buildDirectional4() {
G.reset();
setTransitionProb(0,0,0.65); setTransitionProb(0,1,0.30); setTransitionProb(0,2,0.04); setTransitionProb(0,3,0.01);
setTransitionProb(1,0,0.25); setTransitionProb(1,1,0.60); setTransitionProb(1,2,0.12); setTransitionProb(1,3,0.03);
setTransitionProb(2,0,0.03); setTransitionProb(2,1,0.12); setTransitionProb(2,2,0.60); setTransitionProb(2,3,0.25);
setTransitionProb(3,0,0.01); setTransitionProb(3,1,0.04); setTransitionProb(3,2,0.30); setTransitionProb(3,3,0.65);
}
void buildChoppy4() {
G.reset();
setTransitionProb(0,0,0.28); setTransitionProb(0,1,0.24); setTransitionProb(0,2,0.25); setTransitionProb(0,3,0.23);
setTransitionProb(1,0,0.23); setTransitionProb(1,1,0.27); setTransitionProb(1,2,0.26); setTransitionProb(1,3,0.24);
setTransitionProb(2,0,0.24); setTransitionProb(2,1,0.26); setTransitionProb(2,2,0.27); setTransitionProb(2,3,0.23);
setTransitionProb(3,0,0.25); setTransitionProb(3,1,0.23); setTransitionProb(3,2,0.24); setTransitionProb(3,3,0.28);
}
// Compactness: lower Wiener => more compact; convert to a score in [0,1]
double compactnessScore() {
G.allPairsShortest();
double W = G.wienerUndirectedLike();
// simple squash: smaller W => larger score
return 1.0/(1.0 + W);
}
};
// ========================== Graph B: Asset Relationship Graph =============
// Edge weight = 1 - |corr| (strong corr => short distance)
class AssetCorrelationGraph {
public:
WeightedGraph G;
AssetCorrelationGraph(int assets) : G(assets) {}
static double corrToDist(double corr) {
double a = fabs(corr);
if(a > 1.0) a = 1.0;
return 1.0 - a; // in [0,1]
}
void setCorr(int i,int j,double corr) {
double w = corrToDist(corr);
G.d[G.pos(i,j)] = w;
G.d[G.pos(j,i)] = w;
}
// Example 3-asset correlation structure (toy)
// 0=EUR/USD, 1=GBP/USD, 2=USD/JPY
void buildToyFX() {
G.reset();
// self already 0
setCorr(0,1,0.85); // EURUSD ~ GBPUSD high positive corr -> short distance
setCorr(0,2,-0.30); // EURUSD vs USDJPY mild negative -> larger distance
setCorr(1,2,-0.25); // GBPUSD vs USDJPY mild negative
}
// Coupling: lower Wiener => assets tightly coupled; convert to risk penalty in [0,1]
double couplingPenalty() {
G.allPairsShortest();
double W = G.wienerUndirectedLike();
// smaller W => higher coupling => higher penalty; invert & squash
return 1.0/(1.0 + W);
}
};
// ========================== Strategy: Coupled Two-Graph Logic =============
class TwoGraphStrategy {
public:
// Hyperparameters
double alpha = 2.0; // weight for regime compactness
double beta = 1.5; // weight for asset coupling penalty
double baseRisk = 1.0;
// Graphs
RegimeMarkovGraph RG;
AssetCorrelationGraph AG;
TwoGraphStrategy() : RG(4), AG(3) {}
static double sigmoid(double x) {
// stable-ish sigmoid
if(x > 30) return 1.0;
if(x < -30) return 0.0;
return 1.0/(1.0 + exp(-x));
}
// In a real system:
// - RG transitions come from online Markov counts over price-action states
// - AG correlations come from rolling returns correlations of assets
// Here: toy graphs to demonstrate the coupling logic.
void buildToyInputs(int useDirectional) {
if(useDirectional) RG.buildDirectional4();
else RG.buildChoppy4();
AG.buildToyFX();
}
// Coupling between two graphs in "mathematical context":
// we treat RG.compactness as signal quality and AG.coupling as diversification risk.
double riskThrottle() {
double comp = RG.compactnessScore(); // higher = better / more predictable
double coup = AG.couplingPenalty(); // higher = more coupled / more dangerous
// combined score -> throttle in [0,1]
double x = alpha*comp - beta*coup;
return sigmoid(x);
}
void explain(double thr) {
printf("\n\n[TwoGraph] Regime compactness score = %.4f", RG.compactnessScore());
printf("\n[TwoGraph] Asset coupling penalty = %.4f", AG.couplingPenalty());
printf("\n[TwoGraph] Risk throttle (0..1) = %.4f", thr);
printf("\n[TwoGraph] Suggested Lots scale = %.3f", baseRisk * (0.25 + 0.75*thr));
}
// Demo run: compare two regimes (directional vs choppy) under same asset coupling
void demo() {
// Case A: directional
buildToyInputs(1);
double thrA = riskThrottle();
printf("\n=== CASE A: Directional regime ===");
RG.G.dump("\nRegime graph shortest distances:");
AG.G.dump("\nAsset graph shortest distances:");
explain(thrA);
// Case B: choppy
buildToyInputs(0);
double thrB = riskThrottle();
printf("\n\n=== CASE B: Choppy regime ===");
RG.G.dump("\nRegime graph shortest distances:");
AG.G.dump("\nAsset graph shortest distances:");
explain(thrB);
printf("\n\nInterpretation:");
printf("\n- If regime transitions are compact (predictable), throttle increases.");
printf("\n- If assets are tightly coupled (low diversification), throttle decreases.");
printf("\n- The trading engine can use throttle to scale order size / aggression.");
}
};
// =============================== Entry ===================================
static TwoGraphStrategy* S = 0;
DLLFUNC void run()
{
if(is(INITRUN))
{
if(!S) S = new TwoGraphStrategy();
S->demo();
quit("Done.");
}
}
Last edited by TipmyPip; Yesterday at 20:08.
|
|
|
|