Broker / Feed Plugin

Zorro supports most major brokers either with a direct connection, or by connecting through a broker-supported platform, for instance with the MT4/5 bridge or the Sierra bridge. A direct connection to a broker API, exchange, market data feed, or platform is established with a DLL in Zorro's Plugin folder. Zorro automatically scans that folder at startup, and lists all valid DLLs in the [Broker / Account] scrollbox. The DLL uses the broker's API for placing orders and getting market data. The interface is organized for keeping the DLL as simple as possible. Only a few functions are required for basic automated trading. Additional functionality, for instance to activate special order types or getting special data, can be implemented with an optional broker command. If you know programming and have access to the broker's API documentation, you can write a broker DLL in a few hours. For downloading historical data in CSV or JSON format from online data sources you'll need no DLL; a small script is sufficient (see assetHistory).

Writing a broker plugin

Plugins can be written in any language that supports DLLs, such as Java, Pascal, C#, or C++. Many plugins have been written by Zorro users, mostly in C++. We reward proper C++ written plugins with a free Zorro S subscription, license, or update extension. Open source plugin code can be found in Zorro's Source folder and on the GitHub pages of plugins developed by Zorro users.

The source code of included broker plugins is available on request to experienced programmers who are developing a similar plugin for the community. Please contact us with a short description of your project and your prior C++ experience. You'll need to sign a non-disclosure agreement, and send us back the final plugin with source code for review. Technical support is free for developing broker plugins; you'll need no support ticket or Zorro S subscription.

You can also contact us for outsourcing the plugin development.

Setting up VC++

In the following you'll find instructions about how to set up Microsoft VC++ to write a broker plugin DLL for the Zorro broker API interface. The dialogs are slightly different for any VC++ version, but here's the general setup for a Win32 DLL. Create a new project (File->New Project). Select Win32 Project. When the Win32 Application Wizard pops up, select DLL in the application settings, then click [Finish]. Under VC++ 2017, select Windows Universal, then DLL. VC++ now creates a new DLL project for you, with a main cpp file that looks like this:

// Defines the entry point for the DLL application.

#include "stdafx.h"

  HANDLE hModule,
  DWORD ul_reason_for_call,
  LPVOID lpReserved)
  return TRUE;

DllMain is the main entry point of the broker DLL, and you can leave that function unchanged. The broker functions require the DATE and T6 data types, thus you need to define DATE and include the trading.h header, like this:

typedef double DATE;
#include "whereever_you_installed_it\Zorro\include\trading.h"

If you want to distribute your broker DLL to other people, we suggest that you open Properties / C/C++ / Code Generation, and change the Runtime Library setting from Multi-threaded DLL (/MD) to Multi-threaded (/MT). Otherwise users won't be able to use the DLL without installing the VC++ Runtime Redistributable before - one of the funny ideas by Microsoft to make Windows user's life more interesting.

If your broker DLL accesses Zorro-specific structs, set struct alignment to 4, or use the #pragma pack(4) statement. Otherwise structs can have different sizes in lite-C and in VC++.

For a DLL to appear in the scrollbox, it must be located in the Plugin folder. Zorro first checks at start if the DLL can be opened with LoadLibrary(). If so, it checks if there is a BrokerOpen function (see below) and if it returns a valid version number. If both conditions are fulfilled, the DLL is registered and appears in the scrollbox. LoadLibrary will fail when DllMain does not return properly. Most frequent reasons are not creating a plain Win32 DLL (f.i. a 64-bit or MFC DLL) or a missing module that the DLL requires. Thus, the more complex libraries you're using, the more likely is your DLL to fail, probably not on your, but on other people's PCs. For being on the safe side, include in the distribution all modules that your DLLs needs. If in doubt, check your DLL's dependencies with DependencyWalker. For debugging, place breakpoints in DllMain and BrokerOpen and check what's happening when Zorro starts.

Plugin templates & the TradeTest script

The Source folder contains two broker plugin examples in .zip archives:

You can find more Zorro broker plugins on Github. Use the best suited as a template for your own plugin. Implement the DLL functions (see below) in this order: BrokerOpen, BrokerLogin, BrokerAsset, BrokerBuy2. These 4 functions (described below) are the minimum required for trading with the broker. Optionally, implement BrokerAccount, BrokerHistory2, BrokerTime, BrokerTrade, BrokerSell2, BrokerStop if supported by the API. Test any function after implementation with the TradeTest script.

Some functions need not be fully implemented, or not at all. The minimum functions for TradeTest to run are BrokerOpen and BrokerLogin. If a function, f.i. BrokerAsset, is not yet available in the DLL, Zorro simulates it with default values. So you can implement and test the functions step by step.

As soon as the BrokerAsset function is correctly implemented, you should see the current price in the Server window. The TradeTest script opens a panel with the following buttons for testing various broker functions:

[Auto On/Off] - Toggle button for a simulated trade session that automatically opens or closes a trade every minute.

[NFA On/Off] - Toggle the NFA flag. Required for most US accounts; not to be set for most Forex/CFD accounts.

[Hedge] - Toggle between Hedge modes 0, 2, 4,and 5. Some brokers do not support full hedging (mode 2) or partial closing (mode 5).

[Order] - Toggle between limit (LMT), market orders (MKT), good-til-cancelled (GTC) and adaptive orders (Adaptive) when supported by the plugin.

[Asset] - Enter the asset symbol to trade (default: asset from the scroll box).

[Buy Long] - Open a long position with the Lots and Stop value set up with the sliders.

[Buy Short] - Open a short position. Dependent on Hedge, close any open position in opposite direction.

[Close Long] - Close the given number of lots from an open long position. Partial closing is not supported by some brokers.

[Close Long] - Close the given number of lots from an open short position.

[Update Stop] - Sets the Stop of all open positions to the value (in Pips) set up with the slider. Stop adjustment is not supported by some brokers. Due to StopFactor, the broker stop is more distant than the real stop.

LMT orders attempt to open the position at half spread, adaptive orders at zero spread. The broker must support real limit orders for this; MT4 "pending positions" are no limit orders and will not work for LMT or adaptive orders. Various trading modes, broker commands, asset lists etc. can be set up in #define statements at the begin of the TradeTest script.

Broker API functions

The broker DLL exports functions that are described in the following list. With VC++, exported DLL functions must be either declared with the extern "C" __declspec(dllexport) attribute, or listed in a .def file. The DLL functions use only a small subset of a usual broker API. In the following list, pointer arguments printed in italic can be NULL; if they are nonzero, the function must fill them with the required data. All data is mandatory if not mentioned otherwise.

BrokerOpen (char* Name, FARPROC fpError, FARPROC fpProgress) : int

Called at startup for all broker DLLs found in the Plugin folder. Retrieves the name of the broker, and sets up two callback functions. Should not allocate or load any resources - this should be done in the BrokerLogin function.


Name Output, char[32] array to be filled with the name of the broker, f.i. "FXCM". The name appears in the Account scrollbox.
fpError Input, pointer to a int BrokerError(const char* message) function, to be called for printing broker messages (usually error messages) in Zorro's message window. Calling this function is not mandatory. If the message string begins with an exclamation mark '!', Zorro opens an alert box for notifying the user that his attention might be required. If it begins with a hash '#', it is printed into the diagnostics file only.
fpProgress Input, pointer to a int BrokerProgress(DWORD progress) function, to be called repeatedly when broker operations take longer than a second, f.i. BrokerLogin or BrokerHistory. When progress is 0, the Zorro UI will update for for preventing unresponsiveness. When it is 1, dots will be printed in the message window for indicating the progress of the operation. When progress is a pointer and a callback function exists in the script, it is called and the pointer is passed for triggering script functions from the broker API. When the function returns 0, the current broker operation must be aborted.


Broker interface version number; currently 2.

BrokerHTTP (FARPROC fpSend, FARPROC fpStatus, FARPROC fpResult, FARPROC fpFree)

Optional function that is called when the broker API requires HTTP access, as for REST and FIX APIs. Sets up 4 function pointers for exchanging data with HTTP POST, GET, DELETE, or other messages through a URL. Headers and content can be set separately. This way the plugin needs not to implement own http/https libraries.


