AmiBroker Auto-Trading interface for Interactive Brokers 1.3.0 Beta Read Me
October 23, 2009 22:55 

THIS IS A BETA VERSION OF THE SOFTWARE. EXPECT BUGS !!!

AUTOMATIC TRADING BRINGS CERTAIN RISKS ! 
PLEASE TEST CAREFULLY YOUR CODE USING FIRST DEMO TWS AND THEN PAPER TRADING ACCOUNT !

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, SOFTWARE CRASH, ETC THAT MAY LEAD TO SERIOUS FINANCIAL LOSS.

INSTALLATION INSTRUCTIONS

Just run the installer and follow the instructions. 

See CHANGE LOG below for detailed list of changes.

REQUIREMENTS

AmiBroker 4.63.1 beta or higher. Preferred 5.10 or higher. 
TWS workstation (DEMO, PaperTrading is OK) from http://www.interactivebrokers.com/ . Preferred version: 890+ (min version 879) 
Enable ActiveX and Socket Clients turned ON in TWS (Configure->API menu in TWS) 
DOWNLOAD

The most recent version of IBController (1.3.0) can be downloaded from:
http://www.amibroker.com/at/at1300beta.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 AmiBroker 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 methods (functions) that allow to place/modify/cancel orders via TWS and to query portfolio information. Those methods (functions) are called as any automation object 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 order 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 higher-level interface that will be implemented later.

IB Controller Methods (Functions):

PlaceOrder( string Ticker, string Action, number Quantity, string Type, number LimitPrice, number StopPrice, string TimeInForce, bool Transmit, [optional] number TickSize = 100, [optional] string Attributes = "", [optional] string ParentID = "", [optional] string OCAGroup, [optional] number OCAType, [optional] string FAParams)

This function places a new order

Return value: 

The function returns the OrderId (string) that can be later used to modify/cancel/query status of the order

Parameters: 
Ticker - string that specifies the symbol of security/contract to be purchased. 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", "REL", "VWAP"
- consult the documentation of Interactive Brokers TWS for more information on order types 
LimitPrice - this defines the limit price for limit and stop limit orders 
StopPrice - this defines stop price for stop orders 
TimeInForce - defines the time in force of the order, possible values are: "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 until
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 extra
GoodAfterTime (GAT) part. GAT part comes AFTER semicolon. It indicates that
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/time
GTC;GAT YYYYMMDD HH:MM:SS TZONE - good till canceled order valid after specified time
GTD yyyymmdd hh:mm:ss tzone;GAT YYYYYMMDD HH:MM:SS TZONE - GTD order valid 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 in 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 expressed 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 attributes (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); this applies to stop orders, conditional orders, and alerts; it is used by the triggering 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.


By default all those flags are INACTIVE (OFF)

Example:
ibc.PlaceOrder("MSFT", "BUY", 1000, "LMT", 27, 0, "GTD 20051215 19:00:00 GMT", True, 100, "allOrNone" ); 


(Note that optional parameter TickSize MUST be specified if you want to use Attributes)

ParentID - is a string that specifies parent order identifier (returned by previous PlaceOrder call)
allowing you to place BRACKET orders.

Example:

parentID = ibc.PlaceOrder("MSFT", "BUY", 1000, "LMT", 27, 0, "GTC", False ); 
ibc.PlaceOrder("MSFT", "SELL", 1000, "LMT", 28, 0, "GTC", False, 100, "", parentID ); 
ibc.PlaceOrder("MSFT", "SELL", 1000, "STP", 26, 26, "GTC", True, 100, "", parentID );

Note that TRANSMIT flag is set to FALSE on all bracket orders except the last one. This ensures that orders wait until bracket order set is completed. Setting Transmit flag to TRUE on the very last one transmits entire bracket.

OCAGroup - optional string parameter (new in 1.1.0) that allows to define OCA (One-Cancels-All) group of orders
OCA group orders work in conjuntion with one another so when one order within the group is executed the remaining orders are canceled. For more info see: http://www.interactivebrokers.com/php/webhelp/Making_Trades/Create_Order_Types/oca.htm

Example:
ibc.PlaceOrder("MSFT", "SELL", 1000, "LMT", 28, 0, "GTC", True, 100, "", 0, "MYGROUP" ); 
ibc.PlaceOrder("MSFT", "SELL", 1000, "STP", 26, 26, "GTC", True, 100, "", 0, "MYGROUP" );

OCAType - optional numeric parameter (new in 1.1.0) that allows to control the way OCAGroup orders are handled when one order in the group is partially filled.
Possible values are: 
1 = CANCEL_WITH_BLOCK - other orders are cancelled 
2 = REDUCE_WITH_BLOCK - other orders are reduced in size and overfill protection is ON
3 = REDUCE_NON_BLOCK - other orders are reduced in size and overfill protection is OFF

Default value is 3

