Avellaneda-Stoikov मॉडल का उपयोग करके क्रिप्टो पेयर्स के लिए मार्केट मेकिंग एल्गोरिदम बनाना
नमस्ते दोस्तों! आज मैं आपको दिखाऊंगा कि USD+/wETH और USD+/cbbtc क्रिप्टो पेयर्स के लिए मार्केट मेकिंग एल्गोरिदम कैसे बनाया जाए। हम Avellaneda-Stoikov (A-S) मॉडल का उपयोग करेंगे और डायनामिक स्प्रेड ऑप्टिमाइज़ेशन के लिए इसे Reinforcement Learning (PPO) एल्गोरिदम से बेहतर बनाएंगे। सुनने में जटिल लगता है? चिंता न करें, मैं सब कुछ स्पष्ट चरणों में विभाजित करूंगा ताकि एक शुरुआती डेवलपर भी इसे समझ सके।
मार्केट मेकिंग के सार को दर्शाना: इष्टतम बाजार तरलता को संश्लेषित करने के लिए एक उचित मूल्य के आसपास खरीद और बिक्री ऑर्डर को लगातार संतुलित करना।
मार्केट मेकिंग क्या है और हमें इसकी आवश्यकता क्यों है?
मार्केट मेकिंग एक रणनीति है जिसमें एक ट्रेडर एक साथ किसी संपत्ति के लिए खरीद और बिक्री ऑर्डर लगाता है, स्प्रेड (कीमतों के बीच का अंतर) से कमाई करता है। DeFi क्षेत्र में, मार्केट मेकर्स तरलता प्रदान करके और अन्य बाजार प्रतिभागियों के लिए स्लिपेज को कम करके एक महत्वपूर्ण भूमिका निभाते हैं।
कल्पना कीजिए कि आप एक बाजार में विक्रेता हैं, हमेशा बाजार मूल्य से थोड़ा कम पर उत्पाद खरीदने और थोड़ा अधिक पर बेचने के लिए तैयार हैं। आपका लाभ आपके खरीद और बिक्री मूल्यों के बीच का अंतर है। लेकिन एक समस्या है: यदि कीमत अचानक एक दिशा में चलती है, तो आप बहुत अधिक इन्वेंटरी जमा कर सकते हैं, या इसके विपरीत, बेचने के लिए कुछ भी नहीं बचेगा।
Avellaneda-Stoikov मॉडल: ट्रेडिंग की सेवा में गणित
A-S मॉडल मार्केट मेकिंग के लिए इष्टतम कीमतें निर्धारित करने का एक गणितीय दृष्टिकोण है। इसका मुख्य लाभ यह है कि यह न केवल वर्तमान बाजार मूल्य को ध्यान में रखता है, बल्कि आपकी पोजीशन के आकार (इन्वेंटरी), बाजार की अस्थिरता और जोखिम की भूख को भी ध्यान में रखता है।
मॉडल के मुख्य सूत्र:
δ_a = S_t + (1/γ) * ln(1 + γ/k) + q_t * σ² * T
δ_b = S_t - (1/γ) * ln(1 + γ/k) - q_t * σ² * T
जहां:
δ_aऔरδ_bआस्क और बिड कीमतें हैंS_tवर्तमान बाजार मूल्य हैγजोखिम पैरामीटर है (जितना अधिक होगा, स्प्रेड उतना ही व्यापक होगा)kऑर्डर आगमन दर हैq_tवर्तमान इन्वेंटरी हैσअस्थिरता हैTसमय क्षितिज है
ऑनचेन ट्रेडिंग की विशेषताएं
जब हम एल्गोरिदम को ऑनचेन ले जाते हैं, तो अतिरिक्त चुनौतियां पैदा होती हैं:
- लेटेंसी – ब्लॉकचेन पर लेनदेन तत्काल नहीं होते हैं, और ऑर्डर निष्पादित होने से पहले कीमत बदल सकती है
- गैस लागत – प्रत्येक लेनदेन के लिए नेटवर्क शुल्क की आवश्यकता होती है
- AMM/PMM विशेषताएं – लिक्विडिटी पूल की यांत्रिकी पारंपरिक एक्सचेंजों से भिन्न होती है
आइए देखें कि हम अपने एल्गोरिदम में इन कारकों को कैसे ध्यान में रख सकते हैं।
चरण 1: वातावरण सेट करें और डेटा एकत्र करें
सबसे पहले, हमें बाजार डेटा प्राप्त करने के लिए एक वातावरण सेट करने की आवश्यकता है। हम वर्तमान कीमतें और ऑर्डर बुक की गहराई प्राप्त करने के लिए Binance API का उपयोग करेंगे।
std::tuple MarketMaker::get_binance_data(const std::string& pair) {
// In real code, this would be a request to the Binance API
// Returns: mid_price, bid, ask, bid_volume, ask_volume
double mid_price = 2000.0;
double bid = mid_price - 1.0;
double ask = mid_price + 1.0;
double bid_volume = 10.0;
double ask_volume = 8.0;
return {mid_price, bid, ask, bid_volume, ask_volume};
}
हमें गैस लागत और नेटवर्क लेटेंसी जैसे ऑनचेन मेट्रिक्स की भी आवश्यकता होगी:
std::pair MarketMaker::get_onchain_metrics() {
// In real code, this would be a request to an Ethereum node
// Returns: gas_price (wei), latency (seconds)
return {50e9, 12.0};
}
चरण 2: बेसिक A-S मॉडल लागू करें
अब आइए A-S मॉडल का उपयोग करके स्प्रेड की गणना को लागू करते हैं:
std::pair MarketMaker::calculate_spreads(double S_t, double sigma, double k, double q_t) {
// Avellaneda-Stoikov formula
double spread_term = (1.0 / gamma_) * log(1.0 + gamma_ / k);
double inventory_term = q_t * sigma * sigma * T_;
double delta_a = S_t + spread_term + inventory_term; // Ask price
double delta_b = S_t - spread_term - inventory_term; // Bid price
return {delta_a, delta_b};
}
inventory_term पर ध्यान दें। यदि आपके पास पॉजिटिव इन्वेंटरी है (संपत्ति की बड़ी मात्रा), तो आस्क मूल्य घट जाता है, और बिड मूल्य और भी अधिक घट जाता है ताकि बिक्री को प्रोत्साहित किया जा सके और खरीद को सीमित किया जा सके। और नेगेटिव इन्वेंटरी के लिए इसके विपरीत।
चरण 3: ऑनचेन ट्रेडिंग के लिए मॉडल को अनुकूलित करें
अब हमें ब्लॉकचेन की विशेषताओं को ध्यान में रखना होगा। आइए लेटेंसी से शुरू करते हैं:
double MarketMaker::adjust_price_with_latency(double S_t, double sigma, double latency) {
// Simulate random price change due to latency
double latency_adjustment = utils::normal_dist(0.0, sigma * std::sqrt(latency));
return S_t + latency_adjustment;
}
यहां हम एक रैंडम वॉक मॉडल का उपयोग करते हैं: अस्थिरता जितनी अधिक होगी और लेटेंसी जितनी लंबी होगी, ऑर्डर निष्पादित होने से पहले कीमत उतनी ही अधिक बदल सकती है।
अब आइए गैस लागत को ध्यान में रखें:
double MarketMaker::calculate_gas_cost(double gas_price, double trade_size) {
const double GAS_LIMIT_PER_ORDER = 100000; // Approximate value per order
return (gas_price * GAS_LIMIT_PER_ORDER * trade_size) / 1e18; // Convert wei to ETH
}
अंत में, आइए PMM पूल विशेषताओं के लिए स्प्रेड को अनुकूलित करें:
std::pair MarketMaker::adjust_spreads_for_pmm(double S_t, double delta_a, double delta_b, double pool_depth) {
// Simplified PMM model: adjust spreads based on pool depth
const double MIN_POOL_DEPTH = 10.0;
double depth_factor = std::max(pool_depth, MIN_POOL_DEPTH) / MIN_POOL_DEPTH;
// Reduce spreads with greater pool depth
double spread_reduction = 1.0 / std::sqrt(depth_factor);
double mid_price = (delta_a + delta_b) / 2;
double new_delta_a = mid_price + (delta_a - mid_price) * spread_reduction;
double new_delta_b = mid_price - (mid_price - delta_b) * spread_reduction;
return {new_delta_a, new_delta_b};
}
चरण 4: इन्वेंटरी प्रबंधन
इन्वेंटरी को ट्रैक और प्रबंधित करने के लिए, आइए एक सरल क्लास बनाते हैं:
class InventoryManager {
public:
InventoryManager() : inventory_(0.0) {}
void update_inventory(double size, bool is_buy) {
inventory_ += is_buy ? size : -size;
}
double get_inventory() const {
return inventory_;
}
private:
double inventory_;
};
इन्वेंटरी रिस्क विज़ुअलाइज़ेशन: एकतरफा बाजार गतिविधियों के प्रति अत्यधिक एक्सपोज़र (लॉन्ग या शॉर्ट) से बचने के लिए पोजीशन आकार की निगरानी करना।
चरण 5: सब कुछ एक ही एल्गोरिदम में मिलाएं
अब आइए सभी घटकों को एक ही मार्केट मेकिंग एल्गोरिदम में मिलाते हैं:
void MarketMaker::step(double S_t, double sigma, double k, double latency, double gas_cost, double trade_size) {
// Get current inventory
double current_inventory = inventory_.get_inventory();
// Calculate spreads based on current market conditions and inventory
auto [delta_a, delta_b] = calculate_spreads(S_t, sigma, k, current_inventory);
auto [adjusted_delta_a, adjusted_delta_b] = adjust_spreads_for_onchain(S_t, delta_a, delta_b, latency, sigma, gas_cost, trade_size);
// Generate independent market price
double market_price = S_t + utils::normal_dist(0.0, sigma);
// Determine if trades should occur based on market price and spreads
bool is_buy = (market_price = adjusted_delta_a);
// Execute trades and update inventory
if (is_buy) {
inventory_.update_inventory(trade_size, true);
std::cout reset();
// Take action and get new state, reward, and done flag
std::tuple, double, bool> step(const std::array& action);
private:
// Get current environment state
std::vector get_state() const;
MarketMaker& mm_;
double current_inventory_;
double current_profit_;
int current_step_;
int max_steps_;
// Current market parameters
double mid_price_;
double sigma_;
double latency_;
double pool_depth_;
std::mt19937 rng_;
};
हमारे एनवायरनमेंट का स्टेट वर्तमान कीमत, इन्वेंटरी, अस्थिरता, नेटवर्क लेटेंसी और पूल गहराई का एक वेक्टर है। एक्शन स्प्रेड और खरीद/बिक्री आकारों का एक वेक्टर है।
अब आइए रिवॉर्ड फंक्शन को लागू करें:
double reward = profit_term - inventory_risk - gas_cost;
जहां:
profit_termट्रेडों से लाभ हैinventory_riskबड़ी इन्वेंटरी (जोखिम) के लिए एक पेनल्टी हैgas_costखर्च की गई गैस है
अंत में, आइए PPO एजेंट को प्रशिक्षित करें:
void PPOTrainer::train(int episodes) {
for (int ep = 0; ep states;
std::vector actions;
std::vector rewards;
while (true) {
// Get action from policy
auto action_probs = policy_net_->forward(torch::tensor(state));
auto action = action_probs.multinomial(1);
// Take a step in the environment
auto [next_state, reward, done] = env_.step(action);
// Save transition
states.push_back(torch::tensor(state));
actions.push_back(action);
rewards.push_back(reward);
if (done) break;
state = next_state;
}
// Update PPO policy
update_policy(states, actions, rewards);
}
}
कार्रवाई में Reinforcement Learning: अधिकतम अपेक्षित रिवॉर्ड के लिए खरीद/बिक्री स्प्रेड को डायनामिक रूप से ऑप्टिमाइज़ करने हेतु जटिल बाजार स्टेट्स को प्रोसेस करता PPO एजेंट।
चरण 7: परीक्षण और विज़ुअलाइज़ेशन
अपने एल्गोरिदम का परीक्षण करने के लिए, आइए एक सरल सिमुलेशन बनाते हैं:
int main() {
// Use T = 300 seconds as specified in the task
MarketMaker mm(0.1, 300.0);
// Simulate historical data for volatility
std::vector prices = {2000.0};
double S_t = 2000.0;
double trade_size = 1.0;
double initial_sigma = 0.05; // 5% volatility
for (int i = 0; i < 300; ++i) {
std::cout << "Step " << i + 1 << ": ";
// Get data (stubs)
auto [mid_price, bid_ask] = mm.get_binance_data("USD+/wETH");
auto [gas_cost, latency] = mm.get_onchain_metrics();
// Add random price movement to simulate a real market
S_t = mid_price + utils::normal_dist(0.0, mid_price * 0.01);
// Calculate volatility
double sigma = mm.calculate_volatility(prices, 5);
if (sigma < 0.01) sigma = initial_sigma;
// Order arrival rate (stub)
double k = 5.0;
mm.step(S_t, sigma, k, latency, gas_cost, trade_size);
// Update price for next step
S_t += utils::normal_dist(0.0, S_t * 0.02);
prices.push_back(S_t);
}
return 0;
}
आगे क्या?
हमारा मार्केट मेकिंग एल्गोरिदम तैयार है, लेकिन इसे बेहतर बनाने के कई तरीके हैं:
- वास्तविक API से कनेक्ट करें: स्टब्स को Binance API और एथेरियम नोड के लिए वास्तविक अनुरोधों से बदलें
- अस्थिरता मॉडल में सुधार करें: GARCH या अन्य उन्नत मॉडल का उपयोग करें
- PPO का विस्तार करें: स्टेट और एक्शन में अधिक पैरामीटर जोड़ें
- गैस को ऑप्टिमाइज़ करें: गैस लागत को कम करने की रणनीतियां
- मल्टी-एसेट रणनीति: एक साथ कई पेयर्स तक विस्तार करें
निष्कर्ष
हमने एक मार्केट मेकिंग एल्गोरिदम बनाया है जो ऑनचेन ट्रेडिंग विशेषताओं को ध्यान में रखता है और क्लासिक A-S मॉडल तथा आधुनिक RL विधियों दोनों का उपयोग करता है। यह दृष्टिकोण बदलती बाजार स्थितियों के अनुकूल होने और जोखिम को नियंत्रित करते हुए लाभ को अधिकतम करने की अनुमति देता है।
बेशक, वास्तविक ट्रेडिंग में विचार करने के लिए कई अतिरिक्त कारक हैं, लेकिन हमारा एल्गोरिदम आगे के विकास के लिए एक ठोस आधार प्रदान करता है। याद रखें: एल्गोरिदमिक ट्रेडिंग में, केवल गणित ही महत्वपूर्ण नहीं है, बल्कि गहन परीक्षण, निगरानी और निरंतर ऑप्टिमाइज़ेशन भी महत्वपूर्ण हैं।
मुझे उम्मीद है कि इस लेख ने आपको मार्केट मेकिंग के सिद्धांतों को बेहतर ढंग से समझने में मदद की और अपने खुद के एल्गोरिदम बनाने के लिए प्रेरित किया। ट्रेडिंग में शुभकामनाएं!
उद्धरण
@software{soloviov2025marketmakingavellanedastoikov,
author = {Soloviov, Eugen},
title = {Building a Market Making Algorithm for Crypto Pairs Using the Avellaneda-Stoikov Model},
year = {2025},
url = {https://marketmaker.cc/en/blog/post/market-making-avellaneda-stoikov},
version = {0.1.0},
description = {A step-by-step guide to building a market making algorithm for USD+/wETH and USD+/cbbtc pairs using the Avellaneda-Stoikov model and PPO. Onchain trading features, inventory management, RL training.}
}
Authors
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.