Skip to content

Commit

Permalink
Update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
Starmel committed Dec 25, 2024
1 parent 5fbb22e commit b38862f
Show file tree
Hide file tree
Showing 120 changed files with 8,997 additions and 508 deletions.
18 changes: 18 additions & 0 deletions .idea/deployment.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/sshConfigs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions .idea/webServers.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.0] - 2024-12-25

### Added
- Initial release of MT5 gRPC Server
- Basic MetaTrader 5 operations support through gRPC
- Protocol buffer definitions for MT5 operations
- Example client implementation
- Basic documentation
- Windows support under Wine for Linux/macOS users

### Dependencies
- Python >=3.8
- gRPC framework
- MetaTrader 5 terminal
- Required Python packages listed in requirements.txt
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 MT5-RPC-server

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
89 changes: 89 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Metatrader5 RPC Server 🚀

## 📋 Project Description
This project is a gRPC server for interacting with Metatrader 5, designed specifically to provide a convenient way to host an API service on Windows and interact with it using any programming language through gRPC. This approach allows you to build trading applications and services in your preferred language while keeping MetaTrader 5 running on Windows.

## 🏗️ Project Structure

The project consists of two main packages:

### 1. MT5 gRPC Proto (`mt5-grpc-proto`)
Protocol Buffers and gRPC service definitions package. Contains the contract between the MT5 gRPC server and its clients.

Installation:
```bash
pip install mt5-grpc-proto
```

### 2. MT5 gRPC Server (`mt5-grpc-server`)
The server implementation that interfaces with MetaTrader 5 terminal.

Installation:
```bash
pip install mt5-grpc-server
```

## ✨ Features
- Account information retrieval
- Trading symbol management
- Sending and checking trading orders
- Market data acquisition
- Position management
- Retrieving trade and order history
- Terminal information retrieval

## 💡 Key Benefits
- Run MetaTrader 5 on Windows while accessing it from any OS
- Build trading applications in any language that supports gRPC
- High-performance binary protocol communication
- Bi-directional streaming capabilities
- Type-safe API interface

## 🖥️ Server Usage

### Basic Start
```bash
mt5-grpc-server
```
The server will start on default port 50051 and host 0.0.0.0

### Secure Connection
```bash
mt5-grpc-server --host 127.0.0.1 --port 50052 --secure --cert-file server.crt --private-key-file server.key
```

### Command-line Options
- `--host HOST`: Host address to bind the server to (default: "0.0.0.0")
- `--port PORT`: Port number to listen on (default: 50051)
- `--secure`: Enable secure connection with SSL/TLS
- `--cert-file FILE`: Path to the SSL certificate file (required if --secure is used)
- `--private-key-file FILE`: Path to the private key file (required if --secure is used)

## 🛠️ Development Setup

1. Clone the repository:
```bash
git clone https://github.com/your-username/Metatrader5-gRPC-server.git
cd Metatrader5-gRPC-server
```

## 🔄 Generating Proto Files
To regenerate proto files during development, use:
```bash
./generate_proto.sh
```

## 🐧 Running Under Wine (Linux, MacOS)
If you need to run the server on Linux:
```bash
./start_server_under_wine.sh
```

## 📚 Usage Examples
See `client_example.py` for client code examples. You can implement clients in any language that supports gRPC.

## 📄 License
MIT License

## 🤝 Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
153 changes: 153 additions & 0 deletions client_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
from datetime import datetime, timedelta
import random

import grpc
from mt5_grpc_proto import common_pb2, common_pb2_grpc, position_pb2, deal_pb2, history_orders_pb2_grpc, position_pb2_grpc, \
symbol_info_pb2_grpc, history_orders_pb2, terminal_pb2, symbols_pb2_grpc, order_pb2, terminal_pb2_grpc
from mt5_grpc_proto import symbol_info_pb2, deal_pb2_grpc, order_pb2_grpc, symbols_pb2

if __name__ == '__main__':
with (grpc.insecure_channel('192.168.10.100:50051') as channel):
# Connect to MetaTrader
mt = common_pb2_grpc.MetaTraderServiceStub(channel)
mt.Connect(common_pb2.Empty())

# Get terminal info
terminal = terminal_pb2_grpc.TerminalInfoServiceStub(channel)
terminal_info = terminal.GetTerminalInfo(terminal_pb2.TerminalInfoRequest())
print("Terminal Info:")
print(terminal_info)

# Get symbols service stub
symbols = symbols_pb2_grpc.SymbolsServiceStub(channel)

# Get list of all symbols
symbols_list = symbols.GetSymbols(symbols_pb2.SymbolsGetRequest())
print("Available symbols:", [symbol for symbol in symbols_list.symbols])

