 
    
    
    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 codeparameter
- Copy the code and run watasaxoauthon 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 watawebtokencommand
Command Reference:
- watawebtoken: View your current webhook token
- watawebtoken --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.iniwith 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 application
- watastop: Stop the application
- watalogs: View application logs
- watastatus: Check application status
- watasaxoauth: Launch the secure authorization code submission process
- watawebtoken: View your webhook authentication token
- watawebtoken --new: Generate a new webhook token
 
The application uses Docker Compose with an override file for enhanced configuration:
- 
Environment Variables - The system uses a .envfile in thedeploydirectory 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 setupservice 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.jsonwith 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 indices
- market_closed_dates: Set market holidays
- day_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.

