Broker / Feed Plugin

Zorro already supports most major brokers either through a direct connection or via the MT4 bridge. But for connecting to a broker API or a data feed that's not supported yet, you can write a DLL and put it in Zorro's Plugin folder. Zorro automatically scans that folder at startup, and lists all broker DLLs in the [Broker / Account] scrollbox. The DLL uses the broker's API for placing orders and getting price information. The interface is organized to keep the DLL as simple as possible; only 9 functions are required for automated trading. If you know programming, you can write a broker DLL in a few days. It can be written in any language that supports DLLs.

In the following you'll find instructions about how to set up Microsoft VC++ to write a broker DLL for the Zorro broker API interface. The C++ source code of the FXCM Order2Go™ plugin is included in the Zorro distribution and can be found in the Source folder. You can look into it to see how a broker plugin is written, and use it as a 'template' for your own broker DLL.

Setting up VC++

When you create a new project (File->New Project), VC++ offers you a choice of project templates. Select Win32 Project. When the Win32 Application Wizard pops up, select DLL in the application settings, then click [Finish]. VC++ now creates a new DLL project for you, with a main cpp file that looks like this:

// broker.cpp : Defines the entry point for the DLL application.

#include "stdafx.h"

BOOL APIENTRY DllMain( 
  HANDLE hModule,
  DWORD ul_reason_for_call,
  LPVOID lpReserved)
{
  return TRUE;
}

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

typedef double DATE;
#include "..\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 your 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 life more interesting.

Developing a broker plugin - the TradeTest script

Implement the DLL functions in this order: BrokerOpen, BrokerLogin, BrokerTime, BrokerAsset, BrokerHistory, BrokerAccount, BrokerOpen, BrokerBuy, BrokerTrade, BrokerSell, BrokerStop (functions are described below). Test any function after implementation f.i. with the TradeTest script. Some of the functions are optional and need not be fully implemented, or not at all. The minimum functions for TradeTest to run are BrokerOpen, BrokerLogin, and BrokerTime. If a function, f.i. BrokerAsset, is not yet available in the DLL, it is simulated with default values. So you can implement them step by step.

As soon as the BrokerAsset function is 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; must not be set for most other 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).

[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.
 

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.

Parameters:

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(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 the progress parameter is 0, Zorro will trigger a cycle for requesting a price quote. When it is > 0, dots are 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. Calling this function is not mandatory, but when it is called during a broker operation and returns 0, the operation must be aborted.

Returns:

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 to a URL, f.i. for REST and FIX APIs. Sets up 4 functions for exchanging data through a URL, so the plugin needs not to implement own http/https libraries.

Parameters:

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.

Parameters:

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.

Returns:

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.

Parameters:

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.

Returns:

0 when the connection to the server was lost, and a new login is required.
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.

Remarks:

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 are retrieved when the strategy needs them or when BrokerProgress was called; other asset information is retrieved in regular intervals.

Parameters:

Asset Input, name of the symbol, f.i. "EUR/USD" or "NAS100". Some broker APIs, such as MT4 or IB, don't accept a "/" slash in an asset name; either a different symbol in the asset list must be defined, or the plugin must remove or replace the slash before sending the request to the API.
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, recent trade volume of the asset per minute, or 0 when the volume is unavailable. If no volume is returned in this function, Zorro retrieves it with a BrokerHistory2 call.
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.

Returns:

1 when the asset is available and the returned data is valid, 0 otherwise. An asset that still returns 0 after subscription will not be traded.

Remarks:

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.

Parameters:

Asset Input, symbol from the asset list, f.i. "EUR/USD". Some broker APIs, such as MT4 or IB, don't accept a "/" slash in an asset name; the plugin must remove or replace the slash in that case before sending the request to the API.
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; guaranteed to be 300 or less.
ticks Output, array of up to 300 T6 structs (defined in include\trading.h) to be filled with the ask price history and additional optional data if available, such as historical spread and volume. 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 the TICK struct can be set to the same value.

Returns:

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. Returns the current account status, or changes the account if multiple accounts are supported. Called repeatedly during the trading session. If the BrokerAccount function is not provided, f.i. when using a FIX API, Zorro calculates balance, equity, and total margin itself.

Parameters:

Account Input, new account 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 balance. If not available, it can be replaced by a Zorro estimate with the SET_PATCH broker command.
pMarginVal Optional output, current total margin bound by all open trades.

Returns:

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.
 

BrokerBuy (char* Asset, int nAmount, double dStopDist, double *pPrice): int

Enters a long or short trade at market. Also used for NFA compliant accounts to close a trade by opening a position in the opposite direction.

Parameters:

Asset Input, name of the asset, f.i. "EUR/USD". Some broker APIs don't accept a "/" slash in an asset name; the plugin must remove the slash in that case.
nAmount 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.
dStopDist Input, '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 that case dStopDist is 0 for opening a trade and -1 for closing a trade by opening a position in opposite direction.
pPrice Optional output, the current asset price at which the trade was opened.

Returns:

Trade ID number when opening a trade, or 1 when buying in opposite direction for closing a trade the NFA compliant way, or 0 when the trade could not be opened or closed. If the broker API does not deliver a trade ID number (for instance with NFA brokers that do not store individual trades), the plugin can just return an arbitrary unique number f.i. from a counter.
 

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

Optional function. Returns the status of an open or recently closed trade. Can be omitted when the API does not store individual trades.

Parameters:

nTradeID Input, trade ID number as returned by BrokerBuy.
pOpen Optional output, enter price of the asset including spread.
pClose Optional output, current price of the asset including spread.
pRoll Optional output, total rollover fee (swap fee) of the trade so far.
pProfit Optional output, profit or loss of the trade so far. If not available, the profit/loss can be replaced by Zorro estimates with the SET_PATCH broker command.

Returns:

Number of contracts of the given trade ID number, or 0 when no trade with this ID could be found, or a negative number when the trade was recently closed. When the returned value is nonzero, the output pointers must be filled when the data is available.
 

BrokerStop (int nTradeID, double dStop): int

Optional function. Adjusts the 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.

Parameters:

nTradeID Input, trade ID number as returned by BrokerBuy.
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.

Returns:

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

BrokerSell (int nTradeID, int nAmount): int

Optional function; closes a trade - completely or partially - at market. If partial closing is not supported by the broker, the trade is completely closed. Only for not NFA compliant accounts.

Parameters:

nTradeID Input, trade ID as returned by BrokerBuy.
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.

Returns:

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.

Parameters:

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

Returns:

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

 

Remarks:

Example: see source\FXCMplugin.cpp

See also:

Brokers, brokerCommand, enterShort/Long, order, DLL, IB, FXCM, Oanda, MT4

► latest version online