Stop Copy‑Pasting Code: One Command That Changes How You Build MQL5 Projects

Stop Copy‑Pasting Code: One Command That Changes How You Build MQL5 Projects

22 May 2026, 18:35
Douglas Nascimento Rechia
0
35

If you’ve ever started a new EA, indicator, or service in MetaTrader and thought “ugh, here we go again” while copy‑pasting boilerplate from an old file, this post is for you.

Most MQL5 devs still live in that world: no package manager, no reproducible builds, no standard project layout, no versioned dependencies. Every new project is a mini migration project from your last EA.

KnitPkg exists to kill that pain — and the real magic starts with a single command:

kp init

That’s it. One command, and you get:

  • A clean project structure
  • A manifest with metadata and dependencies
  • A build pipeline (kp compile)
  • A place to grow a reusable package, EA, indicator or service

Below I’ll show you how little you need to do to spin up real projects in MQL5 using kp init, with concrete examples for:

  • A Service (RiskGate server)
  • An Expert Advisor (RiskGate client EA)
  • A generic project (e.g., indicator)
  • A reusable package (a library)

All of these start exactly the same way: open a terminal in the right folder and run kp init.

The core idea: MQL5 projects in one line

KnitPkg’s philosophy is simple:
  1. You describe the project in a manifest (knitpkg.yaml).
  2. KnitPkg generates the structure and build files.
  3. You add dependencies with kp add, download them with kp install, and build with kp compile.

The entry point is always kp init. You tell it what you want, and it scaffolds everything.

For example, a MetaTrader 5 Service for centralized risk management (RiskGate server) is initialized like this: 

kp init \
  --type service \
  --target mql5 \
  --name riskgate-service-example \
  --organization douglasrechia \
  --version 1.0.0 \
  --description "Gate risk manager service example" \
  --keywords "risk-manager,service,showcase,risk-gate" \
  --author "Douglas Rechia" \
  --license "MIT" \
  --include-mode "include" \
  --git-init \
  --enable-telemetry

You confirm once, and KnitPkg creates a full project under: MQL5/Services/riskgate-service-example. Metadata, manifest, initial source files, Git repo, everything ready to go.

From there, the server tutorial shows that you only add your handler and a simple OnStart() that wires it to RiskGateServer. No manual search for third‑party includes, no hand‑built path gymnastics.

Minimal real-world example: RiskGate Service

Let’s look at how quickly a real Service comes together. See all about that service in the article "RiskGate: Centralized Risk Management for Multiple EAs".

Step 1 — Initialize the project. You’ve seen the kp init command above. As a result of that command, KnitPkg creates:

  • knitpkg.yaml with metadata and dependencies
  • src/riskgate-service-example.mq5 with boilerplate
  • knitpkg/build/ placeholder for build info

Step 2 — Add your dependency. Inside the project, you declare what you actually want to use:

kp add @douglasrechia/riskgate
kp install

KnitPkg resolves the dependencies and drops the headers into: knitpkg/include/douglasrechia/riskgate/...

No manual download, no “where did I save that .mqh again?".

Step 3 — Plug in your logic. You create one handler file, for example src/riskgate-handler.mqh:

#include "../knitpkg/include/douglasrechia/riskgate/RiskGateHandler.mqh"
#include "../knitpkg/include/knitpkg-labs/JAson/JAson.mqh"

class MyHandler : public douglasrechia::RiskGateHandler
{
  void OnSignal(CJAVal &signal, CJAVal &response) override
  {
    string symbol       = signal["symbol"].ToStr();
    response["approved"] = true;
    response["lot"]      = 0.01;
    response["reason"]   = "";
  }

  string Name() override { return "MyHandler"; }
};

That’s already a working risk server: it always approves trades with fixed lot size.

Step 4 — Wire it in the Service entry point

kp init has generated src/riskgate-service-example.mq5 with build info and metadata. You just add:

#include "riskgate-handler.mqh"
#include "../knitpkg/include/douglasrechia/riskgate/RiskGateServer.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();
}

Compile the project with:

kp compile

Attach the Service in MetaTrader, enable DLLs, and you now have a TCP server listening on port 5555 handling risk across any EAs that talk to it. That’s a full distributed architecture for risk — starting from one kp init command.

