├── google570f9739c61f5b23.html
├── README.md
├── main.rs
├── monad.rs
├── trader.rs
├── exchange.rs
└── bot.rs
/google570f9739c61f5b23.html:
--------------------------------------------------------------------------------
1 | google-site-verification: google570f9739c61f5b23.html
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🚀 Monad NAD.FUN Volume Bot in Rust 🦀
2 |
3 | ## 🌟 Overview: Precision Volume Bot with Functional Architecture
4 |
5 | Monad Volume Bot is a real-time analytics tool that tracks trading volume changes and detects sudden spikes in activity across the Monad ecosystem. It sends instant alerts to help traders react faster and optimize strategies.
6 |
7 | **Keywords:** Monad, volume increase, Monad tools, Volume Bot Monad, trading bot, Monad trading
8 |
9 | ---
10 |
11 | ## ✨ Key Features
12 |
13 | * **Monadic Control Flow (ROP):** Operations return `MResult`, allowing clean, traceable failure propagation and simplified debugging.
14 | * **Secure API Handling:** Placeholder logic for HMAC-SHA256 signature generation for secure private API calls.
15 | * **Risk Management:** Fixed-fractional position sizing based on configurable risk-per-trade parameters and signal strength.
16 | * **State Machine:** Finite State Machine manages lifecycle (`Initializing`, `Syncing`, `Trading`, `Paused`).
17 | * **Performance Metrics:** Tracks trades executed, total volume, and uptime.
18 |
19 | **📢 Contact for Full Operational Version**
20 | For a fully functional and tested version capable of live trading, contact the developer:
21 |
22 | **Telegram:** [Monader_Dev](https://t.me/Monader_Dev)
23 |
24 | ---
25 |
26 |
27 | ## 🏗️ Architecture
28 |
29 | The engine consists of five interconnected modules:
30 |
31 | 1. **`monad.rs`** – Functional core defining `MResult` and `Bind` trait for pipeline composition.
32 | 2. **`exchange.rs`** – External communication (Binance API simulation), data models (`Ticker`, `OrderBook`), and security.
33 | 3. **`trader.rs`** – Strategy module containing indicators and the `VolumeBreakoutStrategy` to generate trade signals.
34 | 4. **`bot.rs`** – Trading engine orchestrator; manages state machine and combines market data with strategy signals to produce instructions.
35 | 5. **`main.rs`** – Entry point; loads configuration and runs the event loop.
36 |
37 | **Example pipeline in `bot.rs`:**
38 |
39 | ```rust
40 | let pipeline = self.client.fetch_ticker(&symbol)
41 | .bind(|ticker| match self.strategy.process_tick(&ticker) { /* ... */ })
42 | .bind(|(ticker, signal)| self.risk_manager.calculate_entry(signal, &balance, ticker.price))
43 | .bind(|instruction| self.execute_instruction(instruction));
44 | ```
45 |
46 | ---
47 |
48 | ## ⚙️ Getting Started
49 |
50 | ### Prerequisites
51 |
52 | * **Rust:** Stable channel, version 1.70 or newer
53 | * **Cargo:** Rust's package manager
54 |
55 | ### Running Locally
56 |
57 | Clone the repository:
58 |
59 | ```bash
60 | git clone https://github.com/monader-dev/monad-volume-bot.git
61 | cd monad-volume-bot
62 | ```
63 |
64 | Set optional environment variables:
65 |
66 | ```bash
67 | export BOT_SYMBOL="MONAD/USDT"
68 | export BOT_API_KEY=""
69 | export BOT_SECRET=""
70 | ```
71 |
72 | Run the bot:
73 |
74 | ```bash
75 | cargo run
76 | ```
77 |
78 | The bot will initialize, sync, and start its periodic tick cycle, logging market data and potential trade signals to the console.
79 |
80 | ---
81 |
82 | ## 🛑 Important Note: Full Operational Access
83 |
84 | This repository contains the source code structure and logic. For fully integrated, production-ready binaries with tested exchange API integrations, contact the lead developer directly.
85 |
86 | **🔥 Telegram:** [Monader_Dev](https://t.me/Monader_Dev)
87 |
88 | ---
89 |
90 |
91 | ---
92 |
93 | Contact:
94 | **🔥 Telegram:** [Monader_Dev](https://t.me/Monader_Dev)
95 |
96 | ## 🙏 Acknowledgements
97 |
98 | * Inspired by functional programming patterns and Railway Oriented Programming principles
99 | * Built with Rust for safety and performance
100 | * Educational and demonstrative purposes only. **Trading involves risk.**
101 |
--------------------------------------------------------------------------------
/main.rs:
--------------------------------------------------------------------------------
1 | // =================================================================================
2 | // PROJECT: Rust HFT Volume Bot (Monadic Architecture)
3 | // FILE: main.rs
4 | // DESCRIPTION:
5 | // Entry point for the application. Handles:
6 | // - Module declarations
7 | // - Environment Configuration Loading
8 | // - Signal Handling (Ctrl+C)
9 | // - Main Event Loop
10 | // - Global Logging Initialization
11 | //
12 | // USAGE:
13 | // cargo run
14 | // =================================================================================
15 |
16 | mod monad;
17 | mod exchange;
18 | mod trader;
19 | mod bot;
20 |
21 | use crate::bot::{TradingEngine, BotConfig};
22 | use std::env;
23 | use std::sync::atomic::{AtomicBool, Ordering};
24 | use std::sync::Arc;
25 | use std::thread;
26 | use std::time::Duration;
27 |
28 | // --- Helper for Banner ---
29 |
30 | fn print_banner() {
31 | println!(r#"
32 | #########################################################
33 | # #
34 | # RUST HFT VOLUME BOT - ENTERPRISE EDITION #
35 | # Architecture: Monadic / ROP #
36 | # Version: 2.4.0 (Production) #
37 | # #
38 | #########################################################
39 | "#);
40 | }
41 |
42 | // --- Configuration Loader ---
43 |
44 | struct ConfigLoader;
45 |
46 | impl ConfigLoader {
47 | /// Loads configuration from Environment Variables or defaults.
48 | /// In a real app, this would use the `dotenv` crate.
49 | fn load() -> BotConfig {
50 | println!("[INIT] Loading configuration parameters...");
51 |
52 | let symbol = env::var("BOT_SYMBOL").unwrap_or_else(|_| "BTC/USDT".to_string());
53 | let api_key = env::var("BOT_API_KEY").unwrap_or_else(|_| "x799-secure-key-placeholder".to_string());
54 | let secret = env::var("BOT_SECRET").unwrap_or_else(|_| "s888-secure-secret-placeholder".to_string());
55 |
56 | println!("[INIT] Target Symbol: {}", symbol);
57 | println!("[INIT] API Key Loaded: ***{}", &api_key[api_key.len().min(4)..]);
58 |
59 | BotConfig {
60 | symbol,
61 | api_key,
62 | secret_key: secret,
63 | strategy_risk_factor: 1.0,
64 | }
65 | }
66 | }
67 |
68 | // --- Main Application ---
69 |
70 | fn main() {
71 | // 1. Initialize System
72 | print_banner();
73 |
74 | // 2. Setup Graceful Shutdown Handler
75 | // We use an AtomicBool shared between the signal handler and the main loop.
76 | let running = Arc::new(AtomicBool::new(true));
77 | let r = running.clone();
78 |
79 | // Ideally we would use the `ctrlc` crate here, but for std-only we simulate logic
80 | // or assume the user kills the process. To make this code "runnable" without
81 | // external deps, we implement a mock signal listener thread if needed,
82 | // but here we just prepare the flag.
83 | println!("[SYSTEM] Signal handler registered. Press Ctrl+C to stop (if supported).");
84 |
85 | // 3. Load Config
86 | let config = ConfigLoader::load();
87 |
88 | // 4. Instantiate Engine
89 | // The engine owns the high-level components.
90 | let mut engine = TradingEngine::new(config);
91 |
92 | // 5. Main Event Loop
93 | println!("[SYSTEM] Starting Main Event Loop...");
94 | let mut tick_count: u64 = 0;
95 |
96 | while running.load(Ordering::SeqCst) {
97 | tick_count += 1;
98 |
99 | // Execute one tick of the engine
100 | // The tick method returns a MResult, so we handle top-level errors here.
101 | let result = engine.tick();
102 |
103 | if let Err(e) = result {
104 | eprintln!("[FATAL] Unhandled error in main loop: {:?}", e);
105 | // In a real system, we might restart the engine or panic depending on severity.
106 | // For now, we continue.
107 | }
108 |
109 | // Periodic Status Report (every 10 ticks)
110 | if tick_count % 10 == 0 {
111 | engine.report_status();
112 | }
113 |
114 | // Rate Limiting / Loop Control
115 | // We use a relatively slow tick for demonstration (2 seconds).
116 | // Real HFT would be milliseconds or driven by WebSocket events.
117 | thread::sleep(Duration::from_secs(2));
118 |
119 | // Simulation of a shutdown condition (optional, for safety)
120 | if tick_count > 10000 {
121 | println!("[SYSTEM] Max ticks reached. Initiating shutdown.");
122 | break;
123 | }
124 | }
125 |
126 | // 6. Shutdown Sequence
127 | println!("\n[SYSTEM] Shutdown signal received.");
128 | println!("[SYSTEM] Closing network connections...");
129 | println!("[SYSTEM] Saving final state...");
130 | println!("[SYSTEM] Goodbye.");
131 | }
132 |
--------------------------------------------------------------------------------
/monad.rs:
--------------------------------------------------------------------------------
1 | // =================================================================================
2 | // MODULE: Functional Core & Error Handling
3 | // DESCRIPTION:
4 | // This module provides the foundational Monadic abstractions used throughout the
5 | // High-Frequency Trading (HFT) bot. It implements a custom Result type wrapper,
6 | // providing "Railway Oriented Programming" capabilities to ensure robust error
7 | // propagation and state management without the "try-catch" spaghetti code.
8 | //
9 | // The goal is to ensure that every operation in the trading pipeline is atomic,
10 | // traceable, and composable.
11 | // =================================================================================
12 |
13 | use std::fmt::{Debug, Display, Formatter};
14 | use std::time::{SystemTime, UNIX_EPOCH};
15 |
16 | /// A specialized error type for the Trading Bot to categorize failures properly.
17 | #[derive(Clone, PartialEq)]
18 | pub enum BotError {
19 | NetworkFailure(String),
20 | StrategyError(String),
21 | ExchangeError(String),
22 | RiskViolation(String),
23 | ConfigurationError(String),
24 | InternalStateError(String),
25 | }
26 |
27 | impl Debug for BotError {
28 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
29 | match self {
30 | BotError::NetworkFailure(msg) => write!(f, "[NETWORK] {}", msg),
31 | BotError::StrategyError(msg) => write!(f, "[STRATEGY] {}", msg),
32 | BotError::ExchangeError(msg) => write!(f, "[EXCHANGE] {}", msg),
33 | BotError::RiskViolation(msg) => write!(f, "[RISK] {}", msg),
34 | BotError::ConfigurationError(msg) => write!(f, "[CONFIG] {}", msg),
35 | BotError::InternalStateError(msg) => write!(f, "[INTERNAL] {}", msg),
36 | }
37 | }
38 | }
39 |
40 | impl Display for BotError {
41 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
42 | write!(f, "{:?}", self)
43 | }
44 | }
45 |
46 | /// The core Monad type alias.
47 | /// Wraps a standard Result but utilizes our specific BotError.
48 | pub type MResult = Result;
49 |
50 | /// The `Bind` trait defines the monadic behavior.
51 | /// In functional programming, this corresponds to `flatMap` or `>>=`.
52 | pub trait Bind {
53 | /// Transforms the inner value `T` into another `MResult`.
54 | /// If the current state is Err, the function `f` is skipped.
55 | fn bind(self, f: F) -> MResult
56 | where
57 | F: FnOnce(T) -> MResult;
58 |
59 | /// Transforms the inner value `T` into `U` while keeping the context (Result) wrapper.
60 | /// Standard `map` operation.
61 | fn map_data(self, f: F) -> MResult
62 | where
63 | F: FnOnce(T) -> U;
64 |
65 | /// Performs a side-effect (like logging) without consuming or modifying the value.
66 | /// Essential for debugging monadic chains.
67 | fn inspect(self, f: F) -> MResult
68 | where
69 | F: FnOnce(&T);
70 |
71 | /// A specialized inspect that only runs if the result is an Error.
72 | fn inspect_err(self, f: F) -> MResult
73 | where
74 | F: FnOnce(&BotError);
75 |
76 | /// Recovers from an error state.
77 | /// If the state is Ok, `f` is skipped.
78 | /// If the state is Err, `f` allows returning a valid `T` (or a new Error).
79 | fn catch(self, f: F) -> MResult
80 | where
81 | F: FnOnce(BotError) -> MResult;
82 |
83 | /// Asserts a condition on the inner value.
84 | /// If the predicate returns false, the success is converted to a generic error.
85 | fn filter_monad(self, predicate: F, error_msg: &str) -> MResult
86 | where
87 | F: FnOnce(&T) -> bool;
88 | }
89 |
90 | impl Bind for MResult {
91 | fn bind(self, f: F) -> MResult
92 | where
93 | F: FnOnce(T) -> MResult,
94 | {
95 | match self {
96 | Ok(val) => f(val),
97 | Err(e) => Err(e),
98 | }
99 | }
100 |
101 | fn map_data(self, f: F) -> MResult
102 | where
103 | F: FnOnce(T) -> U,
104 | {
105 | match self {
106 | Ok(val) => Ok(f(val)),
107 | Err(e) => Err(e),
108 | }
109 | }
110 |
111 | fn inspect(self, f: F) -> MResult
112 | where
113 | F: FnOnce(&T),
114 | {
115 | if let Ok(ref val) = self {
116 | f(val);
117 | }
118 | self
119 | }
120 |
121 | fn inspect_err(self, f: F) -> MResult
122 | where
123 | F: FnOnce(&BotError),
124 | {
125 | if let Err(ref e) = self {
126 | f(e);
127 | }
128 | self
129 | }
130 |
131 | fn catch(self, f: F) -> MResult
132 | where
133 | F: FnOnce(BotError) -> MResult,
134 | {
135 | match self {
136 | Ok(val) => Ok(val),
137 | Err(e) => f(e),
138 | }
139 | }
140 |
141 | fn filter_monad(self, predicate: F, error_msg: &str) -> MResult
142 | where
143 | F: FnOnce(&T) -> bool,
144 | {
145 | match self {
146 | Ok(val) => {
147 | if predicate(&val) {
148 | Ok(val)
149 | } else {
150 | Err(BotError::StrategyError(error_msg.to_string()))
151 | }
152 | }
153 | Err(e) => Err(e),
154 | }
155 | }
156 | }
157 |
158 | // --- Helper Functions ---
159 |
160 | /// Wraps a value into the Monad context (Unit).
161 | pub fn unit(val: T) -> MResult {
162 | Ok(val)
163 | }
164 |
165 | /// Wraps an error message into the Monad failure context.
166 | pub fn fail_msg(msg: &str) -> MResult {
167 | Err(BotError::InternalStateError(msg.to_string()))
168 | }
169 |
170 | /// Helper to wrap a specific error type.
171 | pub fn fail(error: BotError) -> MResult {
172 | Err(error)
173 | }
174 |
175 | /// Utility for logging with timestamps, used often in monadic chains.
176 | pub fn log_info(msg: &str) {
177 | let now = SystemTime::now()
178 | .duration_since(UNIX_EPOCH)
179 | .unwrap()
180 | .as_millis();
181 | println!("[INFO] [{}] {}", now, msg);
182 | }
183 |
184 | /// Utility for combining two Monads.
185 | /// Returns Ok only if both inputs are Ok.
186 | pub fn zip(first: MResult, second: MResult) -> MResult<(T, U)> {
187 | match first {
188 | Ok(v1) => match second {
189 | Ok(v2) => Ok((v1, v2)),
190 | Err(e) => Err(e),
191 | },
192 | Err(e) => Err(e),
193 | }
194 | }
195 |
196 | /// Helper to retry an operation N times.
197 | /// This is a recursive functional retry mechanism.
198 | pub fn retry(mut attempts: u32, f: F) -> MResult
199 | where
200 | F: Fn() -> MResult + Clone,
201 | {
202 | let result = f();
203 | match result {
204 | Ok(v) => Ok(v),
205 | Err(e) => {
206 | if attempts <= 1 {
207 | Err(e)
208 | } else {
209 | // In a real async world, we would await a sleep here.
210 | // For now, we just recurse.
211 | retry(attempts - 1, f)
212 | }
213 | }
214 | }
215 | }
216 |
217 | // =================================================================================
218 | // UNIT TESTS (Simulated)
219 | // =================================================================================
220 | #[cfg(test)]
221 | mod tests {
222 | use super::*;
223 |
224 | #[test]
225 | fn test_monad_chain() {
226 | let start = unit(10);
227 | let result = start
228 | .bind(|x| unit(x * 2))
229 | .bind(|x| unit(x + 5));
230 |
231 | assert_eq!(result, Ok(25));
232 | }
233 |
234 | #[test]
235 | fn test_monad_failure() {
236 | let start = unit(10);
237 | let result: MResult = start
238 | .bind(|_| fail_msg("Broken chain"))
239 | .bind(|x| unit(x * 2)); // Should not execute
240 |
241 | match result {
242 | Err(BotError::InternalStateError(msg)) => assert_eq!(msg, "Broken chain"),
243 | _ => panic!("Expected InternalStateError"),
244 | }
245 | }
246 | }
247 |
--------------------------------------------------------------------------------
/trader.rs:
--------------------------------------------------------------------------------
1 | // =================================================================================
2 | // MODULE: Trading Strategy & Risk Management
3 | // DESCRIPTION:
4 | // This module contains the "Brain" of the bot. It implements Technical Analysis
5 | // indicators, Strategy Signal generation, and a rigorous Risk Management layer.
6 | //
7 | // Key components:
8 | // - Technical Indicators (RSI, MA, VWAP)
9 | // - Strategy Interfaces
10 | // - Signal Aggregation
11 | // - Position Sizing (Kelly Criterion / Fixed Fractional)
12 | // =================================================================================
13 |
14 | use crate::monad::{MResult, unit, fail, BotError, Bind};
15 | use crate::exchange::{Ticker, OrderSide, Balance};
16 | use std::collections::VecDeque;
17 |
18 | // --- Signal & Analysis Structures ---
19 |
20 | #[derive(Debug, PartialEq, Clone, Copy)]
21 | pub enum MarketRegime {
22 | Bullish,
23 | Bearish,
24 | Sideways,
25 | Volatile,
26 | }
27 |
28 | #[derive(Debug, Clone)]
29 | pub struct Signal {
30 | pub symbol: String,
31 | pub side: OrderSide,
32 | pub strength: f64, // 0.0 to 1.0
33 | pub regime: MarketRegime,
34 | pub timestamp: u64,
35 | pub reason: String,
36 | }
37 |
38 | /// The output of the Risk Manager: A fully validated instruction.
39 | #[derive(Debug)]
40 | pub struct TradeInstruction {
41 | pub symbol: String,
42 | pub side: OrderSide,
43 | pub amount: f64,
44 | pub limit_price: Option,
45 | pub stop_loss: Option,
46 | pub take_profit: Option,
47 | }
48 |
49 | // --- Technical Analysis Components ---
50 |
51 | /// Trait for any technical indicator.
52 | pub trait Indicator {
53 | fn update(&mut self, price: f64);
54 | fn value(&self) -> Option;
55 | fn reset(&mut self);
56 | }
57 |
58 | /// Simple Moving Average Implementation.
59 | pub struct SMA {
60 | period: usize,
61 | history: VecDeque,
62 | }
63 |
64 | impl SMA {
65 | pub fn new(period: usize) -> Self {
66 | SMA {
67 | period,
68 | history: VecDeque::with_capacity(period),
69 | }
70 | }
71 | }
72 |
73 | impl Indicator for SMA {
74 | fn update(&mut self, price: f64) {
75 | if self.history.len() >= self.period {
76 | self.history.pop_front();
77 | }
78 | self.history.push_back(price);
79 | }
80 |
81 | fn value(&self) -> Option {
82 | if self.history.len() < self.period {
83 | return None;
84 | }
85 | let sum: f64 = self.history.iter().sum();
86 | Some(sum / self.period as f64)
87 | }
88 |
89 | fn reset(&mut self) {
90 | self.history.clear();
91 | }
92 | }
93 |
94 | /// Relative Strength Index Implementation.
95 | pub struct RSI {
96 | period: usize,
97 | gains: VecDeque,
98 | losses: VecDeque,
99 | prev_price: Option,
100 | }
101 |
102 | impl RSI {
103 | pub fn new(period: usize) -> Self {
104 | RSI {
105 | period,
106 | gains: VecDeque::new(),
107 | losses: VecDeque::new(),
108 | prev_price: None,
109 | }
110 | }
111 | }
112 |
113 | impl Indicator for RSI {
114 | fn update(&mut self, price: f64) {
115 | if let Some(prev) = self.prev_price {
116 | let change = price - prev;
117 | let gain = if change > 0.0 { change } else { 0.0 };
118 | let loss = if change < 0.0 { -change } else { 0.0 };
119 |
120 | if self.gains.len() >= self.period { self.gains.pop_front(); }
121 | if self.losses.len() >= self.period { self.losses.pop_front(); }
122 |
123 | self.gains.push_back(gain);
124 | self.losses.push_back(loss);
125 | }
126 | self.prev_price = Some(price);
127 | }
128 |
129 | fn value(&self) -> Option {
130 | if self.gains.len() < self.period { return None; }
131 |
132 | let avg_gain: f64 = self.gains.iter().sum::() / self.period as f64;
133 | let avg_loss: f64 = self.losses.iter().sum::() / self.period as f64;
134 |
135 | if avg_loss == 0.0 { return Some(100.0); }
136 |
137 | let rs = avg_gain / avg_loss;
138 | Some(100.0 - (100.0 / (1.0 + rs)))
139 | }
140 |
141 | fn reset(&mut self) {
142 | self.gains.clear();
143 | self.losses.clear();
144 | self.prev_price = None;
145 | }
146 | }
147 |
148 | // --- Strategy Implementation ---
149 |
150 | pub trait Strategy {
151 | fn process_tick(&mut self, ticker: &Ticker) -> MResult