-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
120 changed files
with
8,997 additions
and
508 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}") | ||
|
Oops, something went wrong.