Minimal EA that talks to the Service

On the EA side, it’s the same story.

Step 1 — Initialize the EA project. In the MQL5/Experts folder, run:

kp init \
  --type expert \
  --target mql5 \
  --name riskgate-ea-example \
  --organization douglasrechia \
  --version 1.0.0 \
  --description "Risk gate EA example" \
  --keywords "riskgate,risk-management,showcase" \
  --author "Douglas Rechia" \
  --license "MIT" \
  --include-mode "include" \
  --git-init \
  --enable-telemetry

This generates src/riskgate-ea-example.mq5 with:

  • #include "../knitpkg/build/BuildInfo.mqh"
  • #property lines auto-filled from the manifest (version, description, author, license)
  • Empty OnInit, OnDeinit, OnTick ready to use. 

Step 2 — Add the client dependency

kp add @douglasrechia/riskgate-ea
kp install

Again, headers land in knitpkg/include/... and are ready to #include. 

Step 3 — Use the RiskGateClient in a few lines

At the top of src/riskgate-ea-example.mq5:

#include "../knitpkg/include/douglasrechia/riskgate-ea/RiskGateClient.mqh"

douglasrechia::RiskGateClient client("127.0.0.1", 5555);
int count = 0;

Then:

int OnInit()
{
  client.Connect();
  return INIT_SUCCEEDED;
}

void OnDeinit(const int reason)
{
  client.Disconnect();
}

void OnTick()
{
  count++;
  if(count < 30)
    return;

  CJAVal signal, response;
  signal["symbol"]    = _Symbol;
  signal["side"]      = "BUY";
  signal["stop_loss"] = 12.34;

  bool online = client.RequestPositionSize(signal, response);

  if(!online)
    Print("ERROR: server offline");

  Print("approved: ", response["approved"].ToBool(),
        " lot: ",    response["lot"].ToDbl(),
        " reason: ", response["reason"].ToStr());

  count = 0;
}

Compile with:

kp compile

Attach the EA to a chart, enable DLLs, and it immediately starts talking to the Service, every 30 ticks. You can attach it to multiple symbols and all flows through a single central risk brain.

All of this came from two kp init calls (one for the Service, one for the EA) and a few kp add / kp install / kp compile commands. No manual folder juggling, no copy‑pasted meta headers, no hardcoded version strings.

Beyond RiskGate: creating any MQL5 project or package

RiskGate is just a concrete example. The same pattern applies to any project type: indicators, EAs, services, scripts, utilities. See the “Creating Projects” guide, which demonstrates this with an ATR indicator that consumes other packages. The “Creating Packages” guide walks through the example of a composite package barhelper that extends the existing bar package. 

Why this matters for traders, freelancers, and researchers

If you’re a:

  • Trader: you get a repeatable way to spin up new strategies, experiment, and keep them versioned without the “which copy of MyStrategy_v7_final.mq5 is this?” problem.
  • Freelancer: you reduce setup time on every client project. Initialize, pull in your standard libraries as packages, and focus on the custom logic that actually gets you paid.
  • Researcher / quant: you can treat MQL5 like a proper engineering environment. Reproducible builds, versioned dependencies, shared internal packages, and centralized services (like RiskGate) become the norm rather than the exception.
  • Package author: you can publish and evolve packages that other people can consume with a single kp add — there’s an actual ecosystem path, not just “here’s a .mqh, good luck”.

And the common denominator is banal but powerful:

kp init

It removes friction at the exact point where most MQL5 work starts: the creation of a new project.

Where to go from here

My suggestion if you’re new to KnitPkg:

  1. Pick a super simple idea (like a moving‑average EA or a small risk helper service).
  2. Initialize it with kp init as a project.
  3. Add one dependency (for example, logging or a small helper lib). You can find all the available packages by querying the registry.
  4. Compile and attach it in MetaTrader.

If you’re already building with MQL5 and want to help grow a healthier, shared package ecosystem, starting your next project with kp init is the most effective first step.

What kind of project would you be most interested in turning into a KnitPkg project first: an EA, an indicator, a shared library, or a background service like RiskGate? Add your comments here ;-)