#define PAIRS 28 // Number of currency pairs
string CurrencyPairs[PAIRS] = {
"EURUSD", "GBPUSD", "USDJPY", "GBPJPY", "USDCAD", "EURAUD", "EURJPY",
"AUDCAD", "AUDJPY", "AUDNZD", "AUDUSD", "CADJPY", "EURCAD", "EURCHF",
"EURGBP", "EURNZD", "GBPCAD", "GBPCHF", "NZDCAD", "NZDJPY", "NZDUSD",
"USDCHF", "CHFJPY", "AUDCHF", "GBPNZD", "NZDCHF", "CADCHF", "GBPAUD"
};
vars ProfitMatrix[PAIRS][PAIRS]; // Edge weights (profitability)
int Previous[PAIRS]; // Stores the previous node in the path
vars PathProfit[PAIRS]; // Stores cumulative profit along the path
vars DynamicDeltaThreshold; // Dynamic threshold to execute trades
// Function to calculate profitability matrix
function calculateProfitMatrix() {
for (int i = 0; i < PAIRS; i++) {
for (int j = 0; j < PAIRS; j++) {
if (i != j) {
var priceRatio = price(CurrencyPairs[i]) / price(CurrencyPairs[j]);
ProfitMatrix[i][j] = log(priceRatio); // Logarithmic profitability
} else {
ProfitMatrix[i][j] = 0; // No self-loop
}
}
}
}
// Calculate the Dynamic Delta Threshold with risk-adjustment and feedback
function calculateDynamicDeltaThreshold() {
var totalRiskAdjustedProfit = 0;
int count = 0;
for (int i = 0; i < PAIRS; i++) {
for (int j = 0; j < PAIRS; j++) {
if (i != j && ProfitMatrix[i][j] > 0) {
var volatility = StdDev(series(price(CurrencyPairs[i])), 50); // 50-period volatility
var riskAdjustedProfit = ProfitMatrix[i][j] / volatility; // Risk-adjusted profit
totalRiskAdjustedProfit += riskAdjustedProfit;
count++;
}
}
}
if (count > 0) {
var baselineThreshold = totalRiskAdjustedProfit / count; // Average risk-adjusted profit
var performanceFactor = Equity / MaxEquity; // Performance feedback
DynamicDeltaThreshold = baselineThreshold * performanceFactor; // Adjust threshold dynamically
} else {
DynamicDeltaThreshold = 0.001; // Default fallback
}
// Log the threshold for backtesting and analysis
printf("DynamicDeltaThreshold: %.6f\n", DynamicDeltaThreshold);
}
// Bellman-Ford algorithm to find paths with the highest cumulative profit
function bellmanFord(int start) {
for (int i = 0; i < PAIRS; i++) {
PathProfit[i] = -1e10; // Negative infinity for unvisited nodes
Previous[i] = -1; // No predecessor
}
PathProfit[start] = 0; // Profit starts at 0 from the source
for (int k = 0; k < PAIRS - 1; k++) {
for (int i = 0; i < PAIRS; i++) {
for (int j = 0; j < PAIRS; j++) {
if (ProfitMatrix[i][j] != 0 && PathProfit[i] + ProfitMatrix[i][j] > PathProfit[j]) {
PathProfit[j] = PathProfit[i] + ProfitMatrix[i][j]; // Update cumulative profit
Previous[j] = i; // Track the path
}
}
}
}
}
// Execute trades along the highest cumulative profit path
function executePath(int start, int end) {
int current = end;
while (current != -1) {
int previous = Previous[current];
if (previous == -1) break;
if (ProfitMatrix[previous][current] > 0) {
enterLong(CurrencyPairs[previous]);
enterShort(CurrencyPairs[current]);
} else {
enterShort(CurrencyPairs[previous]);
enterLong(CurrencyPairs[current]);
}
current = previous;
}
}
// Continuously execute trades while conditions exist
function executeContinuousTrades(int start) {
while (1) {
calculateProfitMatrix(); // Update the graph with live data
calculateDynamicDeltaThreshold(); // Adjust the threshold dynamically
bellmanFord(start); // Recalculate paths with the highest cumulative profit
for (int i = 0; i < PAIRS; i++) {
for (int j = 0; j < PAIRS; j++) {
if (i != j && ProfitMatrix[i][j] > DynamicDeltaThreshold) {
enterLong(CurrencyPairs[i]);
enterShort(CurrencyPairs[j]);
printf("Executing Trade: Long %s, Short %s\n", CurrencyPairs[i], CurrencyPairs[j]);
}
}
}
// Add a condition to exit the loop for backtesting or analysis
if (isBacktest() && getBacktestPeriod() == "End") {
break;
}
}
}
// Main trading function
function run() {
set(PLOTNOW);
int startPair = 0; // Start from the first currency pair
executeContinuousTrades(startPair);
}