# Select random symbol and set it as active
if symbols_list.symbols:
random_symbol = random.choice(symbols_list.symbols)
select_response = symbols.SelectSymbol(symbols_pb2.SymbolSelectRequest(
symbol=random_symbol,
enable=True
))
if select_response.success:
print(f"Selected random symbol: {random_symbol}")
else:
print(f"Failed to select symbol: {select_response.error.description}")

positions_total = position_pb2_grpc.PositionsServiceStub(channel).GetPositionsTotal(
position_pb2.PositionsTotalRequest()
)

print("Total positions: ", positions_total.total)

# Get all positions
# Get symbol info for EURUSD
symbol_info = symbol_info_pb2_grpc.SymbolInfoServiceStub(channel).GetSymbolInfo(symbol_info_pb2.SymbolInfoRequest(
symbol="EURUSD"
))

if symbol_info.error.code == 0:
info = symbol_info.symbol_info
print("\nEURUSD Symbol Details:")
print(f"Bid: {info.bid}")
print(f"Ask: {info.ask}")
print(f"Point: {info.point}")
print(f"Digits: {info.digits}")
print(f"Spread: {info.spread}")
print(f"Trade mode: {info.trade_mode}")
print(f"Volume min: {info.volume_min}")
print(f"Volume max: {info.volume_max}")
print(f"Volume step: {info.volume_step}")
else:
print(f"Failed to get EURUSD info: {symbol_info.error.message}")

# Get orders history
orders_service = order_pb2_grpc.OrdersServiceStub(channel)
orders = orders_service.GetOrders(order_pb2.OrdersGetRequest())
print("\nActive Orders:")
if orders.error.code == 0:
for order in orders.orders:
print(f"Order #{order.ticket}:")
print(f" Symbol: {order.symbol}")
print(f" Type: {order.type}")
print(f" Volume: {order.volume_current}")
print(f" Open Price: {order.price_open}")
print(f" Current Price: {order.price_current}")
print(f" Stop Loss: {order.stop_loss}")
print(f" Take Profit: {order.take_profit}")
print(f" Comment: {order.comment}")
else:
print(f"Failed to get orders: {orders.error.message}")

# Get deals history for the last day
trade_history = deal_pb2_grpc.TradeHistoryServiceStub(channel)

# Calculate timestamps for the last 24 hours
now = datetime.now()
yesterday = now - timedelta(days=10)

deals_request = deal_pb2.DealsRequest(
time_filter=common_pb2.TimeFilter(
date_from=int(yesterday.timestamp()),
date_to=int(now.timestamp())
)
)

deals = trade_history.GetDeals(deals_request)
print("\nDeals History (last 24 hours):")
if deals.error is None or deals.error.code == 0:
for deal in deals.deals:
print(f"Deal #{deal.ticket}:")
print(f" Symbol: {deal.symbol}")
print(f" Type: {deal.type}")
print(f" Entry: {deal.entry}")
print(f" Volume: {deal.volume}")
print(f" Price: {deal.price}")
print(f" Profit: {deal.profit}")
print(f" Commission: {deal.commission}")
print(f" Swap: {deal.swap}")
print(f" Comment: {deal.comment}")
else:
print(f"Failed to get deals history: {deals.error.message}")

# Get orders history for the last 10 days
history_orders_service = history_orders_pb2_grpc.HistoryOrdersServiceStub(channel)

# Get total number of orders in history
history_orders_total = history_orders_service.GetHistoryOrdersTotal(
history_orders_pb2.HistoryOrdersTotalRequest(
date_from=int(yesterday.timestamp()),
date_to=int(now.timestamp())
)
)
print(f"\nTotal orders in history for last 10 days: {history_orders_total.total}")

# Get detailed orders history
history_orders_request = history_orders_pb2.HistoryOrdersRequest(
time_filter=common_pb2.TimeFilter(
date_from=int(yesterday.timestamp()),
date_to=int(now.timestamp())
),
group="*" # Get all symbols
)

history_orders = history_orders_service.GetHistoryOrders(history_orders_request)
print("\nOrders History (last 10 days):")
if history_orders.error is None or history_orders.error.code == 0:
for order in history_orders.orders:
print(f"Order #{order.ticket}:")
print(f" Symbol: {order.symbol}")
print(f" Type: {order.type}")
print(f" State: {order.state}")
print(f" Volume Initial: {order.volume_initial}")
print(f" Volume Current: {order.volume_current}")
print(f" Price Open: {order.price_open}")
print(f" Stop Loss: {order.stop_loss}")
print(f" Take Profit: {order.take_profit}")
print(f" Comment: {order.comment}")
else:
print(f"Failed to get orders history: {history_orders.error.message}")

Loading

0 comments on commit b38862f

Please sign in to comment.