fpSend, fpStatus, fpResult, fpFree Input, pointers to the http_send, http_status, http_result and http_free functions.


BrokerLogin (char* User, char* Pwd, char* Type, char* Accounts): int

Login or logout to the broker's API server; called in [Trade] mode or for downloading historical price data. If the connection to the server was lost, f.i. due to to Internet problems or server weekend maintenance, Zorro calls this function repeatedly in regular intervals until it is logged in again. Make sure that the function internally detects the login state and returns safely when the user was still logged in.


User Input, User name for logging in, or NULL for logging out.
Pwd Input, Password for logging in.
Type Input, account type for logging in; either "Real" or "Demo".
Accounts Optional output, char[1024] array to be filled with all user's account numbers as subsequent zero-terminated strings, ending with "" for the last string. Only the first account number is used by Zorro.


Login state: 1 when logged in, 0 otherwise.

BrokerTime (DATE *pTimeUTC): int

Returns connection status and (optionally) the server time. Repeatedly called during the trading session.


pTimeUTC Optional output, current server time in UTC / GMT+0 with no daylight saving. The DATE format (OLE date/time) is a double float value, counting days since midnight 30 December 1899, while hours, minutes, and seconds are represented as fractional days.


0 when the connection to the server was lost (see remarks).
1 when the connection is ok, but the market is closed or trade orders are not accepted.
2 when the connection is ok and the market is open for trading at least one of the subscribed assets.


DATE convertTime(__time32_t t32)
  return (double)t32/(24.*60.*60.) + 25569.; // 25569. = DATE(1.1.1970 00:00)
} __time32_t convertTime(DATE date) { return (__time32_t)((date - 25569.)*24.*60.*60.);

BrokerAsset (char* Asset, double *pPrice, double *pSpread, double *pVolume, double *pPip, double *pPipCost, double *pLotAmount, double *pMarginCost, double *pRollLong, double *pRollShort): int

Subscribes an asset, or returns information about it. Zorro subscribes all assets at the begin of the trading session. Price and spread for all assets are retrieved in TickTime intervals or when BrokerProgress was preciously called by the plugin. Other asset data is retrieved once per bar.


Asset Input, asset symbol for live prices (see Symbols).
pPrice Optional output, current ask price of the asset, or NULL for subscribing the asset. An asset must be subscribed before any information about it can be retrieved.
pSpread Optional output, the current difference of ask and bid price of the asset.
pVolume Optional output, a parameter reflecting the current supply and demand of the asset, f.i. trade volume per minute, open interest, quote volume, or tick frequency, when such information is available. If a value is returned, it should be consistent with the fVol content of the T6 struct in BrokerHistory2 (see below)..
pPip Optional output, size of 1 PIP, f.i. 0.0001 for EUR/USD.
pPipCost Optional output, cost of 1 PIP profit or loss per lot, in units of the account currency. If not directly supported, calculate it as decribed under asset list.
pLotAmount Optional output, minimum order size, i.e. number of contracts for 1 lot of the asset. For currencies it's usually 10000 with mini lot accounts and 1000 with micro lot accounts. For CFDs it's usually 1, but can also be a fraction of a contract, f.i. 0.1.
pMarginCost Optional output, initial margin cost for buying 1 lot of the asset in units of the account currency. Alternatively, the leverage of the asset when negative (f.i. -50 for 50:1 leverage). If not supported, calculate it as decribed under asset list.
pRollLong Optional output, rollover fee for long trades, i.e. interest that is added to or subtracted from the account for holding positions overnight. The returned value is the daily fee per 10,000 contracts for currencies, and per contract for all other assets, in units of the account currency.
pRollShort Optional output, rollover fee for short trades.


1 when the asset is available and the returned data is valid, 0 otherwise. An asset that returns 0 after subscription will trigger Error 053, and its trading will be disabled.


double Price = MarketInfo(Asset,MODE_ASK);
double Spread = Price - MarketInfo(Asset,MODE_BID);
double Volume = 0;
double LotFactor = MarketInfo(Asset,MODE_MINLOT); // correction for different lot scale
double Pip = MarketInfo(Asset,MODE_POINT);
double PipCost = MarketInfo(Asset,MODE_TICKVALUE) * LotFactor;
int DigitSize = MarketInfo(Asset,MODE_DIGITS); // correction for brokers with 5 digits if(DigitSize == 3 || DigitSize == 5) { Pip *= 10.;
PipCost *= 10.; }
double MinAmount = MarketInfo(Asset,MODE_LOTSIZE) * LotFactor;
double Margin = MarketInfo(Asset,MODE_MARGINREQUIRED) * LotFactor; double RollLong = MarketInfo(Asset,MODE_SWAPLONG); double RollShort = MarketInfo(Asset,MODE_SWAPSHORT);
if(MarketInfo(Asset,MODE_SWAPTYPE) == 0.) { RollLong *= PipCost; RollShort *= PipCost; }

BrokerHistory2 (char* Asset, DATE tStart, DATE tEnd, int nTickMinutes, int nTicks, T6* ticks): int

Returns the price history of an asset. Called by Zorro's assetHistory function and at the begin of a trading session for filling the lookback period.


Asset Input, asset symbol for historical prices (see Symbols).
tStart Input, UTC start date/time of the price history (see BrokerTime about the DATE format). This has only the meaning of a seek-no-further date; the relevant date for the begin of the history is tEnd.
tEnd Input, UTC end date/time of the price history. If the price history is not available in UTC time, but in the brokers's local time, the plugin must convert it to UTC.
nTickMinutes Input, time period of a tick in minutes. Usual values are 0 for single price ticks (T1 data; optional), 1 for one-minute (M1) historical data, or a larger value for more quickly filling the LookBack period before starting a strategy.
nTicks Input, maximum number of ticks to be filled; must not exceed the number returned by brokerCommand(GET_MAXTICKS,0), or 300 otherwise.
ticks Output, array of T6 structs (defined in include\trading.h) to be filled with the ask prices, close time, and additional data if available, such as historical spread and volume. See history for details. The ticks array is filled in reverse order from tEnd on until either the tick time reaches tStart or the number of ticks reaches nTicks, whichever happens first. The most recent tick, closest to tEnd, is at the start of the array. In the case of T1 data, or when only a single price is available, all prices in a TICK struct can be set to the same value.


Number of ticks returned, or 0 when no ticks could be returned, f.i. when the server was offline, the asset was not subscribed, or price history was not available for the given date/time.

BrokerAccount (char* Account, double *pBalance, double *pTradeVal, double *pMarginVal): int

Optional function. Is called by Zorro in regular intervals and returns the current account status. Is also used to change the account if multiple accounts are supported. If the BrokerAccount function is not provided, f.i. when using a FIX API, Zorro estimates balance, equity, and margin from initial values and trade results.


Account Input, new account name or number, or NULL for using the current account.
pBalance Optional output, current balance on the account.
pTradeVal Optional output, current value of all open trades; the difference between account equity and returned balance value. If not available, Zorro estimes the equity from balance and value of all open trades. If no balance was returned, the account equity can be returned in pTradeVal.
pMarginVal Optional output, current total margin bound by all open trades. If not


1 when the account is available and the returned data is valid, 0 when a wrong account was given or the account was not found.

BrokerBuy2 (char* Asset, int Amount, double StopDist, double Limit, double *pPrice, int *pFill): int

Enters a long or short trade either at market, or at a price limit. Also used for NFA compliant accounts to close a trade by opening a position in the opposite direction. The order type (FOK, IOC, GTC) was set with SET_ORDERTYPE before. Default is FOK ("Fill-Or-Kill").


