Algorithmic trading, the use of computer programs to execute trading strategies, has revolutionized financial markets. For developers looking to leverage Python’s capabilities in this domain, Deriv offers a compelling platform. This article guides you through starting to create a Python trading bot specifically tailored for Deriv.
Overview of Deriv and Its Trading Platform
Deriv is an established online trading provider offering a wide range of assets, including forex, commodities, stock indices, and its popular synthetic indices which are available 24/7. Key features attractive for algorithmic trading include:
- Diverse Instruments: Access to various markets allows for diversified trading strategies.
- Synthetic Indices: Unique, proprietary indices that simulate real-world market volatility and are not affected by global events or market hours.
- Multiple Trading Interfaces: Including DTrader, DBot (a visual strategy builder), and DMT5 (for MetaTrader 5 integration).
For programmatic trading, the Deriv API is the primary interface we will focus on.
Why Use Python for Deriv Trading Bots?
Python stands out as a preferred language for algorithmic trading due to several factors:
- Extensive Libraries: Rich ecosystem including
pandasfor data manipulation,NumPyfor numerical operations,SciPyfor scientific computing, andwebsocket-clientfor real-time communication. - Ease of Prototyping: Python’s syntax allows for rapid development and testing of trading ideas.
- Strong Community Support: A vast global community contributes to a wealth of resources, tutorials, and third-party packages.
- API Integration: Python excels at integrating with APIs, making it ideal for connecting to services like the Deriv API.
Introduction to the Deriv API: Key Features and Functionality
The Deriv API is a WebSocket-based service that allows developers to build custom trading applications. Its core functionalities include:
- Real-time Data: Streaming of ticks and candles for various instruments.
- Account Management: Access to account information, balances, and portfolio.
- Trading Operations: Programmatic placement and management of trades (proposals, buying contracts, selling contracts).
- Historical Data: Ability to fetch historical price data for backtesting and analysis.
The API uses JSON for message formats, making it straightforward to work with in Python.
Setting Up Your Python Environment for Deriv Trading
A correctly configured environment is crucial for developing your trading bot.
Installing Python and Essential Libraries (requests, json, pandas)
Ensure you have Python 3.7+ installed. It’s highly recommended to use a virtual environment (venv) for project isolation:
python -m venv deriv_bot_env
source deriv_bot_env/bin/activate # On Linux/macOS
# deriv_bot_env\Scripts\activate # On Windows
Install necessary libraries:
pip install websocket-client pandas
websocket-client: For connecting to the Deriv WebSocket API.pandas: For data analysis and manipulation, especially useful for handling time series data like prices and indicators.
The json library is built-in with Python and will be used for message formatting.
Obtaining a Deriv API Token and Understanding Authentication
To interact with the Deriv API, you need an API token:
- Log in to your Deriv account (or create one – a demo account is recommended for development).
- Navigate to Settings > Security & Limits > API Token.
- Create a new token. Ensure you give it appropriate scopes (e.g., ‘Read’, ‘Trade’, ‘Payments’, ‘Admin’). For trading, ‘Trade’ and ‘Read’ are essential.
- Securely store your API token. Treat it like a password.
Authentication with the Deriv API involves sending an authorize request with your token shortly after establishing the WebSocket connection.
Configuring Your Development Environment (IDE, Text Editor)
Choose an Integrated Development Environment (IDE) or text editor that suits your workflow. Popular choices for Python development include:
- Visual Studio Code (VS Code): Lightweight, extensible, with excellent Python support.
- PyCharm: A feature-rich IDE specifically for Python, with robust debugging and project management tools.
Ensure your chosen environment is configured with your Python interpreter from the virtual environment.
Building a Basic Deriv Trading Bot with Python
Let’s outline the steps to create a fundamental trading bot.
Connecting to the Deriv API and Authenticating
Here’s how you can connect and authenticate using the websocket-client library:
import websocket
import json
import threading
import time
APP_ID = '1089' # Default App ID for general use, or your own
API_TOKEN = 'YOUR_API_TOKEN' # Replace with your actual token
WS_URL = f"wss://ws.binaryws.com/websockets/v3?app_id={APP_ID}"
def on_open(ws):
print("WebSocket connection opened.")
auth_payload = {
"authorize": API_TOKEN
}
ws.send(json.dumps(auth_payload))
def on_message(ws, message):
data = json.loads(message)
print(f"Received: {json.dumps(data, indent=2)}")
if 'authorize' in data.get('echo_req', {}):
if data.get('error'):
print(f"Authorization failed: {data['error']['message']}")
else:
print(f"Successfully authorized. Account: {data['authorize']['loginid']}")
# Bot logic can start here, e.g., subscribe to ticks
# subscribe_ticks(ws, 'R_100') # Example symbol
# Handle other message types (ticks, candles, proposal responses, etc.)
elif 'tick' in data:
print(f"Tick: {data['tick']['symbol']} - {data['tick']['quote']}")
# Implement trading logic based on ticks
elif 'candles' in data:
print(f"Candles: {len(data['candles'])} received for {data['echo_req']['ticks_history']}")
# Process candle data for strategy calculation
elif 'proposal' in data:
# Handle proposal response to make a buy decision
handle_proposal(ws, data)
elif 'buy' in data:
# Handle buy confirmation or error
handle_buy_confirmation(ws, data)
def on_error(ws, error):
print(f"Error: {error}")
def on_close(ws, close_status_code, close_msg):
print("WebSocket connection closed.")
# Global variable to store proposal details for buying
latest_proposal_info = {}
def handle_proposal(ws, data):
global latest_proposal_info
if data.get('error'):
print(f"Proposal failed: {data['error']['message']}")
return
proposal = data['proposal']
print(f"Proposal received: ID {proposal['id']}, Payout: {proposal['payout']}, Stake: {proposal['stake']}")
# Store proposal ID and price for buying if strategy conditions are met
# For simplicity, let's assume we always want to buy if proposal is successful
# In a real bot, you'd check your strategy signals here before buying
latest_proposal_info = {'id': proposal['id'], 'price': proposal['ask_price']}
# Example: buy_contract(ws, latest_proposal_info['id'], latest_proposal_info['price'])
def handle_buy_confirmation(ws, data):
if data.get('error'):
print(f"Buy failed: {data['error']['message']}")
return
buy_details = data['buy']
print(f"Contract purchased: ID {buy_details['contract_id']}, Transaction ID: {buy_details['transaction_id']}")
print(f"Details: {buy_details['longcode']}")
# Example: ws = websocket.WebSocketApp(WS_URL, on_open=on_open, on_message=on_message, on_error=on_error, on_close=on_close)
# ws_thread = threading.Thread(target=ws.run_forever)
# ws_thread.start()
Remember to replace YOUR_API_TOKEN.
Fetching Market Data (Ticks, Candles) from Deriv
Once authenticated, you can request market data.
Subscribing to Ticks (Real-time Price Updates):
def subscribe_ticks(ws, symbol):
payload = {
"ticks_history": symbol,
"end": "latest",
"count": 1, # For a single latest tick, effectively
"subscribe": 1 # Key to get continuous updates
}
ws.send(json.dumps(payload))
print(f"Subscribed to ticks for {symbol}")
# Call this after successful authorization in on_message
# Example: subscribe_ticks(ws, 'R_100')
Requesting Historical Candle Data:
def request_candles(ws, symbol, timeframe_seconds=60, count=100):
payload = {
"ticks_history": symbol,
"adjust_start_time": 1,
"count": count,
"end": "latest",
"style": "candles",
"granularity": timeframe_seconds # e.g., 60 for 1-min, 300 for 5-min, 3600 for 1-hour
}
ws.send(json.dumps(payload))
print(f"Requested {count} candles for {symbol} with {timeframe_seconds}s granularity.")
# Call this after successful authorization
# Example: request_candles(ws, 'R_100', 60, 100) # 100 M1 candles
Handle responses for 'ticks_history' (for candles) and 'tick' (for subscribed ticks) in your on_message function.
Implementing Basic Trading Logic (e.g., Simple Moving Average Crossover)
Let’s outline how to calculate SMAs using pandas from candle data and generate signals. Assume you have collected candle data into a list of dictionaries, then converted to a DataFrame.
# Inside on_message, when 'candles' data is received:
# candles_list = data['candles']
# df = pd.DataFrame(candles_list)
# df['close'] = pd.to_numeric(df['close'])
# df['epoch'] = pd.to_datetime(df['epoch'], unit='s')
# df = df.set_index('epoch')
def calculate_sma_signal(df, short_window=5, long_window=20):
if len(df) < long_window:
return 0 # Not enough data
df['short_sma'] = df['close'].rolling(window=short_window).mean()
df['long_sma'] = df['close'].rolling(window=long_window).mean()
latest_short_sma = df['short_sma'].iloc[-1]
latest_long_sma = df['long_sma'].iloc[-1]
prev_short_sma = df['short_sma'].iloc[-2]
prev_long_sma = df['long_sma'].iloc[-2]
# Buy signal: short SMA crosses above long SMA
if prev_short_sma <= prev_long_sma and latest_short_sma > latest_long_sma:
return 1 # Buy
# Sell signal: short SMA crosses below long SMA
elif prev_short_sma >= prev_long_sma and latest_short_sma < latest_long_sma:
return -1 # Sell (or Put for options)
return 0 # No signal
# df_candles = ... (your DataFrame of candle data)
# signal = calculate_sma_signal(df_candles)
# if signal == 1:
# # Initiate Buy/Call option logic
# print("SMA Crossover: BUY signal")
# # Example: request_proposal_for_contract(ws, 'R_100', 'CALL', 10, 5, 't')
# elif signal == -1:
# # Initiate Sell/Put option logic
# print("SMA Crossover: SELL/PUT signal")
# # Example: request_proposal_for_contract(ws, 'R_100', 'PUT', 10, 5, 't')
Placing and Managing Orders (Buy/Sell, Stop Loss, Take Profit)
Trading on Deriv via API typically involves two steps for options-style contracts:
- Request a Proposal: Get terms for a potential contract.
- Buy the Contract: If the proposal is acceptable, buy using the
proposal_id.
def request_proposal_for_contract(ws, symbol, contract_type, amount, duration, duration_unit, barrier_offset=None):
# contract_type: e.g., 'CALL', 'PUT', 'HIGHER', 'LOWER'
# amount: stake amount
# duration: e.g., 5
# duration_unit: 't' (ticks), 's' (seconds), 'm' (minutes), 'h' (hours), 'd' (days)
payload = {
"proposal": 1,
"amount": amount,
"basis": "stake",
"contract_type": contract_type,
"currency": "USD", # Or your account currency
"duration": duration,
"duration_unit": duration_unit,
"symbol": symbol
}
if barrier_offset:
payload['barrier'] = barrier_offset # For contracts like HIGHER/LOWER
print(f"Requesting proposal: {payload}")
ws.send(json.dumps(payload))
def buy_contract(ws, proposal_id, price):
payload = {
"buy": proposal_id,
"price": price # This is the ask_price from the proposal response
}
print(f"Buying contract with proposal ID: {proposal_id} at price: {price}")
ws.send(json.dumps(payload))
# In your trading logic, after a signal:
# if signal == 1: # Buy signal
# request_proposal_for_contract(ws, 'R_100', 'CALL', 10, 5, 't')
# Upon receiving proposal in on_message and handle_proposal:
# if strategy_confirms_trade_with_proposal(proposal_data):
# buy_contract(ws, proposal_data['proposal']['id'], proposal_data['proposal']['ask_price'])
Managing Open Positions:
- Stop Loss/Take Profit: For Deriv’s proprietary contracts (options), traditional SL/TP parameters are not set at order entry like in CFD trading. Management involves monitoring the contract’s current value (if it’s sellable before expiry) and deciding to sell it via the
sellAPI call if certain profit/loss conditions are met. For contracts traded on DMT5 via Deriv, standard MT5 SL/TP mechanisms apply, typically managed through MT5-specific API interactions if not using the Deriv API directly for those. - Selling Contracts: Some contracts can be sold before expiry. Use the
sellAPI call with thecontract_idand desired price.
Always refer to the official Deriv API documentation for the precise JSON structures and available parameters for different contract types as they can evolve.
Customizing and Enhancing Your Deriv Trading Bot
Beyond basic functionality, consider these enhancements:
Implementing Advanced Trading Strategies (e.g., Martingale, Fibonacci)
- Martingale: A strategy that doubles the stake after each loss, aiming to recover previous losses with a single win. Warning: Martingale is extremely risky and can lead to rapid capital depletion. Implement with extreme caution and strict limits.
- Fibonacci Retracements/Extensions: Used to identify potential support and resistance levels. Logic would involve calculating Fibonacci levels based on recent swing highs and lows from candle data and using these levels as entry or exit points.
These require more complex state management and data analysis within your bot.
Integrating Risk Management Techniques (Position Sizing, Drawdown Control)
Effective risk management is paramount:
- Position Sizing: Determine the stake for each trade. Options include:
- Fixed Stake: Using the same amount for every trade.
- Fixed Fractional: Risking a fixed percentage of your account balance per trade (e.g., 1-2%).
- Drawdown Control: Set limits on acceptable losses:
- Max Daily Loss: Stop trading for the day if losses exceed a certain percentage of your capital.
- Max Drawdown: A limit on the total peak-to-trough decline in your account balance.
Adding Error Handling and Logging for Robustness
- Comprehensive Error Handling: Use
try-exceptblocks for API calls, data processing, and any I/O operations. Handle specific API errors returned by Deriv. - Logging: Implement Python’s
loggingmodule to record events, trades, errors, and system status. This is crucial for debugging and monitoring.
python
import logging
logging.basicConfig(level=logging.INFO, filename='trading_bot.log',
format='%(asctime)s - %(levelname)s - %(message)s')
logging.info("Bot started")
# ... later ...
# logging.error("Failed to place trade: ...")
- Reconnection Logic: Implement automatic reconnection for the WebSocket in case of network issues.
Backtesting and Optimization Strategies for Your Bot
Before live trading, thoroughly backtest your strategy:
- Data Acquisition: Fetch historical candle data from Deriv for the instruments and timeframes your strategy uses.
- Simulation Engine: Write Python code to simulate your strategy’s execution on historical data. Iterate through candles, apply your logic, simulate trades, and track profit/loss.
- Performance Metrics: Evaluate using metrics like Net Profit, Sharpe Ratio, Max Drawdown, Win Rate.
- Optimization: Systematically vary strategy parameters (e.g., SMA periods, stake size) to find optimal settings. Be wary of overfitting, where parameters perform well on historical data but poorly on live data. Techniques like walk-forward optimization can help mitigate this.
While libraries like Backtrader are popular, adapting them to Deriv’s specific contract types and data format might require custom extensions. A simpler custom backtester might be more straightforward initially for Deriv’s unique offerings.
Advanced Features and Considerations
For more sophisticated bots:
Utilizing WebSockets for Real-time Data Streaming
As shown, WebSockets are fundamental for Deriv. Efficiently handling asynchronous messages is key. Your on_message handler becomes the central dispatcher for incoming data, routing it to appropriate processing functions (e.g., tick processor, candle updater, order confirmation handler).
Implementing a User Interface (GUI or Web-based) for Your Bot
For easier monitoring and control:
- GUI: Libraries like
Tkinter(built-in),PyQt, orKivycan create desktop applications. - Web-based UI: Frameworks like
FlaskorDjangoallow you to build a web interface, accessible from any browser, even remotely.
This UI could display current balance, open positions, performance charts, and allow manual intervention or parameter adjustments.
Deploying Your Bot to a Server (e.g., AWS, Heroku) for 24/7 Trading
For continuous operation:
- Cloud Providers: AWS (EC2), Google Cloud (Compute Engine), Heroku, or DigitalOcean offer virtual private servers (VPS).
- Reliability: Ensure your server environment is stable with sufficient resources.
- Process Management: Use tools like
supervisor(Linux) orpm2(Node.js, but can manage Python scripts) to keep your bot running and automatically restart it if it crashes. - Security: Secure your server, API keys, and any sensitive data.
Ethical Considerations and Responsible Trading Practices
- Understand the Risks: Algorithmic trading does not guarantee profits. Markets are unpredictable.
- Start Small: Begin with a demo account, then move to a live account with small capital you can afford to lose.
- No Over-leveraging: Be cautious with leverage if trading instruments that offer it (e.g., CFDs on MT5).
- Continuous Monitoring: Regularly check your bot’s performance and behavior.
- Compliance: Adhere to Deriv’s Terms and Conditions and any relevant financial regulations.
- Avoid Unrealistic Expectations: