Build an Expert Advisor
A start-to-finish walkthrough: set up the project, integrate the SDK, and submit your Expert Advisor to the marketplace.
Prerequisites
Before you start, have the following ready. Each item is explained so you know why it matters for an Expert Advisor.
MetaTrader 5 (MT5) — The trading platform where your EA runs. You need it installed to attach the robot to a chart and run it live or in strategy tester.
MetaEditor — The built-in MQL5 editor (F4 in MT5). You will write and compile your EA and configuration class here.
API Key — A secret string that authenticates the end user (or you during testing) with TheMarketRobo. Expose it as an input parameter so users can paste it when attaching the EA.
Robot Version UUID — A 36-character identifier (e.g. xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) that you reserve in the Vendor Portal for this robot version. The SDK sends it at session start so the server knows which product is running.
Magic number — A unique number that identifies orders opened by this EA instance. The SDK does not place orders; you use the magic in your trading logic. You can generate one randomly in OnInit (e.g. MathRand() * MathRand() + GetTickCount()) and pass it to on_init(api_key, magic) so the server can correlate the session with orders.
IRobotConfig — You will implement a configuration class that extends IRobotConfig. It defines the schema (fields, types, ranges) and serialization so customers can change settings from the web dashboard and the server can push updates to the EA.
For local testing, create a new test license in your Vendor Portal and use its API key with the staging API. Do not use production licenses for development.
Get the code
Clone the official sample library with submodules so you get both a working sample EA and the SDK source.
Where things live:
• Experts/sample-ea/SampleTMRBot.mq5 — A full EA that integrates the SDK: 19-field config class, robot class with on_tick, on_config_changed, on_symbol_changed, and all MQL5 handlers. It does not place trades; use it as a reference for wiring and config patterns.
• Include/themarketrobo/ — The SDK folder. Include only TheMarketRobo_SDK.mqh; it pulls in the rest. Keep the folder name lowercase.
Project setup
Copy the themarketrobo folder (lowercase) into your MetaTrader 5 Include directory. The compiler resolves #include <...> from there.
At the top of your EA file (after #property and before inputs), add this single include. It brings in the base class, config interfaces, and all SDK managers.
If the file compiles without errors, the SDK is correctly installed.
Using AI to integrate
Our recommendation: use Antigravity with Claude Opus 4.6 (latest) to integrate the SDK into your Expert Advisor in under 10 minutes. AI coding assistants with large context windows can load the full SDK repository and your EA source, then produce a correctly wired integration — config class, robot class, and event handlers — because our documentation and SDK code are explicit and straightforward.
How to do it: Open your AI assistant (we recommend Antigravity + Claude Opus 4.6), then provide (1) the full SDK repository — sdk-mql5-lib — and (2) your robot source code (or the sample EA from mql5-sample-lib as reference). Ask the model to integrate TheMarketRobo SDK into your EA: implement IRobotConfig (define_schema, apply_defaults, to_json, update_from_json, update_field, get_field_as_string), extend CTheMarketRobo_Base with the two-argument constructor (UUID + config), override on_tick, on_config_changed, and on_symbol_changed, and wire OnInit (with on_init(api_key, magic)), OnDeinit, OnTick, OnTimer, and OnChartEvent.
The SDK is designed for this: the integration booklet and in-repo docs explain every step, and the codebase is structured so an AI can follow the same patterns as the sample EA (including multi-field config and dependencies). In practice, the assistant will handle the bulk of the boilerplate; you only need to replace the robot version UUID, verify config fields and event forwarding, and test. For many developers this path is faster than following the manual steps below — use it if you prefer to iterate with AI, then lean on the rest of this guide for testing and submission.
How the robot and SDK work together
MQL5 calls fixed-named functions: OnInit, OnDeinit, OnTick, OnTimer, OnChartEvent. You create one robot instance (your class extending CTheMarketRobo_Base) and forward each call to it.
What the SDK does for EAs: (1) In on_init(api_key, magic) it collects account and terminal data, gathers Market Watch symbols, POSTs /robot/start, stores the JWT and initial config, and starts a 1-second timer. (2) In OnTimer it sends heartbeats, refreshes the token, and processes config/symbol change requests from the server — applying accepted changes to your config and calling your on_config_changed / on_symbol_changed. (3) On shutdown it POSTs /robot/end with final stats and kills the timer.
What you do: Implement IRobotConfig (schema + six methods) and pass new CMyRobotConfig() to the base constructor. Put your trading logic in on_tick(), reading settings from (CMyRobotConfig*)m_robot_config. Override on_config_changed and on_symbol_changed to react to live updates (values are already applied when these are called). Do not call EventSetTimer or EventKillTimer yourself; the SDK owns the timer.
Define configuration class
The configuration class tells TheMarketRobo what settings your robot has so customers can view and change them from the dashboard. You implement IRobotConfig with six required methods.
Constructor: Call define_schema() then apply_defaults() in that order. The SDK calls define_schema() only once during construction; use it to add fields with CConfigField::create_integer, create_decimal, create_boolean, create_radio, create_multiple. Use .with_range(), .with_step(), .with_precision(), .with_description(), .with_group() for clarity and validation. For conditional fields use CConfigDependency and .with_depends_on().
Best practice: Defaults in apply_defaults() must match the defaults you pass in create_*. Every field in the schema must be handled in to_json(), update_from_json(), update_field(), and get_field_as_string(). Use CheckPointer(m_schema) == POINTER_INVALID at the start of define_schema(). Add public getters (e.g. get_lot_size()) so your robot class can read current values. The base class owns the config pointer — do not delete it yourself.
For full field types, dependencies, and JSON helpers see the . Your schema must follow the platform’s Robot Config Component Schema; the Vendor Portal validates it before you can submit. See the page for the full contract and examples.
Implement your EA class
Robot class. Extend CTheMarketRobo_Base (or the alias CTheMarketRobo_Bot_Base). The constructor takes two arguments: the Robot Version UUID and a new instance of your config class, e.g. CTheMarketRobo_Base(ROBOT_VERSION_UUID, new CMyRobotConfig()). The SDK takes ownership of the config and will delete it.
Override on_tick() — this is where your trading logic runs. Cast m_robot_config to your config type and use getters to read lot size, max trades, etc. Config change and symbol change support are optional. If you enable them, the SDK receives change requests from the server, applies config changes by calling your update_field() (after validate_field()), applies symbol changes via SymbolSelect(), and sends the results in the next heartbeat. You can disable them with set_enable_config_change_requests(false) and set_enable_symbol_change_requests(false). Optionally override on_config_changed(string event_json) to react after remote config updates (e.g. log or recalculate) and on_symbol_changed(string event_json) to react after symbol updates (e.g. close positions on disabled symbols). See the page for the optional “Config & symbol change” section and the SDK repo docs for full request/response flow.
Global pointer and OnInit. Declare CMyRobot* g_robot = NULL; In OnInit: validate API key, generate a magic number, create the robot with new CMyRobot(), then call g_robot.on_init(InpApiKey, magic_number). For EAs you must pass two arguments (unlike indicators). On failure, delete the instance and return the init code.
OnDeinit, OnTick, OnTimer, OnChartEvent. In OnDeinit call on_deinit(reason), then delete g_robot and set to NULL. Forward OnTick, OnTimer, and OnChartEvent to the robot. Always check CheckPointer(g_robot) != POINTER_INVALID before calling. If you use OnChartEvent for your own logic, call g_robot.on_chart_event(...) first so the SDK can process its events.
Reserve UUID and configure
The Robot Version UUID identifies this EA version on the server. In the Vendor Portal, create or open your robot product, reserve a version, and copy its UUID (36 characters). Replace the placeholder in your code, e.g. const string ROBOT_VERSION_UUID = "your-actual-uuid"; Use the same value in the base constructor. An invalid or unreserved UUID will cause session start to fail.
Test locally
1. Allow WebRequest. In MT5 go to Tools → Options → Expert Advisors. Add both https://api.themarketrobo.com and https://api.staging.themarketrobo.com to the allowed URL list. The SDK cannot reach the server without this.
2. Test license. Use an API key from a test license created in your Vendor Portal. Do not use production or customer keys for development.
3. Compile and attach. Compile in MetaEditor (F7), then attach the EA to a chart. Enter your API key in the inputs. The magic number can be auto-generated in OnInit as in the code above, or you can add an optional input long InpMagicNumber = 0; and use a fixed value when non-zero.
4. Experts tab. Look for "SDK session started successfully!" and heartbeat logs. Use the customer dashboard to send config or symbol changes and confirm on_config_changed / on_symbol_changed fire (e.g. Alert or Print). SDK messages are prefixed with SDK Info:, SDK Error: for debugging.
Submit for review
When the EA runs correctly with the SDK, follow the Robot & Indicator Submission Guide: prepare the product file (compiled .ex5 or source), product specifications, config schema alignment, backtest data if required, media gallery, and pricing. Submit via the Vendor Portal.