Asset Input, asset symbol for trading (see Symbols).
Amount Input, number of contracts, positive for a long trade and negative for a short trade. The number of contracts is the number of Lots multiplied with the LotAmount. If LotAmount is < 1 (f.i. for a CFD with 0.1 contracts lot size), the number of lots is given here instead of the number of contracts.
StopDist Optional input, absolute 'safety net' stop loss distance to the opening price, or 0 for no stop. This is not the real stop loss, which is handled by the trade engine. Placing the stop is not mandatory. NFA compliant orders do not support a stop loss in the same order; in that case StopDist is 0 for opening a trade and -1 for closing a trade by opening a position in opposite direction.
Limit Optional input, ask/bid price for limit orders, set up by OrderLimit, or 0 for market orders. Can be ignored if limit orders are not supported by the API. 
pPrice Optional output, the fill price if the trade was partially or fully filled.
pFill Optional output, the fill amount. Needed for other order types than FOK orders and for partial fills.


BrokerTrade (int nTradeID, double *pOpen, double *pClose, double *pCost, double *pProfit): int

Optional function for updating a trade status; normally only used for non-NFA compliant broker APIs that support individual trades. Called by Zorro when the price moved by more than 1 pip, or when contractUpdate or contractPrice is called for an option or future trade. Returns the status of an open or recently closed trade.


nTradeID Input, trade ID number as returned by BrokerBuy,,  or -1 for a UUID to be set before with a SET_UUID command.
pOpen Optional output, the average fill price if the trade was partially or fully filled.
pClose Optional output, current bid or ask close price of the trade.
pCost Optional output, total rollover fee (swap fee) of the trade so far.
pProfit Optional output, current profit or loss of the trade in account currency units, without rollover and commission.


Number of contracts resp. lots (as in BrokerBuy) filled for this trade, or 0 when the order was not filled yet, or the negative number of filled contracts when the trade was closed, or NAY (defined in trading.h) when an error occurred and the order state could not be determined. The returned number can deviate from the original trade volume when the trade was only partially filled. The output pointers can be set up with trade parameters when they are available. Otherwise Zorro will estimate the values based on last price and asset parameters.

BrokerStop (int nTradeID, double dStop): int

Optional function. Adjusts the 'safety net' distant stop loss of an open trade if it had an original stop (dStopDist != 0). If this function is not provided, the original stop loss is never updated. Only for not NFA compliant accounts.


nTradeID Input, trade ID number as returned by BrokerBuy2, or -1 for a UUID to be set before with a SET_UUID command.
dStop The new stop loss price. Must be by a sufficient distace (broker dependent) below the current price for a long trade, and above the current price for a short trade.


0 when no open trade with this ID could be found, otherwise nonzero.

BrokerSell2 (int nTradeID, int nAmount, double Limit, double *pClose, double *pCost, double *pProfit, int *pFill): int

Optional function; closes a trade - completely or partially - at market or at a limit price. If partial closing is not supported by the broker, the trade is completely closed. Only for not NFA compliant accounts; otherwise the trade is closed by calling BrokerBuy2 with the negative amount. 


nTradeID Input, trade ID as returned by BrokerBuy2, or -1 for a UUID to be set before with a SET_UUID command.
nAmount Input, number of contracts resp. lots to be closed, positive for a long trade and negative for a short trade (see BrokerBuy). If less than the original size of the trade, the trade is partially closed.
Limit Optional input, ask/bid price for a limit order, set up by OrderLimit, or 0 for closing at market. Can be ignored if limit orders are not supported by the API. 
pClose Optional output, close price of the trade.
pCost Optional output, total rollover fee (swap fee) of the trade.
pProfit Optional output, total profit or loss of the trade in account currency units.
pFill Optional output, the fill amount.


Trade ID number of the remaining 'reduced' trade when it was partially closed and the broker assigned a different ID; otherwise the original trade ID number. 0 when the trade could not be closed.

BrokerCommand (int nCommand, DWORD dwParameter): var

Optional function. Sets various plugin parameters or returns asset specific extra data. This function is not mandatory, as it is not used by Zorro's trade engine; but it can be called in scripts through the brokerCommand function for special purposes.


nCommand Input, command from the brokerCommand list.
dwParameter Input, parameter or data to the command.


0 when the command is not supported by this broker plugin, otherwise the data to be retrieved.



Example: see Source folder

See also:

Brokers, Symbols, brokerCommand, enter, order, DLL, IB, FXCM, Oanda, MT4

► latest version online