OP
Member
Joined: Sep 2017
Posts: 164
|
The War BeginsRecursive Market Maker Algorithm in Algorithmic Trading In an algorithmic trading system, we need to design a market maker algorithm that balances liquidity provision and adversarial trading risk. The algorithm must predict optimal bid/ask spreads while ensuring resilience to adverse selection. We define: A recursive graph-based order book model, where orders form a tree of limit order dependencies. A recursive game-theoretic strategy, where the market maker competes against adversarial high-frequency traders (HFTs). Each function depends on the other recursively, making an iterative solution nearly impossible. Graph Theory Component: Recursive Order Book Graph We define an order book as a directed graph, where: Nodes represent limit orders. Edges represent dependencies (e.g., order A at $100 depends on order B at $99). The graph grows recursively, as new limit orders are placed based on past orders. Function 1: Recursive Order Book Growth typedef struct Order {
double price;
int size;
double spread;
int parentIndex;
} Order;
void addOrder(Order* orderBook, int index, double price, int size, int totalOrders) {
if (index >= totalOrders) return;
price = randomizePrice(price + random() * 5, VOLATILITY * (0.8 + random() * 0.6));
size = generateOrderSize(MAX_ORDER_SIZE);
double spread = clamp(0.007 + random() * 0.025, 0.007, 0.04); // Spread cannot be negative
orderBook[index].price = price;
orderBook[index].size = size;
orderBook[index].spread = spread;
if (index > 0)
orderBook[index].parentIndex = index - 1;
else
orderBook[index].parentIndex = -1;
print(TO_LOG, " Order Added: Index %d | Price: %.4f | Size: %d | Spread: %.5f", index, price, size, spread);
if (random() < 0.75 && index + 1 < totalOrders) {
int newSize = generateOrderSize(size * (0.8 + random() * 0.3));
addOrder(orderBook, index + 1, price - 0.01 * randomInt(1, 12), newSize, totalOrders);
}
} Game Theory Component: Recursive Market Maker Pricing Now, we must determine optimal bid/ask spreads to balance market efficiency and profitability. A recursive game-theoretic function models how: The market maker sets spreads recursively. HFTs attack weak spreads by executing trades that maximize adverse selection. Function 2: Recursive Bid/Ask Adjustment Based on Game Theory double calculateSpread(Order* orderBook, int index) {
if (index < 0 || index >= MAX_ORDERS) return 0.007; // Prevent invalid indices
double baseSpread = clamp(0.007 + random() * 0.02, 0.007, 0.04);
double hftPressure = ifelse(random() < 0.5, 0.002 + (random() - 0.5) * 0.005, 0.001);
double volatilityFactor = (random() - 0.5) * 0.03;
double spread = baseSpread + (0.025 - orderBook[index].price * 0.0003) - hftPressure + volatilityFactor;
return clamp(spread, 0.007, 0.04);
} 3. Entanglement Between Recursions Now, the recursive order book structure directly affects the recursive pricing strategy: More orders in the book → tighter spreads (more liquidity). HFT attacks → wider spreads (risk mitigation). Spreads impact future orders, creating a recursive feedback loop. Final Algorithm: Recursive Market Maker Strategy. void addOrder(Order* orderBook, int index, double price, int size, int totalOrders) {
if (index >= totalOrders) return;
price = randomizePrice(price + random() * 5, VOLATILITY * (0.8 + random() * 0.6));
size = generateOrderSize(MAX_ORDER_SIZE);
double spread = clamp(0.007 + random() * 0.025, 0.007, 0.04); // Spread cannot be negative
orderBook[index].price = price;
orderBook[index].size = size;
orderBook[index].spread = spread;
if (index > 0)
orderBook[index].parentIndex = index - 1;
else
orderBook[index].parentIndex = -1;
print(TO_LOG, " Order Added: Index %d | Price: %.4f | Size: %d | Spread: %.5f", index, price, size, spread);
if (random() < 0.75 && index + 1 < totalOrders) {
int newSize = generateOrderSize(size * (0.8 + random() * 0.3));
addOrder(orderBook, index + 1, price - 0.01 * randomInt(1, 12), newSize, totalOrders);
}
} Here is a working code, but anyone who wants to improve the simulator, please do, share your suggestions please, thank you. #define MIN_ORDERS 5
#define MAX_ORDERS 15
#define MIN_ORDER_SIZE 5
#define MAX_ORDER_SIZE 100
#define VOLATILITY 0.09 // Slightly increased to ensure better price fluctuations
#define MAX_DEPTH 10
void initializeRandomSeed() {
seed(random() * timer());
}
int randomInt(int min, int max) {
return clamp(min + (int)((max - min + 1) * random()), min, max);
}
double clamp(double x, double min, double max) {
return ifelse(x < min, min, ifelse(x > max, max, x));
}
// Ensures Order Sizes Are Always in a Valid Range
int generateOrderSize(int maxSize) {
double randFactor = random();
int size = MIN_ORDER_SIZE + (int)((randFactor * randFactor * (maxSize - MIN_ORDER_SIZE)) * (0.9 + random() * 0.5));
return clamp(size, MIN_ORDER_SIZE, MAX_ORDER_SIZE);
}
// Fully Randomized Order Prices Within a Safe Range
double randomizePrice(double baseValue, double volatility) {
double direction = ifelse(random() < 0.5, -1, 1);
double priceChange = direction * (random() * volatility * 18 + random() * 12);
double newPrice = baseValue + priceChange;
return clamp(newPrice, 50, 200);
}
typedef struct Order {
double price;
int size;
double spread;
int parentIndex;
} Order;
// Ensures Safe Order Creation with Valid Values
void addOrder(Order* orderBook, int index, double price, int size, int totalOrders) {
if (index >= totalOrders) return;
price = randomizePrice(price + random() * 5, VOLATILITY * (0.8 + random() * 0.6));
size = generateOrderSize(MAX_ORDER_SIZE);
double spread = clamp(0.007 + random() * 0.025, 0.007, 0.04); // Spread cannot be negative
orderBook[index].price = price;
orderBook[index].size = size;
orderBook[index].spread = spread;
if (index > 0)
orderBook[index].parentIndex = index - 1;
else
orderBook[index].parentIndex = -1;
print(TO_LOG, " Order Added: Index %d | Price: %.4f | Size: %d | Spread: %.5f", index, price, size, spread);
if (random() < 0.75 && index + 1 < totalOrders) {
int newSize = generateOrderSize(size * (0.8 + random() * 0.3));
addOrder(orderBook, index + 1, price - 0.01 * randomInt(1, 12), newSize, totalOrders);
}
}
// Ensures Safe and Realistic Spread Calculation
double calculateSpread(Order* orderBook, int index) {
if (index < 0 || index >= MAX_ORDERS) return 0.007; // Prevent invalid indices
double baseSpread = clamp(0.007 + random() * 0.02, 0.007, 0.04);
double hftPressure = ifelse(random() < 0.5, 0.002 + (random() - 0.5) * 0.005, 0.001);
double volatilityFactor = (random() - 0.5) * 0.03;
double spread = baseSpread + (0.025 - orderBook[index].price * 0.0003) - hftPressure + volatilityFactor;
return clamp(spread, 0.007, 0.04);
}
// Main Trading Simulation Function
void run() {
set(LOGFILE);
Verbose = 2;
initializeRandomSeed();
int totalOrders = randomInt(MIN_ORDERS, MAX_ORDERS); // Ensures a dynamic number of orders
static Order orderBook[MAX_ORDERS];
int i;
for (i = 0; i < totalOrders; i++) {
orderBook[i].price = clamp(100.0 + random() * 8, 50, 200);
orderBook[i].size = generateOrderSize(MAX_ORDER_SIZE);
orderBook[i].spread = clamp(0.007 + random() * 0.02, 0.007, 0.04);
orderBook[i].parentIndex = -1;
}
addOrder(orderBook, 0, 100.00 + random() * 6, generateOrderSize(85), totalOrders);
vars SpreadSeries = series(0);
vars PriceSeries = series(0);
for (i = 1; i <= MAX_DEPTH; i++) {
int orderIndex = randomInt(0, totalOrders - 1); // Ensures valid index selection
double spread = calculateSpread(orderBook, orderIndex);
SpreadSeries[0] = spread;
PriceSeries[0] = orderBook[orderIndex].price;
plotBar("Spreads", i, spread * 10000, 1, SUM + BARS, RED);
plot("Price", PriceSeries[0], LINE, BLUE);
plotBar("Order Sizes", i, orderBook[orderIndex].size, 1, SUM + BARS, GREEN);
print(TO_LOG, " Depth %d: Order Index = %d | Spread = %.5f | Price = %.4f | Order Size = %d",
i, orderIndex, spread, PriceSeries[0], orderBook[orderIndex].size);
}
}
Last edited by TipmyPip; 01/31/25 14:38.
|