FAParams - optional string parameter (new in 1.1.0) - for use with FA (Financial Advisor aka Family&Friends) accounts.
Allows to specify FA account allocation group, profile, method and percentage. These four parameters should be provided as semicolon separated string:
"FAGroup;FAProfile;FAMethod;FAPercentage".
If some parameter is not necessary it may be left empty but you need to keep semicolons if there are any further parameters required. For example to specify order that uses "All" group and uses "EqualQuantity" method the FAParameter should look like this:
"All;;EqualQuantity":

ibc.PlaceOrder("MSFT", "BUY", 1000, "LMT", 27, 0, "GTC", True, 100, "", 0, "", 0, "All;;EqualQuantity" ); 

If you want to use custom allocation profile you can use:


ibc.PlaceOrder("MSFT", "BUY", 1000, "LMT", 27, 0, "GTC", True, 100, "", 0, "", 0, "All;MyCustomProfile" );

If FAParams is not provided and you are using FA account than IBc will use default allocation of "All;;AvailableEquity"

Note that by default IB Controller logs into "All" account which is "aggregate", i.e. holds the sum of all positions on all sub-accounts.

ModifyOrder( string OrderId, string Ticker, string Action, number Quantity, string Type, number LimitPrice, number StopPrice, string TimeInForce, bool Transmit, [optional] number TickSize = 100, [optional] string Attributes = "", [optional] string ParentID = "" , [optional] string OCAGroup, [optional] number OCAType, [optional] string FAParam)

This function modifies the order that was placed before but not yet filled. This function can be used also to modify orders that were sent with "Transmit" flag set to False. Also when OrderID parameter is empty this function works exactly like PlaceOrder (so you can place and modify orders using ModifyOrder() function alone)

Return value: 

The function returns the OrderId (string) that can be later used to modify/cancel/query status of the order 

Parameters: 
OrderId - string specifying the orderID to be modified (returned by earlier PlaceOrder or ModifyOrder call). If this parameter is empty then the function places a new order 
all remaining parameters are the same as in PlaceOrder function

In version 1.1.0 one improvement was added to the ModifyOrder function that if some of optional parameters like ParentID, OCAGroup, OCAType, FAParam are not specified - then it uses previously provided values (during PlaceOrder). This prevents from for example losing ParentID when calling ModifyOrder on a child order without currect parentID.


CancelOrder( string OrderId )

This function cancels pending order. 

Return value:

True - if pending order was found and cancel request has been sent, False - if there is no pending order with specified OrderId

Parameters: 
OrderId - string specifying the orderID to be modified (returned by earlier PlaceOrder or ModifyOrder call).

GetAccountValue( string FieldName )

(new in 1.0.2)

This function retrieves account values. 

Return value: 

String representing the value. Note that if you need number in AFL you should use StrToNum conversion function that will convert string returned by this function to the number.

Empty string is returned if field does not exist or is empty.

Parameters: 
FieldName - defines the value to query 


List of available fields (case sensitive):

1. The fields that are either currency-independent or expressed in BASE account currency (usually totals):

AccountCode
AccountReady
AccountType
AccruedCash
CashBalance 
Currency
DayTradesRemaining
DayTradesRemainingT+1
DayTradesRemainingT+2
DayTradesRemainingT+3
DayTradesRemainingT+4
ExchangeRate
FuturesPNL
Leverage-S
LookAheadNextChange
NetLiquidationByCurrency
OptionMarketValue
PNL
RealizedPnL
StockMarketValue
TotalCashBalance
UnrealizedPnL

2. Fields that are provided separately for EACH currency held on the account, [CUR] in the list below means currency symbol, so for USD denominated funds and securities you will see [USD] prefix. Note IDEALPRO spot Forex positions are included in [CUR]CashBalance here.

