Bybit Demo vs Live Trading: The Critical Truth Every Developer Must Know
TL;DR: They're Designed to be Identicalβ
Critical Finding: Bybit demo and live trading use IDENTICAL API endpoints and IDENTICAL trading rules. The ONLY difference is the domain:
- Live:
https://api.bybit.com - Demo:
https://api-demo.bybit.com
This is not an accident - it's intentional design for seamless transition.
The Research: What Bybit Actually Saysβ
From Bybit's official documentation:
"Basic trading rules are the same as real trading"
"Demo trading service is mainly for trading experience purpose"
API Endpoint Comparisonβ
Identical Endpointsβ
| Operation | Live API | Demo API |
|---|---|---|
| Place Order | POST /v5/order/create | POST /v5/order/create |
| Get Positions | GET /v5/position/list | GET /v5/position/list |
| Cancel Order | POST /v5/order/cancel | POST /v5/order/cancel |
| Get Balance | GET /v5/account/wallet-balance | GET /v5/account/wallet-balance |
Only Domain Differsβ
// Live trading
const liveClient = new BybitClient({
baseURL: 'https://api.bybit.com',
apiKey: 'live_key',
apiSecret: 'live_secret',
});
// Demo trading - SAME CODE, DIFFERENT DOMAIN
const demoClient = new BybitClient({
baseURL: 'https://api-demo.bybit.com', // <-- ONLY THIS CHANGES
apiKey: 'demo_key',
apiSecret: 'demo_secret',
});
Why This Matters for Mercury Architectureβ
The Original Misconceptionβ
I initially suggested separating demo and live services because I assumed they had different API constraints. This was completely wrong.
The Correct Architectureβ
Since endpoints are identical:
- Single BybitService: One service handles both demo and live
- Configuration-Based Switching: Change only the
baseURLconfiguration - Identical Code Paths: Same validation, same error handling, same response processing
class BybitService {
constructor(config: {
baseURL: string; // Only this differs between demo/live
apiKey: string;
apiSecret: string;
}) {
// Same implementation for both demo and live
}
async placeOrder(params: OrderParams) {
// IDENTICAL logic for demo and live
return this.client.post('/v5/order/create', params);
}
}
The Strategic Value of Demo Tradingβ
Demo trading is NOT just for "testing how much money you'd lose". It serves critical purposes:
1. Strategy Validationβ
- Test algorithms with real market data
- Validate order execution logic
- Confirm risk management rules
2. Seamless Deploymentβ
- Develop and test on demo
- Switch
baseURLto deploy to live - Zero code changes required
3. Continuous Testingβ
- Run parallel demo instance for ongoing validation
- Test new strategies without risking capital
- Monitor performance differences
Implementation in Mercuryβ
Unified Position Entityβ
// Single entity handles both demo and live positions
@Entity('positions')
export class Position {
@Column()
symbol: string;
@Column()
size: number;
@Column()
entryPrice: number;
@Column({ type: 'enum', enum: ['demo', 'live', 'shadow'] })
positionType: PositionType; // <-- Only this field distinguishes types
}
Instance Configurationβ
// W Instance: Live trading
const wInstanceConfig = {
bybit: {
baseURL: 'https://api.bybit.com',
// ... live credentials
},
};
// R Instance: Demo trading (mirrors W exactly)
const rInstanceConfig = {
bybit: {
baseURL: 'https://api-demo.bybit.com', // <-- ONLY DIFFERENCE
// ... demo credentials
},
};
Lessons for Architecture Designβ
1. Research Before Assumingβ
Never assume API differences without checking documentation. I made a critical error by assuming demo APIs had different constraints.
2. Leverage Vendor Designβ
Bybit designed demo/live to be identical for a reason. Our architecture should leverage this, not fight it.
3. Configuration Over Code Duplicationβ
When vendors provide identical interfaces, use configuration to switch behavior, not separate codebases.
The Corrected Mercury Strategyβ
Instance Rolesβ
- W Instance: Live trading with conservative risk management
- R Instance: Demo trading (perfect mirror of W for validation)
- ABH Instance: Shadow portfolio for unrestricted market intelligence
Unified Implementationβ
- Single
BybitServicewith configurable domain - Single
Positionentity with type discrimination - Identical trading logic across all instances
Conclusionβ
Bybit's demo trading is designed for seamless transition to live trading. They use identical APIs because the goal is to test your code with real market conditions, then deploy with confidence by changing only the domain.
This architectural insight eliminates unnecessary complexity and aligns our implementation with vendor intentions.
Key Takeaway: When in doubt about external APIs, read the fucking documentation before making assumptions.
