Introducing @knitpkg:wired: Real MQL #include for Composite Packages in KnitPkg
If you’ve played with KnitPkg composite packages, you’ve probably hit this classic problem:
- During development, you want MetaEditor to resolve all your #include s so that IntelliSense and unit tests work.
- But when your package is installed as a dependency, those #include s must point to the real installed headers under knitpkg/include/ , not to some dev‑only helper.
Until now, the “classic” solution was:
- Include a big autocomplete.mqh file to make symbols from dependencies visible;
- Declare the real external dependencies via /* @knitpkg:include "..." */ directives, which KnitPkg rewrites into real #include statements during kp install .
This works, but it has two downsides:
- autocomplete.mqh pulls in everything from your dependencies, polluting IntelliSense with lots of unrelated names.
- Your real dependencies are hidden inside comments instead of being visible as normal MQL includes.
KnitPkg v1.1.0 introduces a better approach.
What Is @knitpkg:wired ?
@knitpkg:wired is a new directive for composite packages that lets you write real MQL #include paths to dependency headers, while still letting KnitPkg “rewire” those includes when your package is installed somewhere else.
Instead of doing this (classic approach):
#include "../../../autocomplete/autocomplete.mqh" /* @knitpkg:include "douglasrechia/bar/TimeSeries.mqh" */
you can now write this:
#include "../../../autocomplete/knitpkg/include/douglasrechia/bar/TimeSeries.mqh" /* @knitpkg:wired */
- The #include is real MQL, pointing to the header under knitpkg/autocomplete/knitpkg/include/… .
- MetaEditor resolves it directly, so IntelliSense and unit tests just work.
- The /* @knitpkg:wired */ annotation sits on the same line as the #include .
- During kp install , KnitPkg detects this annotation and rewrites the path from the autocomplete structure to the real installed header under knitpkg/include/… .
So inside your dev repo, your file might look like this:
//+------------------------------------------------------------------+ //| Cross.mqh | //| Package barhelper | //| Organization: douglasrechia | //+------------------------------------------------------------------+ #include "../../../autocomplete/knitpkg/include/douglasrechia/bar/TimeSeries.mqh" /* @knitpkg:wired */ namespace douglasrechia { bool CrossUp(ITimeSeries<double> &series1, ITimeSeries<double> &series2, int shift = 0) { if(shift < 0) return false; if(shift >= series1.Size() - 1) return false; if(shift >= series2.Size() - 1) return false; return series1.ValueAtShift(shift + 1) < series2.ValueAtShift(shift + 1) && series1.ValueAtShift(shift) > series2.ValueAtShift(shift); } } //+------------------------------------------------------------------+
When barhelper is installed as a dependency in another project, KnitPkg rewrites that include so it points at the installed TimeSeries.mqh under knitpkg/include/douglasrechia/bar/… instead of the autocomplete copy.
For another example, see this repository.
Why This Is Better for Composite Packages
From the MQL developer’s point of view, @knitpkg:wired is much more natural than the old autocomplete.mqh + @knitpkg:include combo:
-
The includes are honest MQL.
You see exactly which headers you are including, as normal #include statements. There is no “magic” hidden inside comments. -
No more namespace pollution.
You include only the specific headers you need from each dependency, instead of pulling everything into the current translation unit via autocomplete.mqh . -
MetaEditor just works.
Because the #include references the header under knitpkg/autocomplete/knitpkg/include/… , MetaEditor resolves it normally. IntelliSense and unit tests see the same code you see. -
Install-time wiring is automatic.
kp install simply detects /* @knitpkg:wired */ and overwrites the include path to target the installed package header. You don’t have to maintain a separate list of @knitpkg:include directives.
The result: your composite packages read like idiomatic MQL code, while still behaving correctly when installed as dependencies.
How To Use @knitpkg:wired in Your Package
Here’s the workflow in practice:
1. Declare the dependency.
In your composite package (for example barhelper ), add the dependency with the CLI:kp add @douglasrechia/bar
This updates your knitpkg.yaml with something like:
dependencies: '@douglasrechia/bar': ^1.0.0
2. Generate autocomplete headers.
Run:kp autocomplete
This populates knitpkg/autocomplete/knitpkg/include/... with headers for your dependencies, preserving their structure. These are the headers your dev-time includes should target when you write @knitpkg:wired includes.
3. Write wired includes in your public headers.
In a header under knitpkg/include/<org>/<package>/ , include dependency headers from the autocomplete tree and annotate them:#include "../../../autocomplete/knitpkg/include/douglasrechia/bar/TimeSeries.mqh" /* @knitpkg:wired */A few rules:
- The path must point somewhere under knitpkg/autocomplete/knitpkg/include/ .
- The path should be relative to the header that’s including it.
- The /* @knitpkg:wired */ annotation must be on the same line as the #include .
4. Validate with kp checkinstall. Before publishing your package, run:
kp checkinstallThis simulates installation and verifies that all wired includes will resolve correctly when your package is consumed as a dependency.
Comparison With the Classic @knitpkg:include Approach
For context, here is what the classic approach looked like in a composite package header:
#include "../../../autocomplete/autocomplete.mqh" /* @knitpkg:include "douglasrechia/bar/TimeSeries.mqh" */
During development:
- autocomplete.mqh brings all dependency headers into a local structure so MetaEditor can resolve symbols for IntelliSense and compilation.
- The @knitpkg:include directive lives inside a comment and is only interpreted by KnitPkg at install time.
When the package is installed as a dependency, KnitPkg:
- Comments out the #include "../../../autocomplete/autocomplete.mqh" line so it doesn’t leak into the consumer’s code;
- Converts each @knitpkg:include directive into a real MQL #include pointing at the installed dependency headers under knitpkg/include/… .
This still works and is fully supported, but in practice it has some drawbacks:
- You have two sources of truth for dependencies (the dev-time autocomplete.mqh and the install-time @knitpkg:include comments).
- autocomplete pulls in a lot of stuff you may not need.
- The real dependency edges are hidden in comments rather than expressed as normal #include s.
@knitpkg:wired was designed specifically to remove these wrinkles and make composite packages feel like straightforward MQL projects that just happen to be wired up by KnitPkg at install time.
Recommended Usage
Going forward:
- For composite packages, @knitpkg:wired is the recommended pattern to express dependencies between packages in public headers.
- For single packages (those with no dependencies), you don’t need kp autocomplete , @knitpkg:wired , or @knitpkg:include at all; your headers compile as regular .mqh files.
- For internal includes within the same package, you still use normal relative #include statements with no KnitPkg directives.
If you already have packages using autocomplete.mqh + @knitpkg:include , they will continue to work. You can migrate gradually: as you touch existing headers, you can swap them to @knitpkg:wired if you want the cleaner, more explicit style.
Wrap-Up
@knitpkg:wired is a small directive, but it significantly simplifies how composite packages are written:
- Real MQL includes instead of comment‑based indirection.
- Cleaner IntelliSense, less namespace clutter.
- Automatic path rewiring at install time, validated by kp checkinstall .
If you’re maintaining packages that depend on others, I strongly recommend trying the wired approach in your next refactor or new package.
Read the KnitPkg docs for more information.
If you’d like, I can help you convert one of your existing KnitPkg packages step-by-step from @knitpkg:include to @knitpkg:wired —do you have a specific repo in mind?


