A clean, well-structured Python CLI application for placing orders on the Binance USDT-M Futures Testnet.
Supports MARKET, LIMIT, and STOP_MARKET orders with full input validation, structured logging, and clear error handling.
- Features
- Project Structure
- Setup
- Configuration
- Running the Bot
- CLI Reference
- Examples
- Logging
- Error Handling
- Assumptions
| Feature | Details |
|---|---|
| Order types | MARKET, LIMIT, STOP_MARKET |
| Sides | BUY, SELL |
| Validation | Symbol, side, type, quantity, price — all validated before any network call |
| Logging | Structured rotating log file (logs/trading_bot.log) with timestamps, levels, and module names |
| Error handling | Catches API errors, network failures, and invalid input separately |
| Architecture | Layered: client.py (HTTP) → orders.py (logic) → cli.py (user interface) |
| Bonus | STOP_MARKET order type, balance, positions, open-orders, and cancel commands |
trading_bot/
├── bot/
│ ├── __init__.py
│ ├── client.py # Binance REST API wrapper (signing, HTTP)
│ ├── orders.py # Order placement logic + OrderResult dataclass
│ ├── validators.py # Input validation (raises ValueError with clear messages)
│ └── logging_config.py # Rotating file + console logger setup
├── cli.py # CLI entry point (argparse sub-commands)
├── logs/
│ └── trading_bot.log # Rotating log file (created on first run)
├── requirements.txt
└── README.md
- Python 3.9 or higher
- A Binance Futures Testnet account
- Go to https://testnet.binancefuture.com
- Log in with your GitHub account
- Navigate to API Key → Generate Key
- Copy your API Key and Secret Key — the secret is shown only once
git clone https://github.com/your-username/trading-bot.git
cd trading_botpython3 -m venv .venv
source .venv/bin/activate # Linux / macOS
.venv\Scripts\activate # Windows PowerShellpip install -r requirements.txtSet your credentials as environment variables before running the bot.
Linux / macOS:
export BINANCE_API_KEY="your_testnet_api_key_here"
export BINANCE_API_SECRET="your_testnet_api_secret_here"Windows (PowerShell):
$env:BINANCE_API_KEY="your_testnet_api_key_here"
$env:BINANCE_API_SECRET="your_testnet_api_secret_here"Optional — using a .env file:
Create a .env file in the project root:
BINANCE_API_KEY=your_testnet_api_key_here
BINANCE_API_SECRET=your_testnet_api_secret_here
Then load it before running (requires python-dotenv, included in requirements.txt):
# In your shell session
export $(cat .env | xargs)Never commit your
.envfile or API credentials to version control.
Optional environment variables:
| Variable | Default | Description |
|---|---|---|
BINANCE_API_KEY |
(required) | Testnet API key |
BINANCE_API_SECRET |
(required) | Testnet API secret |
BINANCE_BASE_URL |
https://testnet.binancefuture.com |
API base URL |
LOG_LEVEL |
DEBUG |
Logging level: DEBUG, INFO, WARNING, ERROR |
All commands follow this pattern:
python cli.py <command> [options]
To see all available commands:
python cli.py --helpTo see options for a specific command:
python cli.py order --helppython cli.py order --symbol SYMBOL --side SIDE --type TYPE --quantity QTY [options]
| Argument | Required | Description |
|---|---|---|
--symbol |
✓ | Trading pair (e.g. BTCUSDT, ETHUSDT) |
--side |
✓ | BUY or SELL |
--type |
✓ | MARKET, LIMIT, or STOP_MARKET |
--quantity |
✓ | Number of contracts |
--price |
LIMIT only | Limit price |
--stop-price |
STOP_MARKET only | Trigger price |
--tif |
optional | Time-in-force: GTC (default), IOC, FOK |
--reduce-only |
optional | Only reduce an existing position |
python cli.py balance
python cli.py positions [--symbol SYMBOL]
python cli.py open-orders [--symbol SYMBOL]
python cli.py cancel --symbol SYMBOL --order-id ORDER_ID
python cli.py order \
--symbol BTCUSDT \
--side BUY \
--type MARKET \
--quantity 0.001Output:
╔══════════════════════════════════════════════════════════╗
║ BINANCE FUTURES TESTNET · TRADING BOT CLI ║
╚══════════════════════════════════════════════════════════╝
──────────────────────────────────────────────────
ORDER REQUEST SUMMARY (MARKET)
──────────────────────────────────────────────────
symbol : BTCUSDT
side : BUY
type : MARKET
quantity : 0.001
──────────────────────────────────────────────────
════════════════════════════════════════════════════
ORDER RESULT
════════════════════════════════════════════════════
✓ ORDER PLACED SUCCESSFULLY
Order ID : 8389765432
Client OID : xJ7kqR2mNpL9oT3vW4yA
Symbol : BTCUSDT
Side : BUY
Type : MARKET
Status : FILLED
Avg Price : 62345.10000
Orig Qty : 0.001
Executed Qty : 0.001
✓ Done.
python cli.py order \
--symbol BTCUSDT \
--side SELL \
--type LIMIT \
--quantity 0.001 \
--price 65000python cli.py order \
--symbol BTCUSDT \
--side SELL \
--type STOP_MARKET \
--quantity 0.001 \
--stop-price 60000python cli.py balancepython cli.py open-orders --symbol BTCUSDTpython cli.py cancel --symbol BTCUSDT --order-id 8389771209LOG_LEVEL=WARNING python cli.py order --symbol BTCUSDT --side BUY --type MARKET --quantity 0.001All activity is logged to logs/trading_bot.log with the following format:
TIMESTAMP | LEVEL | MODULE | MESSAGE
2025-05-08 09:12:03 | INFO | trading_bot.client | → POST /fapi/v1/order | params={...}
2025-05-08 09:12:03 | INFO | trading_bot.client | ← HTTP 200 | POST /fapi/v1/order | body={...}
2025-05-08 09:12:03 | INFO | trading_bot.orders | Market order placed — orderId=8389765432 status=FILLED
- Console shows
WARNINGand above only (to keep CLI output clean) - Log file records everything from
DEBUGlevel upward (configurable viaLOG_LEVEL) - Log files rotate at 10 MB, keeping up to 5 backups
- API signatures are never logged (only the non-sensitive parameters)
The bot handles three categories of errors:
| Category | Example | Behaviour |
|---|---|---|
| Input validation | Invalid side, missing price for LIMIT | Prints all validation errors, exits before any network call |
| API errors | Invalid symbol (-1121), insufficient balance |
Prints Binance error code + message, logs full details |
| Network failures | Timeout, connection refused | Prints descriptive message, logs exception with traceback |
Example — validation error:
✗ ERROR: Validation failed:
• Price is required for 'LIMIT' orders but was not provided.
Example — API error:
✗ ORDER FAILED
Error Code : -1121
Error Message: Invalid symbol.
- USDT-M Futures only — the bot targets the
/fapi/endpoints. Spot or COIN-M futures are not supported. - Credentials via environment variables — no credential prompts or config files are used for security.
- Single-leg orders only — bracket / OCO orders are not implemented (STOP_MARKET is the bonus order type).
- Testnet URL —
https://testnet.binancefuture.com. Switching to mainnet requires settingBINANCE_BASE_URL=https://fapi.binance.com(⚠ real funds). - Quantity precision — the bot does not enforce symbol-specific lot-size filters. Binance will reject orders that violate these filters with error
-1111. Check exchange info for exact step sizes. - No position mode check — the bot uses
positionSide=BOTH(one-way mode) by default. Hedge mode requirespositionSide=LONG/SHORT.