[CUR]AccruedCash
[CUR]AccruedCash-C
[CUR]AccruedCash-S
[CUR]AvailableFunds
[CUR]AvailableFunds-C
[CUR]AvailableFunds-S
[CUR]BuyingPower
[CUR]CashBalance 
[CUR]Currency
[CUR]EquityWithLoanValue
[CUR]EquityWithLoanValue-C
[CUR]EquityWithLoanValue-S
[CUR]ExcessLiquidity
[CUR]ExcessLiquidity-C
[CUR]ExcessLiquidity-S
[CUR]FullAvailableFunds
[CUR]FullAvailableFunds-C
[CUR]FullAvailableFunds-S
[CUR]FullExcessLiquidity
[CUR]FullExcessLiquidity-C
[CUR]FullExcessLiquidity-S
[CUR]FullInitMarginReq
[CUR]FullInitMarginReq-C
[CUR]FullInitMarginReq-S
[CUR]FullMaintMarginReq
[CUR]FullMaintMarginReq-C
[CUR]FullMaintMarginReq-S
[CUR]FutureOptionValue
[CUR]FuturesPNL
[CUR]GrossPositionValue
[CUR]GrossPositionValue-S
[CUR]InitMarginReq
[CUR]InitMarginReq-C
[CUR]InitMarginReq-S
[CUR]Leverage-S
[CUR]LookAheadAvailableFunds
[CUR]LookAheadAvailableFunds-C
[CUR]LookAheadAvailableFunds-S
[CUR]LookAheadExcessLiquidity
[CUR]LookAheadExcessLiquidity-C
[CUR]LookAheadExcessLiquidity-S
[CUR]LookAheadInitMarginReq
[CUR]LookAheadInitMarginReq-C
[CUR]LookAheadInitMarginReq-S
[CUR]LookAheadMaintMarginReq
[CUR]LookAheadMaintMarginReq-C
[CUR]LookAheadMaintMarginReq-S
[CUR]LookAheadNextChange
[CUR]MaintMarginReq
[CUR]MaintMarginReq-C
[CUR]MaintMarginReq-S
[CUR]NetLiquidation
[CUR]NetLiquidationByCurrency
[CUR]NetLiquidation-C
[CUR]NetLiquidation-S
[CUR]PreviousDayEquityWithLoanValue
[CUR]PreviousDayEquityWithLoanValue-S 
[CUR]OptionMarketValue
[CUR]OptionMarketValue
[CUR]RealizedPnL
[CUR]SMA
[CUR]SMA-S
[CUR]StockMarketValue
[CUR]TotalCashBalance
[CUR]TotalCashValue
[CUR]TotalCashValue-C
[CUR]TotalCashValue-S
[CUR]UnalteredInitMarginReq
[CUR]UnalteredMaintMarginReq
[CUR]UnrealizedPnL

When currency is NOT specified IBc first looks for values specified in BASE currency and if not found then uses USD as default,
so you can use old-style GetAccountValue("AvailableFunds") and it will return the same as GetAccountValue("[USD]AvailableFunds")
- because there available funds are not specified in base currency. 

If you however call GetAccountValue("TotalCashBalance") it will report in BASE currency and it may be different from GetAccountValue("[USD]TotalCashBalance") which will represent USD cash only. Differences will occur if you have cash positions in many currencies so "base" currency shows gross total of all positions in all currencies as if they were exchanged into base currency

GetExecInfo( string OrderId, , string Field)

(new in 1.3.0) 


This function retrieves the value of the Field of OrderId order from the execution list 

Return value:

the numeric or sting value of the requested Field for OrderId. Null if no field or no such position available

Parameters: 
OrderId - string that specifies the order (returned by PlaceOrder function 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, "Filled" 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 );



GetLastError( string OrderId ) 

(new in 1.0.2)

This function returns the text of last error message

Return value:

string representing the error message. Empty in case when there was no error message or there is no such order

Parameters:

OrderId - specifies the order id to query last error information from. There is a special value that you can pass: 0 (zero) and it has a special meaning: it retrieves last error message for ANY order. This is exactly this message that appears on the top of the error list in IBController user interface.

GetStatus( string OrderId, [optional] boolean InclFilled )

This function retrieves status of pending order. 

Return value:

string that describes the status, it can be:
"NotYetTransmitted", "PreSubmitted", "Pending", "Cancelled","Submitted", "Filled", "Error" (new in 1.0.2), "Inactive" or empty when matching order was not found
Depending on InclFilled field some statuses are intermittient.
If InclFilled is not specified or equal to false (zero) then only "NotYetTransmitted", "Pending", "PreSubmitted", "Submitted" statuses are reported consistently. "Cancelled" and "Filled" statuses are intermittient because such orders are removed from pending orders list within one second from cancelling/filling the order (this will change in the future). "Error" status means that there was an error during processing last request to place/modify an order and you can query detailed error information using GetLastError function.
If InclFilled is set to True then also statuses of orders listed on "Executions" list are reported and this means that you can get "Cancelled", "Filled", "Error", "Inactive" consistently.

Note: InclFilled parameter has been introduced in 1.0.8.

Parameters: 
OrderId - string specifying the orderID to be modified (returned by earlier PlaceOrder or ModifyOrder call). 


GetPositionInfo( string Ticker, string Field)

(new in 1.0.3)

This function retrieves the value of the Field of Ticker symbol held currently in the portfolio

IMPORTANT CHANGE in 1.1.0 : the function does NOT report positions with zero sizes anymore

Return value:

the numeric value of the requested Field for Ticker. Null if no field or no such position available

Parameters: 
Ticker - string that specifies the symbol of security/contract. The symbol should follow the symbology defined in detail at: http://www.amibroker.com/ib.html 
Field - one of column names found in "Portfolio" page of IB Controller. For example "Avg. cost" gives average cost of purchase of given security, "Unrealized PNL" gives unrealized profit and loss.


GetPositionSize( string Ticker )

This function retrieves the number of shares/contracts of Ticker symbol held currently in the portfolio

Return value:

the number that descibes the currently held position size for Ticker. Positive numbers mean long position, negative numbers mean short position, zero means that given ticker is not held in the portfolio

Parameters: 
Ticker - string that specifies the symbol of security/contract. The symbol should follow the symbology defined in detail at: http://www.amibroker.com/ib.html 


IsConnected()

This function retrieves the connection status to TWS.

Return value:

0 - NO connection
1 - connection in progress
2 - means connection OK, no messages
3 - connection OK, but TWS generated some warning/error messages (see "Messages tab)

IsOrderPending( string OrderId )

This function checks if given order is pending (or not yet transmitted). 

Return value:

True - if order is still in the pending list, False if order was Filled, cancelled or there is no such order at all

Parameters: 
OrderId - string specifying the orderID to be modified (returned by earlier PlaceOrder or ModifyOrder call). 


GetPositionList()
(new in 1.0.8)

Returns comma-separated symbol list of currently open positions.

IMPORTANT CHANGE in 1.1.0 : the function does NOT report positions with zero sizes anymore 

Example: 

list of open positions and their sizes 
ibc = GetTradingInterface("IB"); 

openpos = ibc.GetPositionList(); 

for( i = 0; ( symbol = StrExtract( openpos, i ) ) != ""; i++ ) 
{ 
  printf("Position " + i + "\tSymbol: " + symbol + "\tSize: " + ibc.GetPositionSize( symbol ) + "\n" ); 
}

GetPendingList( number Type, string Filter )
(new in 1.0.8)

Returns comma separated list of orders from pending list

Parameters:
Type - specifies what should be returned 0 - gives ORDERIDs, 1 gives symbol lists
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, "Pending" );
- returns comma separated list of pending order IDs

symbols = ibc.GetPendingList( 1, "Pending" );
- returns comma separated list of SYMBOLS that have pending orders

symbols = ibc.GetPendingList( 0, "Error" );
- returns list of orderids that have errors

symbols = ibc.GetPendingList( 0, "Cancelled" );
- returns cancelled orderids (please keep in mind that cancelled order are automatically removed from
the list after few seconds)

symbols = ibc.GetPendingList( 0, "" );
- returns list of all orderIDs present in the "pending list" (may be pending/error/cancelled/partially filled/submitted, etc)

To extract symbols from the list use this kind of loop:
for( i = 0; ( symbol = StrExtract( symbols, i ) ) != ""; i++ ) 
{ 
  printf("Symbol: " + symbol + "\n" ); 
} 

CloseAllOpenPositions( [optional] string Ticker )
(new in 1.0.8)

Sends orders to close all currently open positions.

sends MARKET SELL/BUY order for each and every LONG/SHORT position in the portfolio page - should effectively close all open positions (provided that closing orders will fill correctly), note however that it may happen that these closing orders may fail (for example when markets are closed)

New in 1.1.0: now function accepts optional parameter. When it is provided, the function closes positions only on specified ticker. If it is not specified - it operates as previously (closes positions on all symbols). 

CancelAllPendingOrders( [optional] string Ticker )
(new in 1.0.8)

Cancels all pending orders

Sends cancel for each and every order displayed in the Pending orders page (with the exception of orders with Errors)

New in 1.1.0: now function accepts optional parameter. When it is provided, the function cancels orders only of specified ticker. If it is not specified - it operates as previously (cancels all pending orders on all symbols).

Transmit( string OrderID )
(new in 1.0.8)

Modifies transmit flag on NotYetTransmitted order

Paramters:
OrderID - string specifying the orderid returned by PlaceOrder 

