
Automated trading system for Saxo Bank's Knock-out warrants (Turbos), executing trades via webhook signals.
Warning
This is a personal learning project and not production-ready software.
Do not risk money which you are afraid to lose. USE THE SOFTWARE AT YOUR OWN RISK. THE AUTHORS AND ALL AFFILIATES ASSUME NO RESPONSIBILITY FOR YOUR TRADING RESULTS.
Always start by running WATA with small money amounts to test the system and its performance. Use a secondary Saxo account if possible. Understand the risks involved in trading before you start, and do not engage money before you understand how it works and what profit/loss you should expect.
Risk Warning: WATA CAN LOSE ALL YOUR MONEY due to:
- Insufficient code testing
- Limited security measures on your server
- Lack of fail-safe mechanisms
- No comprehensive monitoring included
- Absence of fail-over systems
- Limited user experience
- Change of Saxo Bank API
- Because trading with leverage is very risky
This software is provided "as is" without warranty. The authors accept no liability for any damages arising from its use.
WATA (Warrants Automated Trading Assistant) is an algorithmic trading system compagnon, designed for automated execution of Knock-out warrants (Turbos) on Saxo Bank. It serves as a reliable bridge between trading signals and actual market execution, offering several key benefits:
- Automated Execution: Eliminates emotional bias and human error by executing trades based on predefined rules and signals (from TradingView, for example)
- Risk Management: Implements systematic position monitoring with stop-loss and take-profit mechanisms
- Performance Tracking: Provides comprehensive analytics and reporting for trade analysis
- Real-time Monitoring: Delivers instant notifications via Telegram for trade execution and system status
- Scalability: Built on a microservice architecture for reliable and maintainable operation
The system is particularly suited for traders who:
- Want to automate their trading strategies
- Need reliable execution of trading signals
- Require comprehensive trade tracking and analysis
- Value real-time monitoring and alerts
- Prefer systematic, rule-based trading over discretionary decisions
WATA uses a microservice architecture with:
Component (roles) | Purpose |
---|---|
Web Server | Receives webhook signals from third party (like: TradingView) |
Trader | Executes Saxo Bank API operations |
Scheduler | Manages job orchestrations |
Telegram | Delivers notifications and alerts |
RabbitMQ | Handles inter-component messaging |
flowchart TD
%% Styling
classDef external fill:#f9f9f9,stroke:#aaa,stroke-width:1px,color:#000
classDef processing fill:#e1f5fe,stroke:#03a9f4,stroke-width:1px,color:#000
classDef execution fill:#e8f5e9,stroke:#4caf50,stroke-width:1px,color:#000
classDef jobs fill:#fff8e1,stroke:#ffc107,stroke-width:1px,color:#000
classDef database fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px,stroke-dasharray: 5 5,color:#000
classDef reporting fill:#ffebee,stroke:#f44336,stroke-width:1px,color:#000
%% External Systems
subgraph ExtSys["π External Systems"]
direction LR
TV("π₯οΈ TradingView/<br>Signal Source")
SB("π¦ Saxo Bank API")
User("π€ User/Trader")
TG("π± Telegram Service")
end
%% WATA Core Services
subgraph CoreSys["βοΈ WATA Core Services"]
direction TB
subgraph SigProc["π‘ Signal Processing"]
direction LR
WS("π Web Server")
RMQ("π¨ RabbitMQ<br>Message Broker")
end
subgraph ExecEng["πΉ Execution Engine"]
direction LR
TR("π± Trader Service")
DB[("πΎ DuckDB")]:::database
end
subgraph JobSvc["β±οΈ Jobs Orchestration"]
SC("π Scheduler")
end
end
%% Reporting System
subgraph RepSys["π Local Reporting System"]
direction LR
EX("π Data Export")
OD("π Observable<br>Dashboard")
end
%% Connections with styled arrows
TV -- "1οΈβ£ Webhook Signal" --> WS
WS -- "2οΈβ£ Signal Message" --> RMQ
RMQ -- "3οΈβ£ Position Request" --> TR
TR -- "Authentication" --> SB
User -- "Auth Code" --> TR
TR -- "4οΈβ£ Trading Operations" --> SB
TR -- "Send Notification" --> RMQ
RMQ -- "Notification Request" --> TG
TG -- "5οΈβ£ Notifications" --> User
TR <-- "Position Data" --> DB
SC -- "Periodic Tasks" --> RMQ
RMQ -- "Status Tasks" --> TR
TR <-- "Performance Data" --> DB
DB -. "6οΈβ£ Manual Data Sync" .-> EX
EX -. "Data Transform" .-> OD
OD -. "7οΈβ£ Performance<br>Visualization" .-> User
%% Apply styles
class TV,SB,User,TG external
class WS,RMQ processing
class TR,DB execution
class SC jobs
class EX,OD reporting
-
Signal Reception
- Validate incoming webhooks (authentication, schema)
- Parse action type (long, short, close)
-
Rule Validation
- Verify market hours, timestamp freshness
- Check allowed indices and position duplicates
- Apply daily profit limits
-
Trade Execution
- For new positions: instrument search, order calculation, position confirmation
- For closing: position retrieval, order creation, performance reporting
- Automatic position monitoring with stop-loss/take-profit handling
-
Performance Tracking
- Daily statistics generation
- Performance metrics reporting
- Database storage for analysis
WATA uses DuckDB for fast in-memory analytics:
- Order tracking: Complete order and positions history with execution details
- Position management: P&L calculations and performance metrics
- Performance analytics: Daily statistics and trading history
- Advantages: High-speed analytics, corruption prevention, SQL support
WATA uses OAuth 2.0 for Saxo Bank API integration:
- When authenticating, the application send you a URL via Telegram (or logs of container)
- Open this URL in your browser and log in with your Saxo credentials, and do all the steps to authorize the application (2FA, risk warning, etc.)
- After authorization, you'll be redirected to a page with a URL containing a
code
parameter - Copy the code and run
watasaxoauth
on your server (you will be prompted to enter the code securely) - The application completes authentication using this code
Command Reference:
watasaxoauth
: Run this command and you'll be prompted to enter the authorization code securely (the code won't be visible when typing)- The authorization code is valid only for a short time (typically a few minutes)
Troubleshooting:
- If you receive an invalid/expired code error, repeat the process
- A "Timeout waiting for authorization code" error means the application waited for 5 minutes without receiving the code
Please refer to the dedicated docs pages for Saxo Authentication for more details.
WATA uses token-based authentication to secure webhook endpoints:
- Each webhook request must include a valid token in the URL (e.g.,
/webhook?token=YOUR_TOKEN
) - This token is securely generated and stored with strong encryption
- Manage your webhook token with the
watawebtoken
command
Command Reference:
watawebtoken
: View your current webhook tokenwatawebtoken --new
: Generate a new webhook token- The command provides instructions on how to use the token in your webhook URL
Security Features:
- All tokens are encrypted before storage
- File permissions are restricted to the owner only
- IP address filtering adds an additional layer of security
For a comprehensive, step-by-step guide on setting up and using WATA, including:
- Detailed prerequisites and estimated costs
- Setting up Saxo Bank integration
- Configuring Telegram notifications
- Deploying and configuring WATA
- Setting up TradingView webhooks
- Starting and monitoring your trading
Please refer to our detailed HOW-TO Guide.
- Saxo Bank account with API access
- Dedicated Ubuntu server (on VPS or local machine)
- Docker and Docker Compose installed
- Python 3.12+
- Ansible (for automated deployment)
- Telegram bot for notifications
- (Optional) TradingView account for webhook signals
For detailed setup instructions, refer to our HOW-TO Guide.
-
Configure Inventory
- Copy the example Ansible inventory file:
cp deploy/tools/ansible/inventory/inventory_example.ini deploy/tools/ansible/inventory/inventory.ini
- Edit
inventory.ini
with your server details
- Copy the example Ansible inventory file:
-
Build Application
- Build the package:
./package.sh
- Build the package:
-
Deploy Application
- Run the deployment script:
cd deploy/tools ./deploy_app_to_your_server.sh
- The script will use Ansible to deploy the application to your server
- Run the deployment script:
-
Configure Application
- On the server, set up your credentials in
etc/config.json
(see below in Configuration section)
- On the server, set up your credentials in
-
Manage Application Use the following aliases on your server:
watastart
: Start the applicationwatastop
: Stop the applicationwatalogs
: View application logswatastatus
: Check application statuswatasaxoauth
: Launch the secure authorization code submission processwatawebtoken
: View your webhook authentication tokenwatawebtoken --new
: Generate a new webhook token
The application uses Docker Compose with an override file for enhanced configuration:
-
Environment Variables
- The system uses a
.env
file in thedeploy
directory to manage sensitive configuration. - The primary use is for setting the RabbitMQ password which is then synchronized with your config.json.
- The system uses a
-
Service Dependencies
- A special
setup
service runs before other services to ensure configuration is properly synchronized. - This setup updates the RabbitMQ password in your config.json file to match the one set in your .env file.
- All other services (web_server, trader, scheduler, telegram) depend on both the setup service and the RabbitMQ service.
- A special
After deployment, you need to set up your configuration:
-
Configure RabbitMQ Password
# Navigate to the deploy directory cd /app/deploy # Copy the example .env file cp .env.example .env # Edit the .env file to set your custom RabbitMQ password nano .env
This sets the password used by RabbitMQ and automatically updates your config.json file through the setup service in docker-compose.
-
Copy the Example Config
cp /app/etc/config_example.json /app/etc/config.json
-
Update Configuration Edit
/app/etc/config.json
with your specific settings:-
Saxo Bank Authentication
"authentication": { "saxo": { "app_config_object": { "AppName": "your_app_name", "AppKey": "your_app_key", "AppSecret": "your_app_secret" } } }
-
WebServer Security
"webserver": { "persistant": { "token_path": "/app/var/lib/web_server/persist_token.json" }, "app_secret": "YOUR_STRONG_SECRET_KEY" }
-
Telegram Notifications
"telegram": { "bot_token": "your_bot_token", "chat_id": "your_chat_id", "bot_name": "your_bot_name" }
-
Trading Rules
allowed_indices
: Configure allowed trading indicesmarket_closed_dates
: Set market holidaysday_trading
: Define profit targets and limits
-
Other Settings
- Logging configuration
- RabbitMQ connection details
- DuckDB database path
For a complete and detailed explanation of all configuration options, please refer to the CONFIGURATION Guide.
-
-
Restart Services
watastop watastart
Send trading signals to:
POST /webhook?token=YOUR_SECRET_TOKEN
Payload:
{
"action": "long",
"indice": "us100",
"signal_timestamp": "2023-07-01T12:00:00Z",
"alert_timestamp": "2023-07-01T12:00:01Z"
}
WATA includes a visualization dashboard built on Observable Framework:
- Daily/cumulative profit tracking
- Performance analysis by action type
- Win-rate and position duration metrics
- Interactive data exploration
(yeah, I'm still loosing money... but at least ... I know how much !)
To use the reporting system, you need:
- Node.js and npm installed
- DuckDB CLI installed
- Python 3.12+ (with required libraries
./reporting/requirements.txt
) - Ansible configured with proper inventory (same as deployment stage)
-
Run the Setup Script
./reporting/setup_dashboard.sh
This script creates a new Observable Framework project in
reporting/trading-dashboard
. -
Sync Trading Data
./reporting/sync_reporting_data.sh
This script synchronizes your trading data from the server to your local dashboard:
- Fetches DuckDB data from your production server
- Exports the database to Parquet format
- Generates the necessary JSON files for visualization
- Copies all data to the Observable Framework project
-
Start the Dashboard Server
./reporting/start_report_server.sh
This launches the development server on port 4321. Access the dashboard at: http://localhost:4321
Here are some of the most common questions about WATA:
- Is WATA suitable for beginners?
WATA requires understanding of trading concepts, Python, and server management. It's recommended for users with intermediate technical skills.
- What markets can I trade with WATA?
WATA supports trading Knock-out warrants (Turbos) available on Saxo Bank, primarily focusing on major indices.
- What are the minimum server requirements?
A basic VPS with 2GB RAM, 50GB SSD, 2 core CPU should be sufficient for getting started.
For a comprehensive list of questions and answers, please see our detailed FAQ documentation.
- @ioiti: Project author and maintainer
- @hootnot: Saxo OpenAPI library
We welcome contributions to WATA! Here's how you can help:
- Report Issues: Submit bugs or suggest features via GitHub issues
- Submit Pull Requests: Code improvements, documentation fixes, or new features
- Share Feedback: Let us know how you're using WATA and what could be improved
MIT License
Copyright (c) 2025 IOITI
WATA have a Docusaurus-based documentation website. The website is hosted on GitHub Pages and can be accessed at https://ioiti.github.io/wata-docs/.
The documentation is organized into the following sections:
- Introduction: Overview of WATA
- How-To Guide: Step-by-step instructions for setting up and using WATA
- Configuration Guide: Details on how to configure WATA
- Saxo Authentication: Guide for authenticating with Saxo Bank's API
- FAQ: Frequently asked questions about WATA
We welcome contributions to the documentation! If you find any errors or have suggestions for improvements, please submit a pull request or open an issue on this GitHub repository.