Files

9.6 KiB

MetaTrader 5 Trading Skill for QwenClaw

Overview

This skill enables QwenClaw to interact with MetaTrader 5 (MT5) for placing and managing trades on demo or live accounts.

Integration: Python MetaTrader5 package + MQL5


Prerequisites

1. Install MetaTrader 5 Python Package

pip install MetaTrader5

2. Ensure MT5 Terminal is Running

The MT5 terminal must be logged in and running before executing trades.

3. Configure Account

  • Demo account recommended for testing
  • Ensure auto-trading is enabled (Alt+A)

Usage

Place a Buy Order

Place a BUY order for EURUSD:
- Lot size: 0.1
- Stop Loss: 1.0800
- Take Profit: 1.0900

Place a Sell Order

Place a SELL order for GBPUSD:
- Lot size: 0.05
- Stop Loss: 1.2700
- Take Profit: 1.2500

Close All Positions

Close all open positions

Get Account Info

Show my MT5 account balance and equity

Get Open Positions

Show all open positions

Python Implementation

import MetaTrader5 as mt5
from datetime import datetime

class MT5Trader:
    def __init__(self):
        if not mt5.initialize():
            raise Exception("Failed to initialize MT5 connection")
    
    def get_account_info(self):
        account_info = mt5.account_info()
        return {
            "balance": account_info.balance,
            "equity": account_info.equity,
            "margin": account_info.margin,
            "profit": account_info.profit,
            "currency": account_info.currency,
        }
    
    def get_positions(self):
        positions = mt5.positions_get()
        if positions is None:
            return []
        return [
            {
                "symbol": pos.symbol,
                "type": "BUY" if pos.type == mt5.ORDER_TYPE_BUY else "SELL",
                "volume": pos.volume,
                "price_open": pos.price_open,
                "price_current": pos.price_current,
                "sl": pos.sl,
                "tp": pos.tp,
                "profit": pos.profit,
            }
            for pos in positions
        ]
    
    def place_order(
        self,
        symbol: str,
        order_type: str,
        volume: float,
        sl: float = None,
        tp: float = None,
        comment: str = "QwenClaw Trade"
    ):
        # Get symbol info
        symbol_info = mt5.symbol_info(symbol)
        if symbol_info is None:
            return {"success": False, "error": f"Symbol {symbol} not found"}
        
        # Check if symbol is visible
        if not symbol_info.visible:
            if not mt5.symbol_select(symbol, True):
                return {"success": False, "error": f"Failed to select symbol {symbol}"}
        
        # Get current price
        tick = mt5.symbol_info_tick(symbol)
        if tick is None:
            return {"success": False, "error": "Failed to get current price"}
        
        # Determine order type and price
        if order_type.upper() == "BUY":
            trade_type = mt5.ORDER_TYPE_BUY
            price = tick.ask
        else:
            trade_type = mt5.ORDER_TYPE_SELL
            price = tick.bid
        
        # Prepare order request
        request = {
            "action": mt5.TRADE_ACTION_DEAL,
            "symbol": symbol,
            "volume": volume,
            "type": trade_type,
            "price": price,
            "sl": sl if sl else 0,
            "tp": tp if tp else 0,
            "deviation": 20,
            "magic": 234000,
            "comment": comment,
            "type_time": mt5.ORDER_TIME_GTC,
            "type_filling": mt5.ORDER_FILLING_IOC,
        }
        
        # Send order
        result = mt5.order_send(request)
        
        if result.retcode != mt5.TRADE_RETCODE_DONE:
            return {
                "success": False,
                "error": f"Order failed: {result.comment}",
                "retcode": result.retcode,
            }
        
        return {
            "success": True,
            "order": result.order,
            "deal": result.deal,
            "volume": result.volume,
            "price": result.price,
            "comment": result.comment,
        }
    
    def close_position(self, ticket: int):
        position = mt5.positions_get(ticket=ticket)
        if not position:
            return {"success": False, "error": f"Position {ticket} not found"}
        
        pos = position[0]
        
        # Prepare close request
        if pos.type == mt5.ORDER_TYPE_BUY:
            trade_type = mt5.ORDER_TYPE_SELL
            price = mt5.symbol_info_tick(pos.symbol).bid
        else:
            trade_type = mt5.ORDER_TYPE_BUY
            price = mt5.symbol_info_tick(pos.symbol).ask
        
        request = {
            "action": mt5.TRADE_ACTION_DEAL,
            "symbol": pos.symbol,
            "volume": pos.volume,
            "type": trade_type,
            "position": ticket,
            "price": price,
            "deviation": 20,
            "magic": 234000,
            "comment": "Close position",
            "type_time": mt5.ORDER_TIME_GTC,
            "type_filling": mt5.ORDER_FILLING_IOC,
        }
        
        result = mt5.order_send(request)
        
        if result.retcode != mt5.TRADE_RETCODE_DONE:
            return {
                "success": False,
                "error": f"Close failed: {result.comment}",
            }
        
        return {
            "success": True,
            "deal": result.deal,
            "profit": result.profit,
        }
    
    def close_all_positions(self):
        positions = mt5.positions_get()
        if positions is None:
            return {"success": True, "closed": 0}
        
        closed = 0
        for pos in positions:
            result = self.close_position(pos.ticket)
            if result["success"]:
                closed += 1
        
        return {"success": True, "closed": closed}
    
    def disconnect(self):
        mt5.shutdown()