Returns non-zero (true) when orderid has been found on the pending order list and zero otherwise. It does not necesarily mean that transmit was successful. 
Transmit( orderid) is used to transmit orders previously placed with transmit flag set to false. 
Transmit internally is handled by calling "modify order" function (so you don't need to specify the same parameters again) but note that TWS has problems with handling modify requests coming too quickly, so you will NOT be able to call modify/transmit immediatelly after placing order with transmit = false.
In such cases we recommend using manual trigger that is slow enough not to cause problems.

Example:
ibc.Transmit( orderid );


Sleep( number Milliseconds )
(new in 1.0.8)

This is EXPERIMENTAL function.

Suspends the execution for specified number of milliseconds.

Please do NOT use this function unless you really have to, because it locks both IBController and AmiBroker for specified period of time and both applications won't respond to user actions (such as mouse/keyboard input). If you suspend execution for more than few seconds AmiBroker will complain about OLE server not responding. 
Example:
ibc.Sleep( 1000 ); // sleep for 1000 milliseconds = 1 second

ClearList( number ListNo )
(new in 1.1.0)

Clears specified display list.

where ListNo can be:
0 - pending order list
1 - execution list
2 - portfolio list
3 - account information list
4 - error message list 
ibc.ClearList( 4 ); // clears error message list 

Note that this function only affects the display, it does NOT affect the status of orders. So if you have any active orders the "pending orders", "executions" lists will be re-filled with currently active orders during next status update (usually within fraction of second - so it may not be visually noticeable) It also applies for portfolio and account information lists - they will be re-filled with next account update - usually within few seconds.


SetAccount( string Account )
(new in 1.1.0)

ONLY FOR FA (financial advisor) accounts.

Sets active account. Note that IB uses "A" subscript to designate "All" account that is aggregate of all subaccounts. So if your FA account has a number of F1234, you need to add "A" suffix to it to get aggregate data:

ibc.SetAccount("F1234A");

Note also that by default IB controller detects that you have FA account and selects "All" account by default if you connect to TWS running FA account.

Note also that "All" account allows to direct orders to specified subaccounts without changing active account. To do this it is enough to call PlaceOrder with correct allocation profile specified in FAParams argument.


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 terminating and re-running IB Controller. 
Examples:

1. Placing and transmitting Market Buy Order for 100 shares when MACD crosses above 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 transmitting 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.


Buy = L > Ref( H, -1 ); // buy when prices gap up 

if( LastValue( Buy ) ) 
{ 
   ibc = GetTradingInterface("IB"); 

   // check if we are connected OK 
   if( ibc.IsConnected() ) 
    { 
       // place orders only if we do not have already open position on this symbol 
      if( ibc.GetPositionSize( Name() ) == 0 ) 
       { 
         // retrieve orderID from previous run, will be empty if no order was placed before   
          OrderID = StaticVarGetText("OrderID"+Name()); 
       
          // place or modify the order - don't transmit yet 
          OrderID = ibc.ModifyOrder( OrderID, Name(), "BUY", 100, 
                                 "LMT", LastValue( C ) + 0.10, 0, "Day", False ); 

         // store orderID for next run so we know which order to modify 
         StaticVarSetText("OrderID"+Name(), OrderID); 
       } 
    } 
} 


3. Placing/modifying manually from Parameters dialog. Code to be applied in Indicator Builder. (Modified to use new features in 1.0.2)

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.

// Param block 
TriggerOrder= ParamTrigger("Place order","Click here to place order"); 
Mode=ParamToggle("Mode","Modify existing|Always place new order"); 
ACT = ParamList("Action", "BUY|SELL|SSHORT"); 
OT = ParamList("Order Type", "MKT|LMT|STP"); 
TIF = ParamList("Time In Force", "DAY|GTC|IOC"); 
Ticker = ParamStr("Ticker",Name()); 
NumShares = Param("Number of Shares",10,10,100,10); 
LimitPrice = LastValue(C) + Param("Limit Price offset",0,-0.1,0.1,0.01); 
StopPrice = LastValue(C) + Param("Stop price offset",0,-0.1,0.1,0.01); 
Transmit = ParamToggle("Transmit","Do NOT transmit|Transmit",0); 
TriggerCancel = ParamTrigger("Cancel Order","Click here to Cancel order"); 

Msg = ""; // this variable stores error message text 

// create instance of trading interface 
ibc = GetTradingInterface("IB"); 

// retrieve orderID from previous run, will be empty if no order was placed before 
OrderID = StaticVarGetText("OrderID"+Ticker); 

if( TriggerOrder ) 
{ 
// check if we are connected OK 
if( ibc.IsConnected() ) 
{ 
   if( Mode == 1 ) OrderID = ""; // if mode set to 'always new' then clear orderid 

   // place orders only if we do not have already open position on this symbol 
   // place or modify the order - don't transmit yet 
   OrderID = ibc.ModifyOrder( OrderID, Ticker, 
         ACT, NumShares, OT, LimitPrice, StopPrice, TIF, Transmit); 
   

   // store orderID for next run so we know which order to modify 

   StaticVarSetText("OrderID"+Ticker, OrderID); 
   
   if( Mode == 1 ) 
       Msg = "New order has been placed with ID = "; 
   else 
       Msg = "Order placed/modified with ID = "; 

   Msg = Msg + OrderID + " on " + Now(); 
} 
else 
{ 
   Msg = "Placing order failed because of no connection to TWS"; 
} 
} 

if( TriggerCancel ) 
{ 
  if( OrderId != "" ) 
   { 
    if( ibc.CancelOrder( OrderId ) ) 
       Msg = "Request to cancel order " + OrderID + " sent successfully"; 
    else 
       Msg = "Request to cancel order " + OrderID + " failed."; 
   } 
  else 
     Msg = "Can not cancel order becase OrderID is empty"; 

} 

execlist = ibc.GetExecList(0,""); // all 

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"; 

} 



// 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, "", parentID ); 
ibc.PlaceOrder("MSFT", "SELL", 1000, "STP", 26, 26, "GTC", True, 100, "", parentID );

Note that TRANSMIT flag is set to FALSE on all bracket orders except the last one. This ensures that orders wait until bracket order set is completed. Setting Transmit 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.GetPositionSize( symbol ) + "\n" ); 
}

