Professional Documents
Culture Documents
AmiBroker Auto-Trading Interface For Interactive Brokers 1.3.8 Beta Read Me
AmiBroker Auto-Trading Interface For Interactive Brokers 1.3.8 Beta Read Me
8 Beta Read Me
May 29, 2014 21:03
June 3, 2013: The auto-trading interface is now open-source. For the details see
: http://www.amibroker.com/devlog/2013/06/03/ibcontroller-1-3-8-source-codes-rel
eased/
THIS IS A BETA VERSION OF THE SOFTWARE (see FAQ section for an answer "why is it
marked as BETA?")
AUTOMATIC TRADING BRINGS CERTAIN RISKS !
PLEASE TEST CAREFULLY YOUR CODE USING FIRST DEMO TWS AND THEN PAPER TRADING ACCO
UNT !
AUTOMATIC TRADING INTEFACE IS INTENDED TO MAKE TRADING EASIER AND FASTER BUT IT
IS NOT INTENDED TO BE RUN WITHOUT SUPERVISION.
DON'T LEAVE AUTOMATIC TRADING UNATTENDED AS CERTAIN CIRCUMSTANCES MAY OCCUR LIKE
INTERNET FAILURE, POWER FAILURE, OTHER UNEXPECTED SITUATION THAT MAY LEAD TO SE
RIOUS FINANCIAL LOSS.
INSTALLATION INSTRUCTIONS
Just run the installer and follow the instructions.
See CHANGE LOG below for detailed list of changes.
REQUIREMENTS
AmiBroker 4.70 or higher. Recommended AmiBroker 5.30 especially on Vista and
Windows 7.
TWS workstation (DEMO, PaperTrading is OK) from http://www.interactivebroker
s.com/ . Preferred version: 907 or higher.
DO NOT use TWS version 945.1 - it is buggy, especially web version.
Use standalone TWS 944.3 or earlier instead.
Enable ActiveX and Socket Clients turned ON in TWS (Configure->API menu in T
WS)
DOWNLOAD
The most recent version of IBController (1.3.8) can be downloaded from:
http://www.amibroker.com/at/at1380beta.exe
USAGE INSTRUCTIONS
Introduction
The IB Controller (BrokerIB.EXE) is a separate application that acts as a buffer
between AmiBroker and Interactive Brokers TWS. It accepts commands from AmiBrok
er and send orders to / retrieves information from TWS. It also allows to cancel
/transmit orders manually. The IB controller application is run automatically by
AmiBroker if the formula contains the following call:
ibc = GetTradingInterface("IB");
After this call the BrokerIB.EXE (IB Controller) application is launched and the
ibc variable contains the pointer to OLE automation object that has several met
hods (functions) that allow to place/modify/cancel orders via TWS and to query p
ortfolio information. Those methods (functions) are called as any automation obj
ect methods, for example:
ibc = GetTradingInterface("IB");
if( ibc.IsConnected() ) // check if connection to IB was successfull
{
ibc.PlaceOrder("MSFT", "BUY", 100, "MKT", 0, 0, "DAY", False ); // place orde
r but do not transmit yet
}
Note that this is low-level interface for advanced users that is made available
in so called phase-one of implementing automated trading via IB. There will be h
igher-level interface that will be implemented later.
IB Controller Methods (Functions):
PlaceOrder( string Ticker, string Action, number Quantity, string Type, numb
er LimitPrice, number StopPrice, string TimeInForce, bool Transmit, [optional] n
umber TickSize = 100, [optional] string Attributes = "", [optional] string Paren
tID = "", [optional] string OCAGroup, [optional] number OCAType, [optional] stri
ng FAParams, [optional] string Account)
This function places a new order
Return value:
The function returns the OrderId (string) that can be later used to modify/c
ancel/query status of the order
Parameters:
Ticker - string that specifies the symbol of security/contract to be pur
chased. The symbol should follow the symbology defined in detail at: http://www.
amibroker.com/ib.html
Action - specifies action to be taken, possible values are:
"BUY", "SELL", "SSHORT"
Quantity - the number of shares/contracts to buy/sell
Type - specifies order type, possible values are:
"MKT", "MKTCLS", "LMT", "LMTCLS", "PEGMKT", "STP", "STPLMT", "TRAIL", "R
EL", "VWAP"
- consult the documentation of Interactive Brokers TWS for more informat
ion on order types
LimitPrice - this defines the limit price for limit and stop limit order
s
StopPrice - this defines stop price for stop orders
TimeInForce - defines the time in force of the order, possible values ar
e: "DAY", "GTC", "IOC","GTD"
Starting from v1.0.8 TimeInForce field in PlaceOrder/ModifyOrder accepts
GTD and GAT specifications
GTD - Good Till Date - indicates that the order should remain workign un
til
the time and date set.
Good Till Date specification
GTD YYYYMMDD HH:MM:SS TZONE
where:
YYYY is 4 digit year
MM is 2 digit month
DD is 2 digit day
HH is 2 digit hour
MM is 2 digit minute
SS is 2 digit second (OPTIONAL)
TZONE is time zone (OPTIONAL)
After regular TimeInForce specifications (DAY, GTC, GTD) you may add ext
ra
GoodAfterTime (GAT) part. GAT part comes AFTER semicolon. It indicates t
hat
trade should be submitted after the time and date set:
GAT specifications:
DAY;GAT YYYYMMDD HH:MM:SS TZONE - day order valid after specified date/t
ime
GTC;GAT YYYYMMDD HH:MM:SS TZONE - good till canceled order valid after s
pecified time
GTD yyyymmdd hh:mm:ss tzone;GAT YYYYYMMDD HH:MM:SS TZONE - GTD order val
id after specified time
where:
YYYY is 4 digit year
MM is 2 digit month
DD is 2 digit day
HH is 2 digit hour
MM is 2 digit minute
SS is 2 digit second (OPTIONAL)
TZONE is time zone (OPTIONAL)
Note: there must be NO SPACE characted between semicolon and GAT string.
Examples:
ibc.PlaceOrder("MSFT", "BUY", 100, "LMT", 27, 0, "DAY;GAT 20051214 18:00
:00 GMT", True );
- day limit order good after Dec 14,2005, 18:00 GMT
ibc.PlaceOrder("MSFT", "BUY", 100, "LMT", 27, 0, "GTD 20051215 17:00:00
GMT;GAT 20051214 18:00:00 GMT", True );
- limit order valid from Dec 14,2005 18:00 to Dec 15,2005 17:00 GMT
ibc.PlaceOrder("MSFT", "BUY", 100, "LMT", 27, 0, "GTD 20051215 19:00:00
GMT", True );
- limit order valid from now until Dec 15,2005 19:00 GMT
Transmit - boolean flag that specifies if given order should be actually
transmitted to the exchange.
if this flag is set to FALSE then order is NOT transmitted but appears i
n the TWS workstation so you can press transmit it manually later
additional parameters for IBController 1.0.4 or higher:
TickSize - defines minimum price fluctuation allowed for given symbol ex
pressed in pips (= 0.0001). For most US stocks it is 100 (represents 0.01 move),
for most currencies: 1 (represents 0.0001 move), if minimum move is less than 0
.0001 you can use fractional values for example 1/100 for 0.000001 move.
additional parameters for IBController 1.0.8 or higher :
Attributes - is a string that allows to specify additional order attribu
tes (comma separated list).
Supported attributes:
outsideRTH - if specified means that order will trigger not only during
Regular Trading Hours (RTH), but also in extended trading (pre/after market); th
is applies to stop orders, conditional orders, and alerts; it is used by the tri
ggering logic. If not specified (false) orders will trigger ONLY during RTH.
allOrNone - fill all or nothing at all
eTradeOnly - trade with electronic quotes only
firmQuoteOnly - trade with firm quotes only
Version 1.1 ignoreRth / rthOnly flags are OBSOLETE now and not supported
as TWS API dropped support for those.
This function retrieves the value of the Field of OrderId order from the exe
cution list
Return value:
the numeric or sting value of the requested Field for OrderId. Null if no fi
eld or no such position available
Parameters:
OrderId - string that specifies the order (returned by PlaceOrder functi
on or retrieved by GetExecList).
Field - one of column names found in "Executions" page of IB Controller.
For example "Avg. price" gives average price of purchase of given security, "Fi
lled" gives number of shares/contracts filled
GetExecList( number Type, string Filter )
(new in 1.3.0)
Returns comma separated list of orders from executions list
Parameters:
Type - specifies what should be returned 0 - gives ORDERIDs (currently this
is the ONLY value accepted)
Filter - when not empty it tells IBc that only orders with specified status
should be returned when empty - all orders from pending list are returned.
Examples:
symbols = ibc.GetPendingList( 0, "Filled" );
- returns comma separated list of completely filled order IDs
symbols = ibc.GetPendingList( 0, "" );
- returns list of all orderIDs present in the "executions list"
To extract symbols from the list use this kind of loop:
for( i = 0; ( symbol = StrExtract( symbols, i ) ) != ""; i++ )
{
printf("Symbol: " + symbol + "\n" );
}
Example usage:
execlist = ibc.GetExecList(0,""); // list all orders from executions page
execinfo = "";
for( i = 0; ( OId = StrExtract( execlist, i ) ) != ""; i++ )
{
execinfo = execinfo + OID + " Symbol: " + ibc.GetExecInfo( OID, "Symbol"
) +
" Filled: " + ibc.GetExecInfo( OID, "Filled" ) +
" Avg. price: " + ibc.GetExecInfo( OID, "Avg. price" ) + "\n";
}
_TRACE( execinfo );
Reconnect()
(new in 1.1.0)
Closes connection to TWS and re-opens it, clears all lists and requeries for
pending orders. Essentially gives the same effect as you would achieve by termi
nating and re-running IB Controller.
Examples:
1. Placing and transmitting Market Buy Order for 100 shares when MACD crosses ab
ove Signal line:
Buy = Cross( MACD(), Signal() );
if( LastValue( Buy ) )
{
ibc = GetTradingInterface("IB");
// check if we are connected OK
if( ibc.IsConnected() )
{
// check if we do not have already open position on this stock
if( ibc.GetPositionSize( Name() ) == 0 )
{
// transmit order
ibc.PlaceOrder( Name(), "Buy", 100, "MKT", 0, 0, "Day", True );
}
}
}
2. Placing/modifying a limit order on current price plus $0.10 but without trans
mitting it (manual transmit required).
This code can be run many times and it will modify existing order as long as it
is not transmitted. It uses static variables to store orderId from last run.
// monitoring code
Title =
Msg +
"\nLast TWS message: "+ ibc.GetLastError(0) +
"\nAvailable funds: " + ibc.GetAccountValue("AvailableFunds")+
" Gross Pos. Value: " + ibc.GetAccountValue("GrossPositionValue")+
"\nOrderID = "+OrderId+
"\nTicker = "+Ticker+
"\nAction = "+ACT+
"\nShares = "+NumToStr(NumShares,1.0)+
"\nOrderType = "+OT+
"\nLimitPrice = "+NumToStr(LimitPrice,1.3)+
"\nStopPrice = "+NumToStr(StopPrice,1.3)+
"\nTimeInForce= "+TIF+
"\nTransmit = "+NumToStr(Transmit,1.0)+"\n"+
"\nGetStatus = "+ibc.GetStatus( OrderID )+
"\nGetPositionSize = "+ibc.GetPositionSize( Ticker )+
"\nIsConnected = "+NumToStr(ibc.IsConnected(),1.0) +
"\nExecInfo\n" + execinfo;
4. Placing bracket order
// create instance of trading interface
ibc = GetTradingInterface("IB");
parentID = ibc.PlaceOrder("MSFT", "BUY", 1000, "LMT", 27, 0, "GTC", False );
ibc.PlaceOrder("MSFT", "SELL", 1000, "LMT", 28, 0, "GTC", False, 100, "", parent
ID );
ibc.PlaceOrder("MSFT", "SELL", 1000, "STP", 26, 26, "GTC", True, 100, "", parent
ID );
Note that TRANSMIT flag is set to FALSE on all bracket orders except the last on
e. This ensures that orders wait until bracket order set is completed. Setting T
ransmit flag to TRUE on the very last one transmits entire bracket.
5. Iterating through open positions:
ibc = GetTradingInterface("IB");
openpos = ibc.GetPositionList();
for( i = 0; ( symbol = StrExtract( openpos, i ) ) != ""; i++ )
{
printf("Position " + i + "\tSymbol: " + symbol + "\tSize: " + ibc.GetPositionS
ize( symbol ) + "\n" );
}
6. Placing OCA group orders:
ibc.PlaceOrder("MSFT", "SELL", 1000, "LMT", 28, 0, "GTC", True, 100, "", 0, "MYG
ROUP" );
ibc.PlaceOrder("MSFT", "SELL", 1000, "STP", 26, 26, "GTC", True, 100, "", 0, "MY
GROUP" );
FAQ
1) Why IBController has BETA status?
The reason is simple - because it relies on IB API we have no control upon. You
need to be aware of the fact that Interactive Brokers may and actually do change
TWS and API quite often and any future changes in the API/TWS may produce incom
patiblities without any warning. We try to adjust IBController as soon as such i
ncompatibilities surface, but we can only do that "after the fact". Due to this
there can be periods when IBController does not work properly with certain versi
on(s) of TWS. That is the only reason why IBController is marked as BETA.
2) What exactly is the OrderID, where is the number stored? How does it incremen
t? Can we assign our own OrderIDs?
OrderID is a string that represents the unique order number that is assigned by
IB Controller (for orders placed via IB Controller) or TWS (for orders placed in
TWS) when you place the order. It is automatically incremented on each NEW orde
r. The implementation takes care that generated ID is unique for given session o
f TWS. You should NOT assign your own IDs because you may risk generating duplic
ates that will be rejected by TWS.
3) The IB Interface contains a lot of useful information, can we access this inf
ormation in afl?
GetAccountValue() function (introduced in 1.0.2) allows that.
4) IMPORTANT. During development i often "lose" my connection to the TWS and can
not get it going again. Under what conditions can/does this happen?
This is probably caused by placing ModifyOrder calls too often so TWS is not abl
e handle them and sends error messages ("Unable to modify this order as its stil
l being processed") and it results in IsConnected() returning false. This should
be addressed by next version. If such thing happens you can simply close IB Con
troller window.
5) Is it possible to read IB Last/Bif/Ask prices while running a eSignal databas
e?
Right now there is no access to price data via IBController but maybe in the fut
ure
6) Why do we have a PlaceOrder() and a ModifyOrder(), if ModifyOrder can be used
in both cases?
Just for completeness. Indeed ModifyOrder alone would be enough.
7) Can we retrieve the "Executions" and "Pending" page (string) from the IB Cont
roller window, for display on the chart?
Pending - yes you can retrieve the status of the order while it is on "Pending"
page using GetStatus. As for "execution" tab - as it is already described in the
read me this is in the works.
8) It appears the startup sequence of TWS and AB is significant, is it?
Not actually TWS and AB - they are independent. But what is important to run TWS
before running IB Controller. If you however have your trading code in indicato
r then it may be auto-refreshed at AB start and in this individual case you woul
d need to run TWS before AB. Anyway if something fails you can simply close IB c
ontroller window and it will re-open automatically and reconnect on next call to
GetTradingInterface.
9) When the TWS/AB connection is broken during trading, what is the best way to
restore it?
Close IB Controller manually. It will re-open automatically and reconnect on nex
t call to GetTradingInterface.
10) What is the consequence of repeated PlaceOrder() or ModifyOrder() execution
due to AB Refresh? What happens when, instead of using Cross() with use ">" or "
<"?
Franly auto-trading interface is NOT indented to be used in indicators. It is in
tended to be used in AA window. But if you prefer to run it in IB you can do thi
s too, but then you should check pending orders and check portfolio position siz
e for given symbol not to buy too many shares. To answer your question: multiple
PlaceOrder calls will result in multiple orders placed. Multiple ModifyOrder()
calls may result in the same (if OrderID is empty) or may just result in updatin
g the values of already exisiting, pending order if you specify correct OrderID
of order placed before (see the example 2.)
11) A "clear" Message button would be nice in the IBc window, i have to scroll d
own continuously to see the latest message (perhaps last-on-top scrolling?)
It is already available in version 1.0.2
12) What is the best way to write a single-(user initiated)-execution line of co
de? ... this is where the ParamTask() i suggested earlier would come in handy.
Use new AFL ParamTrigger function
ParamTrigger( "Name", "Button text")
- to be used in indicator builder - to create triggers (buttons).
If you place ParamTrigger in the indicator code it will create a "button" in Par
ameter dialog that can be pressed.
Normally ParamTrigger will return zero (0) but when button in the param window i
s pressed then it will refresh the chart and ParamTrigger will return 1 (one) fo
r this single execution (further refreshes will return zero, until the button is
pressed again)
Example:
trigger = ParamTrigger("Place Order", "Click here to place order");
if( trigger )
{
// your one-shot code here
}
13) When placing orders from an indicator (the thing to do in RT trading) and ed
iting the code will result in additional afl executions, how can i prevent rando
n order placement from the extra passes? Parameters and Signals may not be the s
ame as a result of using loops, DLLs, and things.
Use static variables as given in example 2 to MODIFY existing order instead of p
lacing many new orders. Or use code given in response to question 10
14) I got an warning from TWS that is treated as error in Pending list. How can
I solve that?
You can put specific TWS code onto "Ignore list" (use File->Error code ignore li
st to enter codes in comma separated list). Any code entered here will be ignore
d by Pending List page, but still will be displayed in the messages window.
15) some message in the IBc are not clear/precise in their meaning ...
Well these messages come from TWS and I have no influence on their wording :-)
CHANGE LOG
CHANGES FOR VERSION 1.3.8
removed the workaround introduced in 1.3.5 for symbol translation because it
caused problems for symbols like 6EU0-GLOBEX-FUT where symbol is not equal to l
ocal symbol less expiration code (EUR vs 6E). Instead symbol translation now rel
ies solely on method introduced in 1.3.6
CHANGES FOR VERSION 1.3.7
GetPositionList() returned empty symbol part for non-stocks. Fixed
PlaceOrder failed on Financial advisor accounts when non-master Account was
passed in a parameter without preceding SetAccount call. Fixed.
CHANGES FOR VERSION 1.3.6
IBController now uses more reliable way to translate from local symbol to TW
S symbol/expiry pair based on information sent back by TWS. (It is not as simple
as one may think because sometimes local symbol does not contain TWS symbol, so
one can not derive TWS symbol from local symbol in general case, for example FE
SX SEP 10 local symbol translates to ESTX50,20100917, therefore IBController nee
ds to get info from TWS)
CHANGES FOR VERSION 1.3.5
New SetInfoAccount( account )
This function changes the account which is displayed in the "account informa
tion" window and "portfolio" tabs.
It does NOT change account used for orders.
Separation of order and viewing accounts allows directing orders to any acco
unt withing changing any views, i.e. you can monitor/view "All" account - that d
isplays cumulative information for all F&F/FA accounts or any other account whil
e placing orders for other accounts.
By default viewing information is the "ALL" account and in most cases there
is no need to change it as it receives updates from all sub-accounts.
To workaround recent change in TWS, for futures (FUT) 'symbol' field is set
by IBController as localsymbol without expiration month/year. This is temporary
workaround which may be broken by other TWS releases. Tested to work with TWS 90
7.7
Pending Orders/Executions/Portfolio/Account info tabs now have additional co
mmand "Account" that specifies the account given item refers to
PlaceOrder and ModifyOrder now accept optional Account parameter
This allows to specify destination account for order for F&F/FA IB accounts
in single call, instead of relying on SetAccount/PlaceOrder sequence.
Single-call PlaceOrder/ModifyOrder with account specification allows to spec
ify account without worrying that other threads/processes can switch the account
between SetAccount() and PlaceOrder().
Now SetAccount() only sets account for NEXT order(s). It does NOT clear list
s anymore and does NOT change 'viewing' account
Clearing execution and pending list was problematic because when switching a
ccounts the information about previously sent orders on different account was lo
st on F&F accounts. So SetAccount() does not clear lists automatically. If you w
ant to do this, you can call ClearList( -1 ) explicitely.
Also this function does NOT change the account which is displayed in the "ac
count information" window and "portfolio" tabs.
To change account displayed in the "account information" page and "portfolio
" tabs use new function SetInfoAccount().
Separation of order and viewing accounts allows directing orders to any acco
unt withing changing any views, i.e. you can monitor/view "All" account - that d
isplays cumulative information for all F&F/FA accounts or any other account whil
e placing orders for other accounts.
By default viewing information is the "ALL" account and in most cases there
is no need to change it as it receives updates from all sub-accounts.
ClearList() method accepts -1 as listno - then it clears ALL lists
CHANGES FOR VERSION 1.3.2
fixed compatibility issues with TWS version 904+
CHANGES FOR VERSION 1.3.1
added configuration file to support AmiBroker 5.30 trading from chart functi
onality
CHANGES FOR VERSION 1.3.0
added GetExecList and GetExecInfo functions.