253 lines
7.3 KiB
Markdown
253 lines
7.3 KiB
Markdown
# Package riskgate
|
|
|
|
**Ready-to-use TCP server infrastructure for centralized risk management**
|
|
*MIT License*
|
|
|
|
---
|
|
|
|
## What is this?
|
|
|
|
`riskgate` is a **KnitPkg package** that provides a complete TCP server framework for implementing centralized risk management in MetaTrader 5.
|
|
|
|
It provides:
|
|
|
|
- `RiskGateServer` — Ready-to-use TCP server with connection pooling, message framing, and JSON parsing
|
|
- `RiskGateHandler` — Base class for implementing custom risk management logic
|
|
- **Message framing** — Reliable JSON message exchange
|
|
- **Multi-client support** — Handle up to 32 simultaneous EA connections
|
|
- **Event-driven architecture** — Override simple methods to implement your risk rules
|
|
|
|
This package is designed to run as an **MQL5 Service** that EAs connect to via TCP sockets. The server receives trading signals (JSON), applies your risk rules, and responds with approved position sizes.
|
|
|
|
## 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
|
|
|
|
- **Package type** (`type: package`) — header-only library consumable by other KnitPkg projects
|
|
- **MQL5 target** — designed for MetaTrader 5
|
|
- **Compile support** — `kp compile` compiles the unit test script(s)
|
|
- **TCP server infrastructure** — Complete accept loop, client pool, and message framing
|
|
- **JSON protocol** — Automatic parsing and serialization using `@vivazzi/jason`
|
|
- **Extensible handler system** — Implement `OnSignal()` to apply your risk rules
|
|
- **Logging integration** — Built-in support for `@douglasrechia/logger`
|
|
- **Non-blocking I/O** — Low-latency message processing with configurable sleep intervals
|
|
|
|
---
|
|
|
|
## Installing as a dependency (recommended)
|
|
|
|
To add `riskgate` to your KnitPkg project:
|
|
|
|
```bash
|
|
kp add @douglasrechia/riskgate
|
|
```
|
|
|
|
---
|
|
|
|
## Basic usage (example)
|
|
|
|
### 1) Create a custom handler
|
|
|
|
```mql5
|
|
#include "../knitpkg/include/douglasrechia/riskgate/RiskGateHandler.mqh"
|
|
|
|
class MyRiskHandler : public RiskGateHandler
|
|
{
|
|
public:
|
|
void OnSignal(CJAVal& signal, CJAVal& response) override
|
|
{
|
|
string symbol = signal["symbol"].ToStr();
|
|
double requestedLot = signal["lot"].ToDbl();
|
|
|
|
// Apply your risk rules here
|
|
bool approved = true;
|
|
double approvedLot = requestedLot;
|
|
|
|
response["approved"] = approved;
|
|
response["lot"] = approvedLot;
|
|
response["reason"] = "";
|
|
}
|
|
|
|
string Name() override { return "MyRiskHandler"; }
|
|
};
|
|
```
|
|
|
|
### 2) Create an MQL5 Service
|
|
|
|
```mql5
|
|
#property service
|
|
|
|
#include "../knitpkg/include/douglasrechia/riskgate/RiskGateServer.mqh"
|
|
#include "riskgate-handler.mqh"
|
|
|
|
void OnStart()
|
|
{
|
|
douglasrechia::Logger log("RiskGate");
|
|
log.AddHandler(new douglasrechia::PrintLogger());
|
|
|
|
douglasrechia::RiskGateServer server(5555);
|
|
server.SetLogger(&log);
|
|
server.SetHandler(new MyHandler());
|
|
server.Run();
|
|
}
|
|
```
|
|
|
|
### 3) Connect from an EA
|
|
|
|
EAs must use the `RiskGateClient` from the `@douglasrechia/riskgate-ea` package:
|
|
|
|
```mql5
|
|
#include "../knitpkg/include/douglasrechia/riskgate-ea/RiskGateClient.mqh"
|
|
|
|
douglasrechia::RiskGateClient client("127.0.0.1", 5555);
|
|
|
|
int OnInit()
|
|
{
|
|
client.Connect();
|
|
return INIT_SUCCEEDED;
|
|
}
|
|
|
|
void OnDeinit(const int reason)
|
|
{
|
|
client.Disconnect();
|
|
}
|
|
|
|
void OnTick()
|
|
{
|
|
// Your trading system code is here...
|
|
// Use something like this to ask the Risk Gate
|
|
// Service the lot size for the position:
|
|
CJAVal signal, response;
|
|
signal["symbol"] = _Symbol;
|
|
signal["side"] = "BUY";
|
|
signal["stop_loss"] = 12.34;
|
|
|
|
bool online = client.RequestPositionSize(signal, response);
|
|
|
|
if (online) {
|
|
if(response["approved"].ToBool()) {
|
|
double positionSize = response["lot"].ToDbl();
|
|
OpenOrder(positionSize);
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
> Note: The `RiskGateClient` handles connection management, automatic reconnection, timeouts, and fallback policies.
|
|
|
|
---
|
|
|
|
## Exploring the project locally (optional)
|
|
|
|
If you want to explore how the riskgate package is structured, clone the repository and run the standard workflow.
|
|
|
|
### 1) Clone into MetaTrader `Scripts` folder (example)
|
|
|
|
```bash
|
|
# Go to your MetaTrader 'Scripts' directory.
|
|
# Tip: in MetaEditor, right-click the `Scripts` folder and choose "Open Folder".
|
|
cd "C:\Users\username\AppData\Roaming\MetaQuotes\Terminal\<TERMINAL_ID>\MQL5\Scripts"
|
|
|
|
git clone https://forge.mql5.io/DouglasRechia/riskgate.git
|
|
cd riskgate
|
|
```
|
|
|
|
### 2) Generate autocomplete
|
|
|
|
```bash
|
|
# Generates autocomplete / IntelliSense support for MetaEditor.
|
|
# This step will also resolve dependencies required by the test scripts.
|
|
kp autocomplete
|
|
```
|
|
|
|
### 3) Compile
|
|
|
|
```bash
|
|
kp compile
|
|
```
|
|
|
|
---
|
|
|
|
## Running unit tests
|
|
|
|
Unit tests are implemented as a MetaTrader **Script**.
|
|
|
|
1. Compile the project.
|
|
2. Restart MetaTrader (so the Navigator refreshes).
|
|
3. Run the generated unit test script from the Navigator on any chart.
|
|
4. Check results in the MetaTrader console (Experts/Scripts tab, depending on your setup).
|
|
|
|
The compiled binary is placed under the project `bin/` directory (and appears in the Navigator under the corresponding compiled location after refresh).
|
|
|
|
---
|
|
|
|
## Architecture
|
|
|
|
### Message Protocol
|
|
|
|
- **Separator**: `\r\n\r\n` (double CRLF)
|
|
- **Format**: JSON strings
|
|
- **Encoding**: UTF-8
|
|
|
|
### Server Components
|
|
|
|
- **RiskGateServer**: Main server class that handles the accept loop, client pool, and message dispatching
|
|
- **RiskGateHandler**: Abstract base class for implementing risk management logic
|
|
- **ClientSocket**: TCP socket wrapper from `@douglasrechia/sockets`
|
|
- **Logger**: Logging infrastructure from `@douglasrechia/logger`
|
|
|
|
### Signal Flow
|
|
|
|
1. EA sends JSON signal → Server receives and parses
|
|
2. Server calls `OnSignal()` on your handler
|
|
3. Handler populates response JSON
|
|
4. Server serializes and sends response → EA receives
|
|
|
|
---
|
|
|
|
## Dependencies
|
|
|
|
This package depends on:
|
|
|
|
- `@douglasrechia/logger` — Logging infrastructure
|
|
- `@douglasrechia/sockets` — TCP socket implementation
|
|
- `@vivazzi/jason` — JSON parsing and serialization
|
|
|
|
All dependencies are automatically resolved by KnitPkg.
|
|
|
|
---
|
|
|
|
## One-command download/build via the registry (optional)
|
|
|
|
You can also use `kp get` to query the registry for metadata and automatically download/build the latest stable version.
|
|
|
|
Example (run from your MetaTrader *Data Folder* root):
|
|
|
|
```bash
|
|
cd "C:\Users\username\AppData\Roaming\MetaQuotes\Terminal\<TERMINAL_ID>"
|
|
|
|
kp get mql5 @douglasrechia/riskgate
|
|
```
|
|
|
|
Restart MetaTrader afterward to refresh the Navigator, then run the unit test script as described above.
|
|
|
|
---
|
|
|
|
## 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.
|