6. Placing OCA group orders:

ibc.PlaceOrder("MSFT", "SELL", 1000, "LMT", 28, 0, "GTC", True, 100, "", 0, "MYGROUP" ); 
ibc.PlaceOrder("MSFT", "SELL", 1000, "STP", 26, 26, "GTC", True, 100, "", 0, "MYGROUP" );

FAQ

1) What exactly is the OrderID, where is the number stored? How does it increment? 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 order. The implementation takes care that generated ID is unique for given session of TWS. You should NOT assign your own IDs because you may risk generating duplicates that will be rejected by TWS.


2) The IB Interface contains a lot of useful information, can we access this information in afl?

GetAccountValue() function (introduced in 1.0.2) allows that.

3) IMPORTANT. During development i often "lose" my connection to the TWS and cannot 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 able handle them and sends error messages ("Unable to modify this order as its still 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 Controller window.

4) Is it possible to read IB Last/Bif/Ask prices while running a eSignal database?

Right now there is no access to price data via IBController but maybe in the future

5) 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. 

5) Can we retrieve the "Executions" and "Pending" page (string) from the IB Controller 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.

6) 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 indicator then it may be auto-refreshed at AB start and in this individual case you would need to run TWS before AB. Anyway if something fails you can simply close IB controller window and it will re-open automatically and reconnect on next call to GetTradingInterface.

7) 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 next call to GetTradingInterface.

8) 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 intended to be used in AA window. But if you prefer to run it in IB you can do this too, but then you should check pending orders and check portfolio position size 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 updating the values of already exisiting, pending order if you specify correct OrderID of order placed before (see the example 2.)

9) A "clear" Message button would be nice in the IBc window, i have to scroll down continuously to see the latest message (perhaps last-on-top scrolling?)

It is already available in version 1.0.2

10) What is the best way to write a single-(user initiated)-execution line of code? ... 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 Parameter dialog that can be pressed.
Normally ParamTrigger will return zero (0) but when button in the param window is pressed then it will refresh the chart and ParamTrigger will return 1 (one) for 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 
} 



11) When placing orders from an indicator (the thing to do in RT trading) and editing the code will result in additional afl executions, how can i prevent randon order placement from the extra passes? Parameters and Signals may not be the same as a result of using loops, DLLs, and things.

Use static variables as given in example 2 to MODIFY existing order instead of placing many new orders. Or use code given in response to question 10

12) 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 list to enter codes in comma separated list). Any code entered here will be ignored by Pending List page, but still will be displayed in the messages window.

13) 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.0

added GetExecList and GetExecInfo functions. 

CHANGES FOR VERSION 1.2.1

The IBc now accepts new symbology convention with 4th part defining currency: SYMBOL-EXCHANGE-TYPE-CURRENCY. When currency is not specified USD is used as default. For more info see http://www.amibroker.com/ib.html 
The IBc also accepts single letter type codes 
CHANGES FOR VERSION 1.2.0

IBc now allows to define which error codes should be ignored using File->Error code ignore list 
upgraded to use latest TWS API 9.41 (tested with latest TWS 885.7, requires at least 879) 
following TWS API changes ignoreRth and rthOnly flags are removed and replaced with single flag: outsideRTH
Quote from TWS DOC http://www.interactivebrokers.com/en/software/apiReleaseNotes/api94.php?ib_entity=llc 
"OutsideRTH Flag Replaces "Ignore Regular Trading Hours" and "Regular Trading Hours Only" Flags
Supported in: All API Platforms 

A new, single order atttibute, bool OutsideRTH(), replaces two flags: ignoreRTH and rthOnly in the Order class/struct. If set to true, this new extended order attribute allows orders to trigger or fill outside of regular trading hours. 
"



CHANGES FOR VERSION 1.1.1

primaryExchange is now set to empty. This solves "invalid symbol" problem occuring for some accounts during last 2 weeks following apparent changes in IB. 
CHANGES FOR VERSION 1.1.0

Added handling of error codes 2100, 1100, 1101, 1102, 1300 


