150 lines
4.4 KiB
Markdown
150 lines
4.4 KiB
Markdown
|
|
# Service riskgate-example
|
||
|
|
|
||
|
|
**Demonstration of a Risk Gate service built with `@douglasrechia/riskgate`**
|
||
|
|
*MIT License*
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## What is this?
|
||
|
|
|
||
|
|
`riskgate-example` is a **KnitPkg service** that demonstrates how to build a centralized risk management service for MetaTrader 5 using the [`@douglasrechia/riskgate`](https://forge.mql5.io/DouglasRechia/riskgate) package.
|
||
|
|
|
||
|
|
It shows how to:
|
||
|
|
|
||
|
|
- Implement a custom `RiskGateHandler` with your own risk rules and position sizing logic
|
||
|
|
- Start a `RiskGateServer` that listens for incoming EA connections on a TCP port
|
||
|
|
- Parse trading signals sent by EAs (JSON), apply risk rules, and respond with approved lot sizes
|
||
|
|
|
||
|
|
This project is intended as a **starting point** — rename the files, implement `OnSignal()` with your own logic, and you have a working risk gate service.
|
||
|
|
|
||
|
|
## Prerequisites
|
||
|
|
|
||
|
|
To use this project, you will need:
|
||
|
|
|
||
|
|
1. [**MetaTrader 5**](https://www.mql5.com/) installed.
|
||
|
|
2. **KnitPkg CLI**: The KnitPkg package manager for MetaTrader. If you don't have it, you can install it by following the instructions in the [main KnitPkg repository](https://github.com/knitpkg-dev/knitpkg-mt.git).
|
||
|
|
3. **KnitPkg homepage**: See [https://knitpkg.dev](https://knitpkg.dev) for an overview and [https://docs.knitpkg.dev](https://docs.knitpkg.dev) for documentation.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Features
|
||
|
|
|
||
|
|
- **Service type** (`type: service`) — runs as an MQL5 Service in MetaTrader 5
|
||
|
|
- **MQL5 target** — designed for MetaTrader 5
|
||
|
|
- **Compile support** — `kp compile` compiles the service
|
||
|
|
- **Custom handler** — `MyHandler` in `src/riskgate-handler.mqh` shows how to implement `OnSignal()`
|
||
|
|
- **JSON protocol** — signals and responses are exchanged as JSON via TCP
|
||
|
|
- **Logging** — built-in logging via `@douglasrechia/logger`
|
||
|
|
- **Multi-client** — handles up to 32 simultaneous EA connections
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Getting started
|
||
|
|
|
||
|
|
### 1) Clone into MetaTrader `Services` folder
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Go to your MetaTrader 'Services' directory.
|
||
|
|
# Tip: in MetaEditor, right-click the `Services` folder and choose "Open Folder".
|
||
|
|
cd "C:\Users\username\AppData\Roaming\MetaQuotes\Terminal\<TERMINAL_ID>\MQL5\Services"
|
||
|
|
|
||
|
|
git clone https://forge.mql5.io/DouglasRechia/riskgate-service-example.git
|
||
|
|
cd riskgate-service-example
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2) Install dependencies
|
||
|
|
|
||
|
|
```bash
|
||
|
|
kp install
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3) Compile
|
||
|
|
|
||
|
|
```bash
|
||
|
|
kp compile
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4) Run the service
|
||
|
|
|
||
|
|
After a successful compilation, restart MetaTrader so the Navigator refreshes. Then attach the service from the Navigator under **Services**.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Project structure
|
||
|
|
|
||
|
|
```
|
||
|
|
src/
|
||
|
|
riskgate-example.mq5 # Service entry point — starts the server
|
||
|
|
riskgate-handler.mqh # MyHandler — implement your risk rules here
|
||
|
|
knitpkg.yaml # Project manifest
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Implementing your own handler
|
||
|
|
|
||
|
|
Open `src/riskgate-handler.mqh` and implement `OnSignal()` with your risk rules:
|
||
|
|
|
||
|
|
```mql5
|
||
|
|
void OnSignal(CJAVal& signal, CJAVal& response) override
|
||
|
|
{
|
||
|
|
string symbol = signal["symbol"].ToStr();
|
||
|
|
string side = signal["side"].ToStr();
|
||
|
|
double stopLoss = signal["stop_loss"].ToDbl();
|
||
|
|
|
||
|
|
// Apply your risk rules here (drawdown checks, correlation, daily loss limits, etc.)
|
||
|
|
double lot = CalculateLot(symbol, stopLoss);
|
||
|
|
|
||
|
|
response["approved"] = (lot > 0.0);
|
||
|
|
response["lot"] = lot;
|
||
|
|
response["reason"] = lot > 0.0 ? "" : "risk_limit_reached";
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
The signal structure is defined by your EA — no schema is enforced by the server.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Connecting from an EA
|
||
|
|
|
||
|
|
EAs connect to this service using the `RiskGateClient` from the [`@douglasrechia/riskgate-ea`](https://forge.mql5.io/DouglasRechia/riskgate-ea) package:
|
||
|
|
|
||
|
|
```mql5
|
||
|
|
douglasrechia::RiskGateClient client("127.0.0.1", 5555);
|
||
|
|
|
||
|
|
void OnTick()
|
||
|
|
{
|
||
|
|
CJAVal signal, response;
|
||
|
|
signal["symbol"] = _Symbol;
|
||
|
|
signal["side"] = "BUY";
|
||
|
|
signal["stop_loss"] = 12.34;
|
||
|
|
|
||
|
|
bool online = client.RequestPositionSize(signal, response);
|
||
|
|
|
||
|
|
if(online && response["approved"].ToBool())
|
||
|
|
OpenOrder(response["lot"].ToDbl());
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Dependencies
|
||
|
|
|
||
|
|
This project depends on:
|
||
|
|
|
||
|
|
- [`@douglasrechia/riskgate`](https://forge.mql5.io/DouglasRechia/riskgate) — TCP server infrastructure and handler base class
|
||
|
|
|
||
|
|
All dependencies are automatically resolved by KnitPkg.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## License
|
||
|
|
|
||
|
|
This project is released under the **MIT License**. See `LICENSE` for details.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Disclaimer
|
||
|
|
|
||
|
|
This code is provided **as-is**, for **educational purposes only**.
|
||
|
|
No warranty (express or implied) is provided. Use at your own risk.
|