Original (English)
Writing Broker / Data Feed Plugins
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. As a starting point you can use the plugin for a cryptocurrency
REST API, which can be found in Zorro's Source folder. The source
code of other plugins developed by Zorro users is available on the GitHub pages
of their authors.
An article about writing a broker plugin can be found on
Financial Hacker.
The source code of included broker plugins is available on request to Zorro S
users 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; for this you'll need no support ticket or Zorro S subscription.
You can also contact us for outsourcing a plugin
development.
Setting up VC++
Creating a VC++ DLL project with access to all Zorro functions is described under
VC++ project setup. Zorro functions, such as for
HTTP requests or signatures, are often useful for the implementation. But if you
want a plain DLL with no Zorro stuff, do not bind the ZorroDll.cpp
source file, but use the dllmain.cpp file that's automatically
created by VC++. Its DllMain function is the main entry point of
the broker DLL, and you can leave that function unchanged. 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 <trading.h>
If your broker DLL accesses Zorro-specific structs, set the struct alignment
to 4 with a #pragma pack(4) statement before including
trading.h. Otherwise structs have different sizes in Zorro and in your
DLL.
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.
On
Financial Hacker you can find a step by step instruction for implementing a
REST API DLL.
Development and test
The Source folder contains broker plugin examples in .zip archives:
- Simulation is a simple 'broker simulation' plugin that
generates random prices and allows to open a trade with an arbitrary asset.
Use it in NFA mode.
- Bittrex is a REST API plugin for the Bittrex crypto exchange.
- AllyInvest is a Github snaphot of a real broker plugin.
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 Short] - 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 fpMessage, 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, nor call any Zorro functions - all this can 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 adn is used for selecting the plugin. |
fpMessage |
Input, pointer to a int BrokerMessage(const char* Message)
function. The plugin can call BrokerMessage for printing
messages - usually errors - in Zorro's message window. Using this function
is not mandatory, but recommended. 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(intptr_t Progress)
function. The plugin can call it repeatedly to keep Zorro responsive in
long loops or when broker operations take longer than a second, like
BrokerHistory2. When Progress is
0, the Zorro UI will only update its controls for preventing
unresponsiveness. When it is 1, dots will be printed in
the message window for indicating progress of a lengthy 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
BrokerProgress returns 0, someone has
hit Zorro's [Stop] button and the current broker
operation must be aborted. |
Returns:
Broker interface version number; currently 2.
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 |
Input / optional output, char[1024] array, intially
filled with the account id from the account list.
Can be filled with all user's account numbers as subsequent zero-terminated
strings, ending with "" for the last string. When a list is returned,
the first account number is used by Zorro for subsequent BrokerAccount
calls. |
Returns:
Login state: 1 when logged in, 0 otherwise.
BrokerTime (DATE *pTimeUTC): int
Optional function that sends a 'ping' to the server and returns connection status
and server time. Repeatedly called in short intervals during the trading session.
Can be used by the plugin for keeping the session open if required.
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 (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.
Remarks:
- If the UTC server time is not available in the broker API, *pTimeUTC
can be left unchanged. If the market state is not available, let the function
just return 2 or 0 dependent on whether the
connection is established or not.
- If the server time is returned, but does not change for several minutes,
Zorro assumes that the broker server is offline. It then displays
"Offline" in the server window, and suspends trading
and requesting price quotes.
- If the broker API uses a different time format, here's a C++ code example
for converting DATE to/from the Linux time format, which is
the number of seconds since January 1st 1970 midnight:
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.);
}
BrokerRequest (string Path, string Method, string Data): string
Optional function for sending an arbitrary HTTP request to a REST API. Path
is the relative URL including the query string, but without the endpoint root. If
Method begins with '$', the request must be signed.
If Method and Data are both 0, a GET
request should be sent. The response is returned.
BrokerAsset (char* Asset, double *pPrice, double *pSpread, double *pVolume,
double *pPip, double *pPipCost, double *pLotAmount, double *pMargin, double *pRollLong,
double *pRollShort,double *pCommission): int
Subscribes an asset, and/or returns information about it. Zorro subscribes all used
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.
Parameters:
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. Such as trade volume per minute, accumulated daily trade volume,
open interest, ask/bid volume, or tick frequency. 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, like 0.1.
|
pMargin |
Optional output, either initial margin cost for buying 1
lot of the asset in units of the account currency.
Or the leverage of the asset when negative (f.i. -50 for
50:1 leverage). |
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. |
pCommission |
Optional output, roundturn commission per 10,000 contracts for currencies,
per contract for all other assets, in units of the account currency. |
Returns:
1 when the asset is available and the returned data is valid,
0 otherwise.
Remarks:
- If parameters are not supplied by the broker
API, they can be left unchanged. Zorro will then use default values from the
asset list. Only price and spread must always be returned
when the pPrice and pSpread parameters are
nonzero.
- For receiving streaming price data, get the
Zorro window handle from the SET_HWND command
for sending messages to a Zorro window. The message WM_APP+1
triggers a price quote request.
- Dependent on the broker API, some asset parameters might require
unit conversions because lots and pips can have
special meanings. In most APIs, such as the FXCM API, the parameters are directly
available. A more complicated example is the MT4™ API where the parameters
must be corrected by the different scales of "Lot" and "Point"
(MQ4 example):
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;
}
- Asset parameters can be different dependent on when they are requested.
For instance, some brokers charge a three times higher rollover fee on Wednesday
for compensating the weekend. Spreads are usually higher when the market is
closed or illiquid.
- If the broker API can not subscribe an asset, it must be manually subscribed
in the broker platform or website.
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, 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 ticks (for T1 or T2 data; all prices of a
T6 struct get the tick price), 1 for
one-minute (M1) historical candles, or a larger value for low-resolution
data. |
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 or T2 data, or
when only a single price is available, all prices in a T6
struct must 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. 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.
Parameters:
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. |
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.
BrokerBuy2 (char* Asset, int Amount, double StopDist, double Limit, double *pPrice,
int *pFill): int
Sends an order to open a long or short position, either at market, or at a price
limit. Also used for NFA compliant accounts to close
a position by opening a new position in the opposite direction. The order type (FOK,
IOC, GTC) can be set with SET_ORDERTYPE before.
Orders other than GTC are cancelled when they are not completely filled within the
wait time (usually 30 seconds).
Parameters:
Asset |
Input, asset symbol for trading (see Symbols). |
Amount |
Input, number of units, positive for a long trade and negative for
a short trade. For currencies or CFDs, the number of units is the number
of Lots multiplied with the LotAmount.
If LotAmount is < 1 (f.i. for a CFD, or for a fractional
share with 0.1 contracts lot size), the number of lots is given here instead
of the number of units. |
StopDist |
Optional input, 'safety net' stop loss distance to the opening price
when StopFactor was set, or 0 for
no stop, or -1 for indicating that this function was called
for closing a position. This is not the real stop loss, which is handled
by Zorro. Can be ignored if the API is NFA compliant and does not support
a stop loss in a buy/sell order. |
Limit |
Optional input, fill 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 average fill price if the position was partially
or fully filled. If no price was set, Zorro assumes the current price. |
pFill |
Optional output, the fill amount (positive), or 0 for an unfilled
order. If no amount was set, Zorro assumes a complete fill. |
Returns:
- 0 or 1 when the order was rejected or
when a FOK or IOC order was unfilled within the wait
time (adjustable with the SET_WAIT command).
An unfilled FOK or IOC order must be cancelled by the plugin.
- Unique trade or order ID number when the order was successfully placed. If the
broker API does not provide trade or order IDs, the plugin should generate a
unique 6-digit number, f.i. from a counter, and return it as a trade ID.
- -1 when the trade or order identifier is a UUID that is
then retrieved with the GET_UUID command.
- -2 when the broker API did not respond within the
wait time, so the order state is unknown. The
plugin must then cancel the order. Zorro will display a "possible orphan"
warning.
- -3 when the order was accepted, but got no ID yet. The
ID is then taken from the next subsequent BrokerBuy call that
returned a valid ID. This is used for combo positions that require several orders.
BrokerTrade (int nTradeID, double *pOpen, double *pClose, double *pCost, double
*pProfit): int
Optional function that returns the order fill state (for brokers that support only
orders and positions) or the trade state (for brokers that support individual trades).
Called by Zorro for any open trade when the price moved by more
than 1 pip, or when contractUpdate or
contractPrice is called for an option or future trade.
Parameters:
nTradeID |
Input, order/trade ID as returned by BrokerBuy, or
-1 when the trade UUID was set before with a
SET_UUID command. |
pOpen |
Optional output, the average fill price if the trade was partially or fully
filled. If not available by the API, Zorro will estimate the values based on
last price and asset parameters. |
pClose |
Optional output, current bid or ask close price of the trade. If not
available, Zorro will estimale the value based on current ask price and
ask-bid spread. |
pCost |
Optional output, total rollover fee (swap fee) of the trade so far.
If not available, Zorro will estimate the swap from the asset parameters. |
pProfit |
Optional output, current profit or loss of the trade in account currency
units, without rollover and commission. If not available, Zorro will
estimate the profit from the difference of current price and fill price. |
Returns:
- Current fill amount in units or lots as in BrokerBuy2.
- -1 when the trade was completely closed.
- NAY (defined in trading.h) when
the order or trade state was unavailable. Zorro will then assume that the order
was completely filled, and keep the trade open.
- NAY-1 when the order was cancelled or removed by the broker.
Zorro will then cancel the trade and book the profit or loss based on the
current price and the last fill amount.
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, nAmount is
ignored and the trade is completely closed. Only used for not
NFA compliant accounts that support individual closing
of trades. If this function is not provided or if the NFA
flag is set, Zorro closes the trade by calling BrokerBuy2 with
the negative amount and with StopDist at -1.
Parameters:
nTradeID |
Input, trade/order 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, fill 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 amount that was closed from the position,
always positive. |
Returns:
- New trade ID when the trade was partially closed and
the broker assigned a different ID to the remaining position.
- nTradeID when the ID did not change or the trade was
fully closed.
- 0 when the trade was not found or could not be closed.
BrokerCommand (int Command, ...): var
Optional function, directly called by the
brokerCommand function for setting special modes or retrievong
special information from the broker API.
Remarks:
- A broker DLL must contain at least the BrokerOpen
function for being recognized by Zorro and appearing in the scrollbox.
- Functions ending with '2' replace older functions that
are however still supported. For instance, BrokerHistory2 replaced
BrokerHistory, but old plugins with BrokerHistory
will still work.
- The broker plugin has full access to all HTTP and other Zorro functions with the
SET_FUNCTIONS command. The old BrokerHTTP
function is no longer needed, but still supported.
- Date/Time parameters and historical time stamps should be UTC. If
GET_BROKERZONE is supported
and returns a different time zone, they should be in that time zone.
- If the connection breaks down, BrokerTime
will be called in TickTime intervals for determining
if it is still broken. If interrupted for a longer time, Zorro will attempt
to re-login in increasing intervals from minutes to hours until the connection
is established again.
- If optional functions are not implemented
or optional parameters not returned, Zorro replaces them with educated guesses
and assumptions. For instance, if BrokerSell2 is not implemented,
Zorro will assume that trades are closed by buying in opposite direction. If
BrokerTrade is not implemented and thus the fill amount and
fill price of GTC orders cannot be traced, Zorro
will treat the order as if it were completely filled at the entry price, and
will estimate the value of the position from the current price and entry price.
- If BrokerTrade is implemented, it is automatically called
in regular intervals for updating the fill amounts and values of all open positions,
except for contracts. For contracts it is only called by
contractUpdate or contractPrice,
and is preceded by a SET_SYMBOL command with
the current contract symbol.
- For a script with low-level broker access, you can call the above functions
of a broker plugin directly from your script. For this, open the plugin DLL
with LoadLibrary or DefineApi
as described under DLL / API implementation.
The broker DLL may also contain other broker-specific functions that are not
directly used by Zorro, but can be called this way from strategy scripts.
- For passing struct pointers via BrokerProgress from the
API to the Zorro script, make sure that struct member alignment is set to 4
bytes or less. Lite-C does not align or pad struct members.
- For asynchronously triggering a price quote request, send a WM_APP+1
message to the window handle received by the SET_HWND
command. For triggering the callback function, send a
WM_APP+2 message. This can be used for prices streamed by another
thread. An example for sending messages can be found under
HWnd.
- Some crypto exchanges require HMAC
authentication signatures for transmitting orders. There is public
C++ code for that in many code libraries on Github (search for f.i.
sha512.cpp).
- Since Zorro broker plugins are standard 32-bit DLLs,
they can also be used by third party software. For instance, the above functions
can be called from Python using the ctypes library.
Example: see Source folder
See also:
Brokers, Symbols,
brokerCommand, enter,
order, DLL,
IB, FXCM, Oanda,
MT4
►
latest version online
|
Übersetzung (Deutsch)
Entwicklung von Broker- / Data-Feed-Plugins
Zorro unterstützt die meisten großen brokers entweder
über eine direkte Verbindung oder über eine vom Broker unterstützte Plattform,
zum Beispiel über die MT4/5 bridge oder die
Sierra bridge. Eine direkte Verbindung zu einer Broker-API,
einer Börse, einem Market Data Feed oder einer Plattform wird über eine DLL im
Plugin-Ordner von Zorro hergestellt. Zorro durchsucht diesen
Ordner beim Start automatisch und listet alle gültigen DLLs in der
[Broker / Account]-Auswahl auf. Die DLL nutzt die
API des Brokers, um Orders auszuführen und Marktdaten abzurufen. Das Interface
ist so organisiert, dass die DLL so einfach wie möglich bleibt. Für
automatisiertes Trading sind nur wenige Funktionen notwendig. Zusätzliche
Funktionalität, zum Beispiel spezielle Order-Typen oder besondere Daten, kann
über einen optionalen broker command hinzugefügt
werden. Wer programmieren kann und Zugang zur Broker-API-Dokumentation hat, kann
eine Broker-DLL in wenigen Stunden schreiben. Um historische Daten im CSV- oder
JSON-Format von online data sources herunterzuladen,
braucht man keine DLL; ein kleines Script genügt (siehe
assetHistory).
Broker-Plugin schreiben
Plugins können in jeder Sprache geschrieben werden, die DLLs unterstützt, etwa
Java, Pascal, C# oder C++. Viele Plugins wurden von Zorro-Anwendern verfasst, meist
in C++. Wir belohnen sauber in C++ geschriebene Plugins mit einer kostenlosen
Zorro S-Subscription, Lizenz oder Verlängerung.
Als Ausgangspunkt kann man das Plugin für eine Kryptowährungs-REST-API verwenden,
das im Source-Ordner von Zorro zu finden ist. Der Quellcode
anderer von Zorro-Anwendern entwickelter Plugins ist auf den entsprechenden GitHub-Seiten
der Autoren verfügbar.
Einen Artikel über das Schreiben eines Broker-Plugins findet man auf
Financial Hacker.
Der Quellcode zu enthaltenen Broker-Plugins kann auf Anfrage von Zorro-S-Nutzern,
die ein ähnliches Plugin für die Community entwickeln, angefordert werden. Bitte
kontaktieren Sie uns mit einer kurzen Beschreibung Ihres Projekts und Ihrer bisherigen
C++-Erfahrung. Ein Non-Disclosure-Agreement muss unterzeichnet werden, und der fertige
Plugin-Code wird zur Prüfung an uns zurückgeschickt. Technischer
Support ist kostenlos für die Entwicklung von Broker-Plugins; hierfür sind
kein Support-Ticket oder eine Zorro-S-Subscription nötig.
Man kann uns auch bezüglich Outsourcing einer
Plugin-Entwicklung kontaktieren.
Einrichtung von VC++
Wie man ein VC++-DLL-Projekt mit Zugriff auf alle Zorro-Funktionen erstellt, ist
unter VC++ project setup beschrieben. Zorro-Funktionen
wie zum Beispiel HTTP-Anfragen oder Signaturen sind oft nützlich für die
Implementierung. Wer jedoch eine reine DLL ohne Zorro-Funktionen möchte, bindet
nicht die Datei ZorroDll.cpp, sondern die automatisch von VC++
erstellte Datei dllmain.cpp ein. Deren DllMain-Funktion
ist der Haupteinstiegspunkt für die Broker-DLL und kann unverändert bleiben.
Broker-Funktionen benötigen die Datentypen DATE und T6,
daher müssen DATE definiert und trading.h eingebunden
werden, zum Beispiel so:
typedef double DATE;
#include <trading.h>
Wenn Ihre Broker-DLL Zorro-spezifische Structs verwendet, setzen Sie vor dem
Einbinden von trading.h das Struct-Alignment mit
#pragma pack(4) auf 4. Andernfalls haben Structs in Zorro und
in Ihrer DLL unterschiedliche Größen.
Damit eine DLL im Auswahlmenü erscheint, muss sie sich im Ordner
Plugin befinden. Zorro prüft beim Start zuerst, ob sich die DLL
mit LoadLibrary() laden lässt. Falls ja, wird geprüft, ob eine
Funktion BrokerOpen (siehe unten) existiert und ob diese eine
gültige Versionsnummer zurückgibt. Sind beide Bedingungen erfüllt, wird die DLL
registriert und im Auswahlmenü aufgeführt. LoadLibrary schlägt
fehl, wenn DllMain nicht ordnungsgemäß zurückkehrt. Häufige
Ursachen sind die Erstellung einer falschen DLL (z.B. 64-bit oder MFC) oder
fehlende Abhängigkeiten. Je komplexer die verwendeten Bibliotheken sind, desto
eher besteht die Gefahr, dass die DLL auf anderen Rechnern nicht funktioniert. Um
auf Nummer sicher zu gehen, sollten alle benötigten Module in der Distribution
enthalten sein. Im Zweifelsfall kann man die Abhängigkeiten der DLL mit
DependencyWalker überprüfen. Zum Debuggen setzt man
Breakpoints in DllMain und BrokerOpen und
überprüft, was passiert, wenn Zorro startet.
Auf
Financial Hacker gibt es eine Schritt-für-Schritt-Anleitung zur Implementierung
einer REST-API-DLL.
Entwicklung und Test
Im Ordner Source befinden sich Beispiele für Broker-Plugins
in .zip-Archiven:
- Simulation ist ein einfaches "broker simulation"-Plugin, das
Zufallspreise erzeugt und das Öffnen eines Trades mit einem beliebigen Asset
ermöglicht. Verwenden Sie es im NFA-Modus.
- Bittrex ist ein REST-API-Plugin für die Bittrex-Krypto-Börse.
- AllyInvest ist ein GitHub-Snapshot eines echten Broker-Plugins.
Weitere Zorro-Broker-Plugins findet man auf GitHub. Verwenden Sie das am besten
geeignete als Vorlage für Ihr eigenes Plugin. Implementieren Sie die DLL-Funktionen
(siehe unten) in folgender Reihenfolge:
BrokerOpen, BrokerLogin, BrokerAsset, BrokerBuy2. Diese 4 Funktionen
(unten beschrieben) sind das Minimum, um mit dem Broker zu traden. Optional können
folgende Funktionen implementiert werden, wenn sie von der API unterstützt werden:
BrokerAccount, BrokerHistory2, BrokerTime,
BrokerTrade, BrokerSell2, BrokerStop. Jede fertig implementierte
Funktion sollte man mit dem TradeTest-Script testen.
Einige Funktionen müssen nicht vollständig implementiert werden, oder gar nicht.
Für das TradeTest-Script genügen
BrokerOpen und BrokerLogin. Wenn z.B.
BrokerAsset noch fehlt, simuliert Zorro dieses mit Standardwerten.
So kann man Schritt für Schritt die Funktionen hinzufügen und jeweils testen.
Sobald BrokerAsset korrekt implementiert ist, sollte im
Server-Fenster der aktuelle Preis erscheinen. Das TradeTest-Script
öffnet ein Panel mit folgenden Buttons zum Test verschiedener Broker-Funktionen:
[Auto On/Off] - Umschalten für eine simulierte
Trading-Session, die automatisch jede Minute einen Trade eröffnet oder schließt.
[NFA On/Off] - Umschalten des
NFA-Flags. In den meisten US-Konten notwendig; für
die meisten Forex/CFD-Konten nicht aktivieren.
[Hedge] - Umschalten verschiedener
Hedge-Modi (0, 2, 4 und 5). Manche Broker unterstützen
kein echtes Hedging (Modus 2) oder kein Teil-Schließen (Modus 5).
[Order] - Umschalten zwischen Limit (LMT),
Market Orders (MKT), Good-til-cancelled (GTC)
und Adaptive Orders (Adaptive), falls vom Plugin unterstützt.
[Asset] - Eingabe des zu handelnden Asset-Symbols
(Vorgabe: Asset aus der Auswahlliste).
[Buy Long] - Eröffnung einer Long-Position mit der
in den Slidern eingestellten Lots- und
Stop-Größe.
[Buy Short] - Eröffnung einer Short-Position.
Abhängig von Hedge wird eine offene Position in entgegengesetzter
Richtung geschlossen.
[Close Long] - Schließt die angegebene Lots-Anzahl
einer offenen Long-Position. Teilweises Schließen wird von einigen Brokern nicht
unterstützt.
[Close Short] - Schließt die angegebene Lots-Anzahl
einer offenen Short-Position.
[Update Stop] - Setzt den Stop
aller offenen Positionen auf den per Slider angegebenen Wert (in Pips). Nicht
alle Broker unterstützen eine nachträgliche Stop-Anpassung. Durch
StopFactor liegt der Broker-Stop meist weiter entfernt
als der eigentliche Stop.
Mit LMT-Orders wird versucht, die Position zum halben Spread zu eröffnen,
Adaptive Orders versuchen es zum Spread = 0. Dafür muss der Broker echte Limit-Orders
unterstützen; MT4-"Pending Orders" sind keine echten Limit Orders und funktionieren
nicht für LMT oder Adaptive. Verschiedene Trading-Modi, Broker Commands, Asset-Listen
usw. können in #define-Anweisungen am Anfang des TradeTest-Scripts
eingestellt werden.
Broker-API-Funktionen
Die Broker-DLL exportiert Funktionen, die in der folgenden Liste beschrieben
sind. Unter VC++ müssen exportierte DLL-Funktionen entweder mit
extern "C" __declspec(dllexport) deklariert oder in einer
.def-Datei aufgeführt werden. Die DLL-Funktionen nutzen nur
einen kleinen Teil einer üblichen Broker-API. In der folgenden Liste können
Pointer-Argumente, die kursiv geschrieben sind,
NULL sein; falls sie ungleich 0 sind, muss die Funktion die
entsprechenden Daten eintragen. Alle Daten sind obligatorisch, sofern nicht anders
vermerkt.
BrokerOpen (char* Name, FARPROC fpMessage, FARPROC fpProgress) : int
Wird beim Start für alle im Ordner Plugin gefundenen
Broker-DLLs aufgerufen. Ruft den Namen des Brokers ab und setzt zwei Callback-Funktionen.
Sollte keine Ressourcen laden oder allozieren und keine Zorro-Funktionen aufrufen;
all das kann in BrokerLogin geschehen.
Parameter:
Name |
Ausgabe, char[32]-Array, das mit dem Namen des Brokers
gefüllt werden soll, z.B. "FXCM". Dieser Name wird im Account-Menü
angezeigt und dient der Auswahl des Plugins. |
fpMessage |
Eingabe, Zeiger auf die Funktion
int BrokerMessage(const char* Message). Das Plugin kann
BrokerMessage aufrufen, um Nachrichten - üblicherweise
Fehler - in Zorros Nachrichtenfenster auszugeben. Der Gebrauch dieser
Funktion ist nicht zwingend, aber empfehlenswert. Beginnt der String mit
einem Ausrufezeichen '!', öffnet Zorro ein Alert-Fenster.
Beginnt er mit einem Hash '#', wird er nur in die
Diagnosedatei geschrieben. |
fpProgress |
Eingabe, Zeiger auf die Funktion
int BrokerProgress(intptr_t Progress). Diese kann vom
Plugin regelmäßig aufgerufen werden, um Zorro während längerer Vorgänge
(z.B. BrokerHistory2) reaktionsfähig zu halten. Ist
Progress = 0, aktualisiert die Zorro-Oberfläche
nur ihre Steuerelemente. Ist Progress = 1,
werden im Nachrichtenfenster Punkte gedruckt, um den Fortschritt eines
zeitintensiven Ablaufs anzuzeigen. Handelt es sich bei Progress
um einen Pointer und existiert im Skript eine
callback-Funktion, wird diese
Funktion aufgerufen und der Pointer übergeben, um Skriptfunktionen aus der
Broker-API heraus auszulösen. Liefert BrokerProgress =
0 zurück, hat der Nutzer den [Stop]-Knopf
gedrückt, sodass der aktuelle Broker-Vorgang abgebrochen werden muss. |
Rückgabewert:
Die Version der Broker-Schnittstelle; momentan 2.
BrokerLogin (char* User, char* Pwd, char* Type, char* Accounts): int
Login oder Logout beim Broker-API-Server; wird im [Trade]-Modus
oder zum Herunterladen historischer Preisdaten aufgerufen. Falls die Verbindung
zum Server abgebrochen ist (z.B. durch Internetprobleme oder Wartungsarbeiten
am Wochenende), ruft Zorro diese Funktion in regelmäßigen Abständen auf, bis
eine erneute Anmeldung erfolgreich ist. Die Funktion sollte intern den Login-Status
erkennen und eine sichere Rückgabe liefern, falls der Anwender noch eingeloggt ist.
Parameter:
User |
Eingabe, Benutzername zur Anmeldung oder NULL zum Logout. |
Pwd |
Eingabe, Passwort zur Anmeldung. |
Type |
Eingabe, Kontotyp; entweder "Real" oder "Demo".
|
Accounts |
Eingabe / optional Ausgabe, char[1024]-Array, initial
gefüllt mit der Kontonummer aus der account list.
Das Plugin kann dieses Array mit allen Kontonummern füllen, jeweils
per Null-Terminierung getrennt, und am Ende mit "" abschließen. Wenn mehrere
Konten zurückgegeben werden, wählt Zorro das erste Konto für alle
BrokerAccount-Aufrufe. |
Rückgabewert:
1 bei erfolgreichem Login, sonst 0.
BrokerTime (DATE *pTimeUTC): int
Optionale Funktion, die einen "Ping" an den Server sendet und den Verbindungsstatus
sowie die Serverzeit abfragt. Wird in kurzen Abständen während der Trading-Session
aufgerufen. Kann vom Plugin genutzt werden, um die Session offen zu halten, falls
nötig.
Parameter:
pTimeUTC |
Optionale Ausgabe, aktuelle Serverzeit in UTC / GMT+0 ohne Sommerzeit.
Das Format DATE (OLE date/time) ist ein double-Wert,
der die Tage seit Mitternacht am 30. Dezember 1899 zählt; Stunden, Minuten
und Sekunden sind dabei als Teil dieses Tageswerts abgebildet. |
Rückgabewert:
0, wenn die Verbindung zum Server verloren wurde (siehe
Anmerkungen).
1, wenn die Verbindung steht, der Markt aber geschlossen ist
oder keine Orders angenommen werden.
2, wenn die Verbindung steht und der Markt für Trading bei
mindestens einem der abonnierten Assets geöffnet ist.
Anmerkungen:
- Falls die UTC-Serverzeit nicht von der Broker-API geliefert wird, kann
*pTimeUTC unverändert bleiben. Wenn der Marktstatus unbekannt
ist, genügt es, 2 oder 0 je nach bestehender
oder fehlender Verbindung zurückzugeben.
- Wenn die Serverzeit mehrere Minuten lang konstant bleibt, nimmt Zorro an,
dass der Server offline ist. Dann zeigt Zorro "Offline" im Server-Fenster an
und pausiert Trading und Kursabfragen.
- Wenn das Broker-API ein anderes Zeitformat nutzt, hier ein C++-Beispiel
zum Konvertieren von DATE in das Linux-Zeitformat (Sekunden
seit 1.1.1970 Mitternacht) und umgekehrt:
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.);
}
BrokerRequest (string Path, string Method, string Data): string
Optionale Funktion für das Senden einer beliebigen HTTP-Anfrage an eine REST-API.
Path ist die relative URL inklusive Query-String, aber ohne
den Endpunkt ("Root"). Wenn Method mit "$"
beginnt, muss die Anfrage signiert werden. Wenn Method und
Data beide 0 sind, sollte eine GET-Anfrage
gesendet werden. Die Antwort wird zurückgegeben.
BrokerAsset (char* Asset, double *pPrice, double *pSpread, double *pVolume,
double *pPip, double *pPipCost, double *pLotAmount, double *pMargin, double *pRollLong,
double *pRollShort, double *pCommission): int
Abonniert ein Asset und/oder gibt Informationen darüber zurück. Zorro abonniert
alle verwendeten Assets zu Beginn einer Trading-Session. Preis und Spread für
alle Assets werden in TickTime-Abständen oder dann
abgerufen, wenn vom Plugin zuvor BrokerProgress aufgerufen wurde.
Andere Asset-Daten werden einmal pro Bar abgefragt.
Parameter:
Asset |
Eingabe, Asset-Symbol für Live-Preise (siehe
Symbols). |
pPrice |
Optionale Ausgabe, aktueller Ask-Preis des Assets oder NULL
zum reinen Abonnieren des Assets. Ein Asset muss abonniert sein, bevor es
Infos dazu geben kann. |
pSpread |
Optionale Ausgabe, die aktuelle Differenz zwischen Ask- und Bid-Preis
des Assets. |
pVolume |
Optionale Ausgabe, ein Parameter, der das aktuelle Angebot und die
Nachfrage des Assets widerspiegelt (z.B. Handelsvolumen pro Minute,
akkumuliertes Tagesvolumen, Open Interest, Ask/Bid-Volumen, Tick-Frequenz).
Falls ein Wert zurückgegeben wird, sollte dieser konsistent zum Wert
fVol in den T6-Strukturen von
BrokerHistory2 sein (siehe unten). |
pPip |
Optionale Ausgabe, die Größe eines PIPs, z.B.
0.0001 bei EUR/USD. |
pPipCost |
Optionale Ausgabe, Gewinn/Verlust-Kosten pro 1 PIP und
Lot in Einheiten der Kontowährung. Wenn nicht
direkt verfügbar, nach asset list-Methode berechnen. |
pLotAmount |
Optionale Ausgabe, Mindesthandelsgröße, d.h. Anzahl Kontrakte für 1
Lot des Assets. Bei Währungspaaren sind das
meist 10.000 in Mini-Lot-Konten und 1.000 in Micro-Lot-Konten. Bei CFDs
ist es oft 1, manchmal aber auch nur 0.1 Kontrakte. |
pMargin |
Optionale Ausgabe, entweder die Initial Margin für den Kauf von 1
Lot in Einheiten der Kontowährung oder bei
negativem Wert den Hebel (z.B. -50 für
50:1 Leverage). |
pRollLong |
Optionale Ausgabe, Rollover-Gebühr für Long-Trades (Zinsen, die pro
Nacht auf dem Konto gutgeschrieben oder belastet werden). Der Wert ist
die tägliche Gebühr pro 10.000 Kontrakte bei Währungspaaren bzw. pro
Kontrakt bei allen anderen Assets, gemessen in Einheiten der Kontowährung. |
pRollShort |
Optionale Ausgabe, Rollover-Gebühr für Short-Trades. |
pCommission |
Optionale Ausgabe, Roundturn-Kommission pro 10.000 Kontrakte bei
Währungspaaren bzw. pro Kontrakt bei allen anderen Assets, in Einheiten
der Kontowährung. |
Rückgabewert:
1, wenn das Asset verfügbar ist und gültige Daten liefert,
0 sonst.
Anmerkungen:
- Wenn die Parameter nicht von der Broker-API
bereitgestellt werden, können sie unverändert bleiben. Zorro nutzt dann die
Standardwerte aus der asset list. Nur Preis und
Spread müssen immer zurückgegeben werden, wenn pPrice und
pSpread ungleich NULL sind.
- Um streaming price data zu empfangen,
kann über den SET_HWND-Befehl das Handle zum
Zorro-Fenster abgefragt werden. Eine Nachricht vom Typ
WM_APP+1 an dieses Fenster triggert dann das Abfragen neuer
Kurse.
- Abhängig vom Broker-API können einige Asset-Parameter
Konvertierungen erfordern, da Lots und Pips
unterschiedlich definiert sein können. In vielen APIs (z.B. FXCM) sind sie
direkt verfügbar. Ein komplizierteres Beispiel ist die MT4™-API, bei der
die Werte aufgrund unterschiedlicher Skalen für "Lot" und "Point" korrigiert
werden müssen (MQ4-Beispiel):
double Price = MarketInfo(Asset,MODE_ASK);
double Spread = Price - MarketInfo(Asset,MODE_BID);
double Volume = 0;
double LotFactor = MarketInfo(Asset,MODE_MINLOT); // Korrektur für unterschiedliche Lot-Skalen
double Pip = MarketInfo(Asset,MODE_POINT);
double PipCost = MarketInfo(Asset,MODE_TICKVALUE) * LotFactor;
int DigitSize = MarketInfo(Asset,MODE_DIGITS); // Korrektur bei 5-stelligen Kursen
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;
}
- Asset-Parameter können je nach Zeitpunkt unterschiedlich sein. Zum Beispiel
berechnen manche Broker mittwochs dreifache Rollover-Gebühren, um das Wochenende
abzudecken. Spreads sind bei geschlossenen oder illiquiden Märkten in der Regel
höher.
- Wenn das Broker-API kein Asset-Abonnement unterstützt, muss man das Asset
eventuell manuell in der Broker-Plattform oder auf der Website abonnieren.
BrokerHistory2 (char* Asset, DATE tStart, DATE tEnd, int nTickMinutes, int nTicks,
T6* ticks): int
Liefert die Preishistorie eines Assets. Aufgerufen durch
assetHistory und zu Beginn einer Trading-Session,
um den lookback-Zeitraum zu füllen.
Parameter:
Asset |
Eingabe, Asset-Symbol für historische Preise
(siehe Symbols). |
tStart |
Eingabe, UTC-Startdatum/-zeitpunkt der Preishistorie
(siehe BrokerTime zum DATE-Format).
Dieser Wert ist nur ein "nicht weiter zurück"-Zeitpunkt; das wesentliche
Startdatum ist tEnd. |
tEnd |
Eingabe, UTC-Enddatum/-zeitpunkt der Preishistorie. Wenn die
Preishistorie nicht in UTC, sondern in lokaler Brokerzeit vorliegt, muss
das Plugin die Zeit selbst nach UTC umrechnen. |
nTickMinutes |
Eingabe, Zeitspanne eines Ticks in Minuten. Übliche Werte sind
0 für Einzelticks (T1- oder T2-Daten, wobei alle Preise
in einem T6 gleich gesetzt werden), 1
für 1-Minuten-Kerzen (M1) oder ein größerer Wert für geringere Auflösung. |
nTicks |
Eingabe, maximale Anzahl an Ticks, die gefüllt werden sollen; darf
den Wert von brokerCommand(GET_MAXTICKS,0) nicht
überschreiten oder sonst 300. |
ticks |
Ausgabe, Array von T6-Strukturen (definiert in
include\trading.h), das mit Ask-Preisen, Endzeit der
Kerze und weiteren verfügbaren Daten wie historischem Spread und Volumen
gefüllt werden soll. Siehe history. Das Array
ticks wird in umgekehrter Reihenfolge befüllt, beginnend
bei tEnd, bis entweder tStart erreicht
oder die Anzahl nTicks ausgeschöpft ist. Der jüngste Tick
(nahe tEnd) steht vorn im Array. Bei T1-
oder T2-Daten bzw. wenn nur ein einzelner Preis verfügbar
ist, müssen alle Preise in einer T6-Struktur gleich sein. |
Rückgabewert:
Anzahl der gelieferten Ticks oder 0, falls keine Ticks geliefert
werden konnten (z.B. Server offline, Asset nicht abonniert oder Historie nicht
verfügbar für den angegebenen Zeitraum).
BrokerAccount (char* Account, double *pBalance, double *pTradeVal, double *pMarginVal):
int
Optionale Funktion. Wird regelmäßig von Zorro aufgerufen und soll die aktuellen
Kontodaten liefern. Außerdem kann hier das Konto gewechselt werden, falls mehrere
Konten unterstützt werden. Ist diese Funktion nicht vorhanden (z.B. bei FIX-APIs),
schätzt Zorro Kontostand, Equity und Margin anhand anfänglicher Werte und der
realisierten sowie offenen Trades.
Parameter:
Account |
Eingabe, neue Kontonummer oder NULL für das aktuelle
Konto. |
pBalance |
Optionale Ausgabe, aktuelles Kontoguthaben. |
pTradeVal |
Optionale Ausgabe, aktueller Wert aller offenen Trades; die Differenz
aus Kontoequity und dem über pBalance gelieferten Guthaben.
Falls nicht vorhanden, schätzt Zorro die Equity aus dem Kontostand und
den offenen Trades. Wenn kein Guthaben pBalance zurückgegeben
wird, kann hier die gesamte Equity stehen. |
pMarginVal |
Optionale Ausgabe, gesamte derzeit gebundene Margin aller offenen Trades. |
Rückgabewert:
1, wenn das Konto gefunden wird und gültige Werte liefert,
0, wenn ein falsches Konto angegeben wurde oder kein Konto gefunden
werden konnte.
BrokerBuy2 (char* Asset, int Amount, double StopDist, double Limit, double *pPrice,
int *pFill): int
Sendet eine Order zum Öffnen einer Long- oder Short-Position, entweder als Market-Order
oder mit Limit-Preis. Außerdem wird diese Funktion bei NFA-konformen
Konten genutzt, um eine Position zu schließen, indem man eine Gegenposition eröffnet.
Der Order-Typ (FOK, IOC, GTC) kann zuvor mit SET_ORDERTYPE
gesetzt werden. Andere Order-Typen als GTC werden storniert, wenn sie innerhalb der
wait time (in der Regel 30 Sekunden) nicht vollständig
ausgeführt werden.
Parameter:
Asset |
Eingabe, Asset-Symbol für den Trade
(siehe Symbols). |
Amount |
Eingabe, Anzahl Einheiten, positiv für Long, negativ für Short. Bei
Währungen oder CFDs ist dies die Anzahl an Lots
multipliziert mit dem LotAmount. Ist
LotAmount < 1 (z.B. bei CFDs oder Bruchstücken einer
Aktie mit 0.1 Kontrakten), entspricht die Zahl hier den Lots anstatt den
Einheiten. |
StopDist |
Optionale Eingabe, Distanz des "safety net" StopLoss zum Eröffnungspreis,
falls StopFactor gesetzt ist, oder 0
für keinen Stop, oder -1 als Kennzeichnung, dass hiermit
eine Position geschlossen werden soll. Dies ist nicht der eigentliche StopLoss,
der wird von Zorro verwaltet. Bei NFA-konformer API, die keinen StopLoss
in Buy/Sell unterstützt, kann das ignoriert werden. |
Limit |
Optionale Eingabe, Ausführungspreis für Limit-Orders, über
OrderLimit konfiguriert, oder 0
für Market-Orders. Falls die API keine Limit-Orders erlaubt, ignorieren. |
pPrice |
Optionale Ausgabe, durchschnittlicher Ausführungspreis, falls die Order
teilweise oder vollständig gefüllt wurde. Wird kein Preis zurückgegeben,
nimmt Zorro den aktuellen Preis an. |
pFill |
Optionale Ausgabe, Füllmenge (positiv), oder 0 bei ungefüllter Order.
Wird kein Wert übergeben, nimmt Zorro an, dass die Order vollständig
ausgeführt wurde. |
Rückgabewert:
- 0 oder 1 bei Ablehnung oder falls eine
FOK- oder IOC-Order innerhalb der wait time
nicht gefüllt wurde (einstellbar mit SET_WAIT);
in diesem Fall muss die Order vom Plugin storniert werden.
- Eine eindeutige Trade- oder Order-ID, falls die Order erfolgreich platziert
wurde. Stellt die API keine ID bereit, sollte das Plugin eine eindeutige 6-stellige
ID erzeugen (z.B. über einen Zähler).
- -1, wenn die Order/Trade-ID ein UUID ist, der anschließend
über GET_UUID abgefragt wird.
- -2 bei keiner Antwort der Broker-API während der
wait time, sodass der Orderstatus unbekannt ist.
Das Plugin muss die Order dann stornieren. Zorro zeigt
"possible orphan" an.
- -3, wenn die Order akzeptiert wurde, aber noch keine ID
vorliegt. Die ID wird dann beim nächsten
BrokerBuy-Aufruf, der eine gültige ID liefert, übernommen
(verwendet bei Combo-Positionen, die mehrere Orders benötigen).
BrokerTrade (int nTradeID, double *pOpen, double *pClose, double *pCost, double
*pProfit): int
Optionale Funktion, die den Status einer Order oder eines Trades abfragt. Wird
von Zorro bei jedem offenen Trade aufgerufen, sobald sich der Kurs um mehr als
1 Pip bewegt, oder durch contractUpdate bzw.
contractPrice bei Futures/Optionen.
Parameter:
nTradeID |
Eingabe, Order/Trade-ID (von BrokerBuy) oder
-1, wenn vorher ein UUID via
SET_UUID gesetzt wurde. |
pOpen |
Optionale Ausgabe, durchschnittlicher Ausführungspreis, falls die
Position teilweise oder vollständig gefüllt wurde. Ist dieser Wert in der
API nicht verfügbar, schätzt Zorro ihn anhand des letzten Preises und der
Asset-Parameter. |
pClose |
Optionale Ausgabe, aktueller Bid- oder Ask-Kurs zum Schließen der
Position. Falls nicht vorhanden, ermittelt Zorro einen geschätzten Wert
aus aktuellem Ask-Preis und Spread. |
pCost |
Optionale Ausgabe, bisher angefallene Rollover- (Swap-)Gebühren für
diesen Trade. Falls nicht verfügbar, schätzt Zorro den Swap basierend
auf den Asset-Parametern. |
pProfit |
Optionale Ausgabe, aktueller Gewinn oder Verlust des Trades in
Kontowährung, ohne Rollover und Kommission. Falls nicht verfügbar,
berechnet Zorro den Gewinn aus der Differenz von aktuellem Kurs und
Ausführungspreis. |
Rückgabewert:
- Aktuelle gefüllte Menge (units oder lots) entsprechend
BrokerBuy2.
- -1 bei komplett geschlossenem Trade.
- NAY (in trading.h definiert), wenn
der Order-/Trade-Status unbekannt ist. Zorro nimmt dann an, dass die Order
vollständig gefüllt wurde, und lässt den Trade offen.
- NAY-1 bei stornierter oder entfernter Order durch
den Broker. Zorro storniert in diesem Fall auch den Trade und verbucht den
Gewinn/Verlust basierend auf dem aktuellen Preis und letzter Füllmenge.
BrokerSell2 (int nTradeID, int nAmount, double Limit, double *pClose, double
*pCost, double *pProfit, int *pFill): int
Optionale Funktion zum (vollständigen oder teilweisen) Schließen eines Trades
per Market-Order oder Limit-Order. Wenn Teil-Schließen nicht unterstützt wird,
wird nAmount ignoriert und der Trade vollständig geschlossen.
Nur relevant für nicht NFA-konforme Konten, die
ein individuelles Schließen von Trades unterstützen. Falls diese Funktion
fehlt oder das NFA-Flag gesetzt ist, schließt Zorro
den Trade durch Aufruf von BrokerBuy2 mit negativem Amount
und StopDist = -1.
Parameter:
nTradeID |
Eingabe, Order-/Trade-ID wie bei BrokerBuy2 geliefert,
oder -1 für einen zuvor per
SET_UUID gesetzten UUID. |
nAmount |
Eingabe, Anzahl Kontrakte oder Lots, die geschlossen werden sollen
(positiv bei Long, negativ bei Short, siehe BrokerBuy).
Ist das weniger als die Gesamtgröße des Trades, wird nur teilweise
geschlossen. |
Limit |
Optionale Eingabe, Ausführungspreis für eine Limit-Order, wie über
OrderLimit eingestellt, oder 0
für Market. Falls die API keine Limit-Orders unterstützt, ignorieren. |
pClose |
Optionale Ausgabe, Kurs beim Schließen. |
pCost |
Optionale Ausgabe, aufsummierte Rollover- (Swap-)Gebühren des Trades. |
pProfit |
Optionale Ausgabe, Gesamtgewinn/-verlust in Kontowährung. |
pFill |
Optionale Ausgabe, Menge (positiv), die von der Position geschlossen
wurde. |
Rückgabewert:
- Neue Trade-ID, falls der Broker beim teilweisen Schließen eine andere
ID für die Restposition vergibt.
- nTradeID bei unveränderter ID oder vollständigem
Schließen.
- 0 bei nicht gefundenem oder nicht geschlossenem Trade.
BrokerCommand (int Command, ...): var
Optionale Funktion, die direkt durch
brokerCommand aufgerufen wird, um spezielle Modi einzustellen
oder besondere Informationen aus der Broker-API abzurufen.
Anmerkungen:
- Eine Broker-DLL benötigt mindestens die Funktion BrokerOpen,
um von Zorro erkannt zu werden und im Auswahlmenü zu erscheinen.
- Funktionen mit Endung '2' ersetzen ältere Funktionen,
die aber noch unterstützt werden. BrokerHistory2 ersetzt
z.B. BrokerHistory, jedoch funktionieren alte Plugins mit
BrokerHistory weiterhin.
- Über den Befehl SET_FUNCTIONS kann das
Broker-Plugin auf alle HTTP- und sonstigen Zorro-Funktionen zugreifen. Die
ältere Funktion BrokerHTTP ist nicht mehr nötig, wird aber
noch unterstützt.
- Zeit- und Datumswerte sowie historische Zeitstempel sollten in UTC angegeben
werden. Falls GET_BROKERZONE
unterstützt wird und eine andere Zeitzone zurückliefert, sind diese Werte in
dieser Zeitzone zu führen.
- Bricht die Verbindung ab, ruft Zorro in TickTime-Abständen
BrokerTime auf, um zu prüfen, ob sie noch unterbrochen ist.
Dauert die Unterbrechung länger, versucht Zorro mehrmals, in zunehmend größer
werdenden Zeitabständen (Minuten, dann Stunden) den Login erneut.
- Werden optionale Funktionen nicht
implementiert oder optionale Parameter nicht zurückgegeben, gleicht Zorro das
durch Annahmen und Schätzungen aus. Existiert z.B.
BrokerSell2 nicht, nimmt Zorro an, dass Trades durch
gegengerichtetes Kaufen geschlossen werden. Ohne BrokerTrade
kann Zorro die Füllmenge und den Preis einer GTC-Order nicht verfolgen und
nimmt an, dass sie zum Einstiegszeitpunkt vollständig gefüllt wurde. Den
Wert der Position schätzt es dann aus aktuellem Kurs und Einstiegsniveau.
- Falls BrokerTrade implementiert ist, wird es regelmäßig
für offene Trades aufgerufen, außer bei Kontrakten; dort nur bei
contractUpdate bzw.
contractPrice und nach einem
SET_SYMBOL-Befehl zum entsprechenden
Kontraktsymbol.
- Für ein Skript mit direktem Zugriff auf Brokerfunktionen kann man die oben
genannten Funktionen eines Broker-Plugins auch direkt aus dem Skript aufrufen
(z.B. per LoadLibrary oder
DefineApi, siehe
DLL / API implementation). Ein Broker-Plugin kann
außerdem weitere Funktionen enthalten, die Zorro selbst nicht nutzt, die aber
vom Skript aufgerufen werden können.
- Für das asynchrone Auslösen einer Kursabfrage kann man
WM_APP+1 an das Fenster-Handle senden, das man zuvor per
SET_HWND erhalten hat. Für den Aufruf der
callback-Funktion sendet man
WM_APP+2. So kann man etwa Streaming-Kurse in einem eigenen
Thread verarbeiten. Ein Beispiel zum Senden dieser Nachrichten steht unter
HWnd.
- Einige Krypto-Börsen verlangen HMAC-Authentifizierung (Signatur) für
Ordertransaktionen. Entsprechenden öffentlichen Beispielcode in C++ findet
man auf GitHub, z.B. sha512.cpp.
- Da Zorro-Broker-Plugins Standard-32-bit-DLLs sind, können sie auch von
Drittsoftware genutzt werden, z.B. in Python per ctypes.
Beispiel: siehe Source-Ordner
Siehe auch:
brokers, Symbols,
brokerCommand, enter,
order, DLL,
IB, FXCM, Oanda,
MT4
►
latest version online
|