Run the broker safety audit before going live on a new broker or after any change to your MT5 terminal connection. It takes about 30 seconds and confirms that the symbol parameters the bot assumes are what the broker actually exposes.
The MT5 API must be running and connected to the target broker before running this script. Start the API first with your broker credentials.
Running the audit
# BTCUSD (default — reads symbol from config.json)
python scripts/check_broker_limits.py
# Specific symbol
python scripts/check_broker_limits.py --symbol XAUUSD
The script connects to the API at API_URL (from .env), reads the symbol spec, fetches the live tick, and prints all attributes in grouped sections.
What to check
Work through these four checks in order. If any fail, do not go live until resolved.
1. Tick size and contract size
Point : 1.0
Digits : 2
Trade Contract Size: 1.0
For BTCUSD:
| Field | Expected | What it means |
|---|
point | 1.0 | 1 point = $1 movement per lot |
digits | 2 | Price quoted to 2 decimal places |
trade_contract_size | 1.0 | 1 lot = 1 BTC |
If point is 0.01 instead of 1.0, the bot’s pip value formula (pip_value = point × contract_size × lot) will be off by 100×. This is a hard blocker — do not go live.
2. Lot limits
Volume Min : 0.01
Volume Max : 100.0
Volume Step : 0.01
The bot requires volume_min ≤ 0.01. If the broker enforces a higher minimum (e.g., 0.1), lot sizing will fail silently on small accounts. Confirm:
volume_min is 0.01 or lower
volume_step is 0.01
volume_max is at least 1.0 (unlikely to be lower, but worth confirming)
3. Stops level
=== Stops & Limits ===
trade_stops_level : 0
trade_freeze_level : 0
trade_stops_level is the minimum distance in points that SL and TP must be from the current price. A value of 0 means the broker places no artificial minimum.
If trade_stops_level > 0, NOVOSKY enforces it automatically in bot.py — but confirm it is within a reasonable range. A stops level above 500 points ($500 for BTCUSD) would force SL distances far larger than the ATR-based sizing intends, which will skew your P/L significantly.
trade_freeze_level is the distance at which pending orders cannot be moved once price is nearby. A value of 0 is normal and expected.
4. Swap rates (swap-free check)
=== ALL Symbol Attributes ===
swap_long : -12.5
swap_short : -8.3
Swap charges are overnight fees applied when a position is held past the broker’s daily rollover time. For accounts marked as swap-free (Islamic), both values should be 0.0 or very close to it.
NOVOSKY passes --no-swap to the backtester when running on swap-free accounts. If the broker actually charges swaps but the backtest ran with --no-swap, the live performance will be worse than the OOS backtest indicated.
Confirm:
- If you expect swap-free: both
swap_long and swap_short should be 0.0
- If you expect swaps: note the values and rerun the OOS backtest with
--swap-long <value> to verify the model is still profitable after costs
Reference values: VT Markets BTCUSD
These values were verified on a VT Markets cent account (terminal-one.novosky.app). Re-run the audit if you change servers or account type.
| Check | Expected value |
|---|
point | 1.0 |
digits | 2 |
trade_contract_size | 1.0 |
volume_min | 0.01 |
volume_step | 0.01 |
trade_stops_level | 0 |
swap_long / swap_short | 0.0 (swap-free cent) |
| Spread at audit time | ~1500–1800 pts ($15–18) |
Reference values: IC Markets RAW BTCUSD
| Check | Expected value |
|---|
point | 1.0 |
volume_min | 0.01 |
trade_stops_level | 0 |
swap_long / swap_short | Non-zero (apply --swap-long / --swap-short in backtest) |
| Spread at audit time | ~300 pts ($3) |
Audit pass/fail criteria
Tick size OK
point = 1.0 and trade_contract_size = 1.0 for BTCUSD. Any other value is a blocker.
Lot limits OK
volume_min ≤ 0.01 and volume_step = 0.01. Minimum must be 0.01 or the bot cannot open minimum-size positions.
Stops level OK
trade_stops_level ≤ 200. Values above 200 pts reduce the effective SL range and should be evaluated against live ATR before trading.
Swap status matches backtest assumptions
If the account is swap-free, swaps must read 0.0. If swaps are non-zero, rerun OOS backtest with the correct swap flags.
If checks fail
| Symptom | Action |
|---|
point = 0.01 | Wrong symbol or broker sends non-standard spec. Contact broker support. Do not trade. |
volume_min > 0.01 | Adjust dynamic_position_sizing.min_lot in config.json to match. Risk sizing will use a larger floor. |
trade_stops_level > 200 | Run backtest with --stops-level <value> flag and confirm SL/TP placements still execute. Check OOS Score does not degrade by more than 5%. |
| Swaps non-zero on expected swap-free account | Re-run python backtest.py ... --swap-long <value> --swap-short <value> to measure real performance. |
Script errors HTTP 404 on symbol | Symbol name may differ per broker (e.g., BTCUSD. with a dot suffix). Run check_broker_limits.py --symbol BTCUSD. or check the broker’s symbol list via the MT5 API /symbols endpoint. |
Brokers with non-standard symbol names
Some brokers append a suffix to symbol names (., c, pro). If the script returns a 404:
# List all available symbols on the broker
curl -s -H "Authorization: Bearer $API_TOKEN" "$API_URL/symbols" | python3 -m json.tool | grep -i btc
Update config.json → "symbol" to match the broker’s exact name, then re-run the audit.