Financial advisor Account support (FC Issue #69) :
Added FA-only fields to PlaceOrder/ModifyOrder 
When run on FA account IBc automatically queries for account list and uses "All" account by default 


GetAccountValue now allows to query values separately for each currency.
Currency specific values are available using this syntax:
[CUR]FieldName
where CUR is currency symbol for example:
[USD]AvailableFunds
[EUR]AvailableFunds

When currency is NOT specified IBc first looks for values specified in BASE currency and if not found then uses USD as default,
so you can use old-style GetAccountValue("AvailableFunds") and it will return the same as GetAccountValue("[USD]AvailableFunds")
- because there available funds are not specified in base currency. 

If you however call GetAccountValue("TotalCashBalance") it will report in BASE currency and it may be different from GetAccountValue("[USD]TotalCashBalance") which will represent USD cash only. Differences will occur if you have cash positions in many currencies so "base" currency shows gross total of all positions in all currencies as if they were exchanged into base currency.


added limit of error messages to be displayed (File->Configure) 


added re-querying for positions after reconnect 


an option to restart/reconnect (File->Reconnect), new method Reconnect() 


CancelAllPendingOrders( [optional] Ticker )
now CancelAllPendingOrders method takes optional parameter Ticker.
If it is specified - it cancels orders only for specified symbol.
If it is NOT specified - it cancels all orders for ALL symbols.


ClearList( iListNo ) method added
ClearList( ListNo )
where ListNo can be:
0 - pending order list
1 - execution list
2 - portfolio list
3 - account information list
4 - error message list

ibc.ClearList( 4 ); // clears error message list 

Note that this function only affects the display, it does NOT affect the status of orders. So if you have any active orders the "pending orders", "executions" lists will be re-filled with currently active orders during next status update (usually within fraction of second - so it may not be visually noticeable) It also applies for portfolio and account information lists - they will be re-filled with next account update - usually within few seconds.


CloseAllOpenPositions( [optional] Ticker )
now CloseAllOpenPosition method takes optional parameter Ticker.
If it is specified - it closes positions only for specified symbol.
If it is NOT specified - it closes all positions.


exchange is reported correctly for non-US stocks in Portfolio page


GetPositionList() - returns only symbols with positions <> 0


OCA groups support added to PlaceOrder/ModifyOrder 


user-definable port and IP number (File->Configure) 


SetAccount( AccNo ) - for FA accounts 


Warning 2107 (Historical Market Data Service inactive) and 2104 (market data OK) is silently ignored now 


CHANGES FOR VERSION 1.0.8

GetStatus() function now has optional parameter InclFilled
GetStatus( string OrderId, [optional] boolean InclFilled )

when InclFilled is provided and set to true GetStatus function provides statuses for filled, cancelled and error orders that may have been already deleted from pending list.


TimeInForce field in PlaceOrder/ModifyOrder allows now to specify "Good Till Date" and "Good After Time" date/times)

TimeInForce field in PlaceOrder/ModifyOrder accepts GTD and GAT specifications

GTD - Good Till Date - indicates that the order should remain workign untilthe 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 extraGoodAfterTime (GAT) part. GAT part comes AFTER semicolon. It indicates thattrade should be submitted after the time and date set:

GAT specifications:
DAY;GAT YYYYMMDD HH:MM:SS TZONE - day order valid after specified date/time
GTC;GAT YYYYMMDD HH:MM:SS TZONE - good till canceled order valid after specified time
GTD yyyymmdd hh:mm:ss tzone;GAT YYYYYMMDD HH:MM:SS TZONE - GTD order valid 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


Portfolio page should now display correct exchange for futures (now it uses reqContractDetails to query for exchange string that is not sent via accountUpdates by TWS)

new Transmit( orderID ) method
Transmit( string orderid )- returns non-zero (true) when orderid has been found on the pending order listand zero otherwise. It does not necesarily mean that transmit was successful.

