A highly resilient, modular, and observable Python trading application designed for placing and managing orders on the Binance Futures Testnet (USDT-M) using a direct REST API connection with persistent HTTP connection pooling and exponential backoff.
The application leverages a strict layered architecture separating command line interactions, validation, domain models, and physical network transport:
User Input
│
▼
CLI Layer
│
▼
Validation Layer
│
▼
Trading Service Layer
│
▼
Request Signing & Normalization
│
▼
Binance API Client
│
▼
Mock Adapter / Binance Futures Testnet
│
▼
Response Formatter & Logger
- Clear Separation between CLI, Business Logic, and API Communication: No business rules leak into CLI parsing or raw connection transport.
- Ensure Testability through Modular Services and Mock Adapters: High-fidelity local testing interface allowing 100% network-free verification.
- Provide Deterministic Logging for Debugging and Auditability: Precise request correlation mapping and execution traceability.
- Minimize API-side Validation Failures: Strict local bounds checking and precision normalization prior to dispatching raw network payloads.
- Support Future Extensibility: Simple logic structures allowing easy porting of strategy models or alternative exchanges.
- requests was chosen over async HTTP clients (like
httpx/aiohttp) to prioritize simplicity and readability for the current scope. - In-memory caching supplemented by local file caching (
exchange_info_cache.json) was preferred over persistent database storage (such as Redis or SQLite) to avoid unnecessary complexity and external dependencies. - Mock mode was implemented directly inside the client layer to ensure deterministic testing without requiring external credentials or mock frameworks.
- The architecture favors modularity and maintainability over aggressive, low-latency sub-millisecond execution optimization.
- High-frequency trading (HFT) optimization or low-latency sub-millisecond execution.
- Multi-account credentials management or sub-account routing.
- Portfolio tracking, open position monitoring, or margin calculations.
- Real-time WebSocket streaming (porting real-time market data or order updates).
- Persistent database storage (order logs, historical trades tracking).
The bot operates under three distinct modes via the --mode flag:
- Live Mode
Executes real orders on the Binance Futures Testnet (
https://testnet.binancefuture.com). Requires live API keys in.envand requests user confirmation (Are you sure? [y/n]) before final dispatch. - Mock Mode
Simulates realistic Binance API responses without network execution. Intercepts requests locally and returns high-fidelity, schema-aligned responses. Supports simulated failure injection via CLI flags (e.g.
--mock-failure insufficient_balance). - Dry-Run Mode Validates and signs requests without execution or simulation. Formulates and displays the complete HTTP URL, headers, and signed query string parameters but bypasses network execution and mock response generation.
The project intentionally minimizes external dependencies to improve portability, readability, and maintainability. Out-of-the-box third-party dependencies are restricted to:
requests(robust, thread-safe persistent HTTP connections pooling).python-dotenv(secure twelve-factor application configuration loading).rich(terminal formatting, interactive guided wizard, and structured UI components).
Mock responses are deterministic and schema-aligned with Binance Futures API responses to ensure reproducible testing and realistic logging behavior. It calculates precise parameters and generated signature hashes, mocking exact field keys (clientOrderId, orderId, cumQty, etc.) without hitting live servers.
Before submitting an order, parameters undergo a 6-stage validation pipeline:
- CLI argument validation: Checks that basic command line parameters are correctly structured, inputs are positive, and type requirements are satisfied (e.g., LIMIT requires a price).
- Symbol validation: Verifies symbol existence and active
TRADINGstatus in the exchange metadata. - Precision normalization: Dynamically quantizes prices and quantities to match exchange parameters perfectly.
- Exchange filter validation: Validates input quantities and prices against strict boundaries (
minQty/maxQty,minPrice/maxPrice). - Business rule validation: Enforces additional system requirements (e.g. Notional value bounds calculated as
Price * Quantity >= minNotional). - API-side validation fallback: Gracefully intercepts and interprets server-side reject payloads if an edge case bypasses local checks.
Failures are categorized into distinct, custom domain exceptions to ensure clear error recovery:
- Validation failures: Local rules violations or parameter issues (
ValidationError). - Authentication failures: Invalid credentials, signature mismatches, or expired request timestamps (
AuthenticationError). - Network failures: Timeout calls, lost connections, or unreachable target servers (
APIConnectionError). - Exchange-side rejections: Validation rejections or business limit fails returned by the remote server (
BinanceAPIError). - Rate-limit violations: HTTP 429 warning signs or IP rate limit restrictions (
RateLimitError).
Responses are normalized into structured output models (using typed bot/models.py dataclasses) before presentation to ensure consistency across live, mock, and dry-run modes. The CLI layer formats response fields into structured console tables.
The architecture is designed to support future idempotent order handling and replay protection mechanisms. The core service supports and propagates unique client-side transaction identifiers (clientOrderId / newClientOrderId), enabling exchange-side deduplication.
The client layer is intentionally abstracted to allow future integration with additional exchanges beyond Binance. Raw transport, signature generation, and path routes are isolated, making it clean to insert OKX, Bybit, or dYdX adapters.
The application clearly separates testnet and mock execution paths to reduce accidental misuse of production credentials. Live mode triggers environment key checks and enforces user confirmation blocks before sending data down physical TCP sockets.
Configuration values are centralized through a dedicated configuration layer (bot/config.py) to avoid hardcoded runtime parameters. Environment keys, cache file limits, timeout thresholds, and logs configurations are loaded securely and validated once at runtime.
In the event of exchange metadata unavailability (e.g., connection timed out or Binance offline), the application gracefully falls back to minimal local validation while surfacing warnings to the user. Rather than failing outright, it utilizes cached exchange details or structural defaults to process execution.
- Interactive CLI workflow: Self-guided wizard triggers automatically if arguments are omitted.
- Rich terminal formatting: Clean, beautiful tables summarizing parameters and response fields.
- Mock execution support: Instantly try the bot and analyze execution logs without API keys.
- Clear error messaging: Human-friendly error callouts, removing cryptic multi-line stacktraces.
- Reproducible logs: Verbose logging options (
--verbose) and comprehensive file capturing.
- Type hints throughout the codebase to ensure compiler safety, readability, and autocomplete support.
- Consistent naming conventions following strict PEP 8 standards.
- Modular architecture emphasizing loose coupling and high cohesion.
- Separation of concerns separating representation (CLI), domain models, business validation, and network transport.
- Structured exception hierarchy allowing caller-specific rescue procedures.
- Reusable utility components for precision normalizers and credential masking filters.
- Structured request/response logging: Comprehensive transaction tracking via standard rotating log files (
logs/trading_bot.log). - Correlation IDs for traceability: Generates a unique UUID
request_idfor every request to track its entire lifecycle. - Latency measurement: Computes round-trip network performance (
latency_ms) using high-precision counters. - Error classification: Categorized exceptions logged with unique identifier markers.
- Request lifecycle visibility: Telemetry tracking every phase: parse -> validate -> sign -> dispatch -> receive.
- Log Security Masking: Rotating log configurations automatically scrub
BINANCE_API_KEY,BINANCE_API_SECRET, and HMAC signature hashes.
-
Clone the Repository Ensure Python 3.8+ is installed on your local machine.
-
Install Dependencies The application minimizes external dependencies. Install the core requirements:
pip install -r requirements.txt
Or install as a local editable module:
pip install -e . -
Configure Environment Variables Copy the blueprint environment file and populate it with your Binance Futures Testnet credentials:
cp .env.example .env
Edit
.env:BINANCE_API_KEY=your_binance_futures_testnet_api_key BINANCE_API_SECRET=your_binance_futures_testnet_api_secret DEFAULT_EXECUTION_MODE=MOCK
Run a diagnostic health check of connectivity, server time offsets, local caching, and key validations:
python cli.py ping --mode MOCKRun without parameters to launch the step-by-step interactive CLI configuration workflow:
python cli.py --mode MOCKpython cli.py --mode MOCK --symbol BTCUSDT --side BUY --type MARKET --quantity 0.05python cli.py --mode MOCK --symbol BTCUSDT --side SELL --type LIMIT --quantity 0.1 --price 68500Verify the compilation, precision normalization, and HMAC signing process for a planned LIMIT order without placing it:
python cli.py --mode DRY_RUN --symbol ETHUSDT --side BUY --type LIMIT --quantity 1.5 --price 3400 --verboseVerify error formatting and client resilience under simulated balance insufficiency:
python cli.py --mode MOCK --mock-failure insufficient_balance --symbol BTCUSDT --side BUY --type MARKET --quantity 10.0Execute the 18-test suite validating validator boundaries, price quantization rounding, signature hashing, failure interceptors, and the full place-order pipeline (validation → normalization → mock execution):
python -m unittest discover -s tests -p "test_*.py"The same suite (plus a no-network CLI smoke test) runs in GitHub Actions on every push — see .github/workflows/ci.yml.
trading_bot/
bot/
__init__.py
config.py # Centralized configuration management
enums.py # Typed domain Enums
exceptions.py # Domain-specific exceptions hierarchy
models.py # Type-hinted dataclass models
client.py # Persistent connection client & mock adapters
trading_service.py # Orchestrates business logic, caching, and precision rounding
validators.py # Local exchange limits validators
logging_config.py # Rotating log setup with mask filters
tests/
__init__.py
test_client.py # Signing & mock failures unit tests
test_validators.py # Validation boundary unit tests
test_trading_service.py # Precision normalization & end-to-end pipeline tests
.github/workflows/ci.yml # GitHub Actions CI (unit tests + CLI smoke test)
cli.py # Command-line entry point with interactive wizard
pyproject.toml # Build & dependency declarations
requirements.txt # Core dependency file
.env.example # Template environment config
.gitignore # Git exclusion definitions
README.md # Systems documentation & architecture map
logs/ # Rotating runtime logs (generated at runtime, git-ignored)
While optimized for simplicity, the modular architecture supports future migration toward asynchronous execution and higher-throughput workflows. The separation of the network client, validation engine, and business layers ensures that transport components can easily be ported to async libraries (such as httpx or aiohttp) and combined with WebSocket streams for real-time portfolio management.