# Example usage
if __name__ == "__main__":
    trader = MT5Trader()
    
    # Get account info
    info = trader.get_account_info()
    print(f"Balance: {info['balance']} {info['currency']}")
    print(f"Equity: {info['equity']}")
    
    # Place a demo trade
    result = trader.place_order(
        symbol="EURUSD",
        order_type="BUY",
        volume=0.1,
        sl=1.0800,
        tp=1.0900
    )
    
    if result["success"]:
        print(f"Order placed: {result['order']} at {result['price']}")
    else:
        print(f"Order failed: {result['error']}")
    
    trader.disconnect()

QwenClaw Integration

Rig Agent Setup

import { RigClient } from "./rig";

const rig = new RigClient({ host: "127.0.0.1", port: 8080 });

// Create trading agent
const traderAgentId = await rig.createAgent({
  name: "mt5-trader",
  preamble: `You are a MetaTrader 5 trading assistant.
  
  When placing trades:
  1. Always confirm symbol, direction, lot size
  2. Set appropriate stop loss and take profit
  3. Use demo account for testing
  4. Report trade results clearly`,
  provider: "qwen",
  model: "qwen-plus",
});

// Place trade
const result = await rig.executePrompt(traderAgentId, `
  Place a BUY order for EURUSD with:
  - Lot size: 0.1
  - Stop Loss: 50 pips
  - Take Profit: 100 pips
`);

Trade Examples

Example 1: Simple Buy Order

Request:

Buy 0.1 lot EURUSD at market

Expected Result:

{
  "success": true,
  "order": 123456789,
  "deal": 987654321,
  "volume": 0.1,
  "price": 1.0850,
  "symbol": "EURUSD",
  "type": "BUY"
}

Example 2: Sell Order with SL/TP

Request:

Sell 0.05 lot GBPUSD
Stop Loss: 1.2700
Take Profit: 1.2500

Expected Result:

{
  "success": true,
  "order": 123456790,
  "volume": 0.05,
  "price": 1.2600,
  "sl": 1.2700,
  "tp": 1.2500,
  "symbol": "GBPUSD",
  "type": "SELL"
}

Example 3: Close All Positions

Request:

Close all open positions

Expected Result:

{
  "success": true,
  "closed": 3
}

Risk Management

Position Sizing

Account Balance Recommended Max Lot
$1,000 0.01 - 0.05
$5,000 0.05 - 0.10
$10,000 0.10 - 0.25
$50,000+ 0.25 - 0.50

Stop Loss Guidelines

  • EURUSD/GBPUSD: 20-50 pips typical
  • Gold (XAUUSD): 50-100 pips typical
  • Indices: 100-200 points typical

Risk Per Trade

  • Conservative: 1-2% of account per trade
  • Moderate: 2-3% of account per trade
  • Aggressive: 3-5% of account per trade (not recommended)

Error Codes

Retcode Description
10006 No connection
10013 Invalid request
10014 Invalid volume
10015 Invalid price
10016 Invalid stops
10019 Insufficient funds
10023 Request rejected
10032 Market closed

Safety Features

Demo Mode (Default)

  • Always use demo account first
  • Verify account type before trading

Confirmation Required

  • Always confirm trade details before execution
  • Show symbol, direction, volume, SL, TP

Logging

  • Log all trade requests
  • Log all trade results
  • Keep audit trail

Resources


Skill Metadata

name: metatrader5-trading
version: 1.0.0
category: trading
description: MetaTrader 5 trading integration for placing and managing forex/CFD trades
author: QwenClaw Team
license: MIT
tags:
  - trading
  - metatrader
  - mt5
  - forex
  - cfd
  - demo

Skill ready for QwenClaw integration! 📊💹