Transmit( orderid) is used to transmit orders previously placed with transmit flag set to false. Transmit internally is handled by calling "modify order" function (so you don't need to specify the same parameters again) but note that TWS has problems with handling modify requests coming too quickly, so you will NOT be able to call modify/transmit immediatelly after placing order with transmit = false.In such cases we recommend using manual trigger that is slow enough not to cause problems.


GetPositionList() method added - returns comma separated list of currently open positions

Example: 

list of open positions and their sizes

ibc = GetTradingInterface("IB"); 

openpos = ibc.GetPositionList(); 

for( i = 0; ( symbol = StrExtract( openpos, i ) ) != ""; i++ ) 
{ 
  printf("Position " + i + "\tSymbol: " + symbol + "\tSize: " + ibc.GetPositionSize( symbol ) + "\n" ); 
} 


GetPendingList( Type, Filter ) - retrieves comma-separated list of orders from pending list

where:
Type - specifies what should be returned 0 - gives ORDERIDs, 1 gives symbol lists
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.

For example:

symbols = ibc.GetPendingList( 0, "Pending" );
- returns comma separated list of pending order IDs

symbols = ibc.GetPendingList( 1, "Pending" );
- returns comma separated list of SYMBOLS that have pending orders

symbols = ibc.GetPendingList( 0, "Error" );
- returns list of orderids that have errors

symbols = ibc.GetPendingList( 0, "Cancelled" );
- returns cancelled orderids (please keep in mind that cancelled order are automatically removed from
the list after few seconds)

symbols = ibc.GetPendingList( 0, "" );
- returns list of all orderIDs present in the "pending list" (may be pending/error/cancelled/partially filled/submitted, etc)


added experimental Sleep() method

Sleep( [number] Milliseconds )

- suspends the execution for specified number of milliseconds.Please do NOT use this function unless you really have to, because it locksboth IBController and AmiBroker for specified period of time and both applicationswon't respond to user actions (such as mouse/keyboard input). If you suspendexecution for more than few seconds AmiBroker will complain about OLE server not responding.


added CloseAllOpenPositons(), CancelAllPendingOrders methods and Panic button

CloseAllOpenPositions() method - sends MARKET SELL/BUY order for each and every LONG/SHORT position in the portfolio page - should effectively close all open positions (provided that closing orders will fill correctly), note however that it may happen that these closing orders may fail (for example when markets are closed)

CancelAllPendingOrders - sends cancel for each and every order displayed in the Pending orders page (with the exception of orders with Errors)

Panic button in the toolbar - sends CancelAllPendingOrders() and then CloseAllOpenPositions()

Bracket orders support. PlaceOrder and ModifyOrder methods have two additional optional parameters: Attributes and ParentID

PlaceOrder( string Ticker, string Action, number Quantity, string Type, number LimitPrice, number StopPrice, string TimeInForce, bool Transmit, [optional] number TickSize = 100, [optional] string Attributes = "", [optional] string ParentID = "" 

Attributes - is a string that allows to specify additional order attributes (comma separated list).

Supported attributes:
rthOnly - (OBSOLETE NOW in 1.2.0) if specified means that the order will only be _filled_ during RTH; this applies to any order type including limit. 
ignoreRth - (OBSOLETE NOW in 1.2.0) if specified means that order will trigger not only during Regular Trading Hours (RTH), but also in extended trading (pre/after market); this applies to stop orders, conditional orders, and alerts; it is used by the triggering 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

By default all those flags are INACTIVE (OFF)

Example:
ibc.PlaceOrder("MSFT", "BUY", 1000, "LMT", 27, 0, "GTD 20051215 19:00:00 GMT", True, 100, "allOrNone" ); 


(Note that optional parameter TickSize MUST be specified if you want to use Attributes)

ParentID - is a string that specifies parent order identifier (returned by previous PlaceOrder call)
allowing you to place BRACKET orders. 
Example:

parentID = ibc.PlaceOrder("MSFT", "BUY", 1000, "LMT", 27, 0, "GTC", False ); 
ibc.PlaceOrder("MSFT", "SELL", 1000, "LMT", 28, 0, "GTC", False, 100, "", parentID ); 
ibc.PlaceOrder("MSFT", "SELL", 1000, "STP", 0, 26, "GTC", True, 100, "", parentID );


CHANGES FOR VERSION 1.0.7

now IBController does not require API installation 
CHANGES FOR VERSION 1.0.6

re-compiled with TWS API 8.41 BETA 
CHANGES FOR VERSION 1.0.5

fixed problem with GetPositionSize() reporting zero for SMART routed symbols in 1.0.4 
CHANGES FOR VERSION 1.0.4

fixed symbology used in Order, Status and Porfolio pages so now futures and currencies work nicely 
added optional TickSize parameter that defines minimum price fluctuation allowed for given symbol (expressed in pips, i.e. 0.0001). For stocks usually 100 (i.e. 0.01), for Forex: 1. 
automatic reconnect implemented - IBc now attempts to reconnect to IB every 5 seconds when case connection is lost or IB has crashed and was restarted 
Now works with "Fire OpenOrder on status change" setting turned off as well as turned on. 
Order once marked with "Error" status keeps last error message 
CHANGES FOR VERSION 1.0.3

compiled with TWS API 8.30 
added GetPositionInfo method 
added unlock code dialog (File->Enter Unlock code). IBController by default does not transmit orders automatically. Transmission can be enabled by entering unlock code that is made available to the user after accepting the agreement. 
CHANGES FOR VERSION 1.0.2 

IBC: Now pending order list features new status code "error" and new column: Last error 
IBC: New toolbar button: auto-cancel orders with errors - when turned on, all orders with errors are cancelled automatically 
IBC: Error messages now show order id and error code 
IBC: Repeating messages are now displayed once with appropriate repeat count and last update time 
IBC: Most recent error messages now appear on the top of the "message" list, so you don't need to scroll 
IBC: "Duplicate order ID" problem solved
[Now when TWS sends "duplicate order" message, appropriate order line is marked in IB Controlled as "error" and such order ID is no longer used. When new ModifyOrder is placed then new order id will be assigned] 
IBC: GetAccountValue function in IB interface

CHANGES FOR VERSION 1.0.1

CancelOrder() removes "NotYetTransmitted" orders from the pending list 
IsConnected() funcition now returns integer values 0..3 (not bool) 
'Clear Messages' toolbar button added 
CHANGES FOR VERSION 1.0.0 

first beta release 
HOW TO REPORT BUGS

If you experience any problem with this beta version please send detailed description of the problem (especially the steps needed to reproduce it) to bugs at amibroker.com
