The IB Controller is an interface designed to facilitate automatic trading with AmiBroker and Interactive Brokers (IB) TWS (Trader Workstation). It serves as a bridge between AmiBroker, a technical analysis and charting software, and IB’s TWS, allowing users to send orders from AmiBroker to TWS based on trading strategies developed within AmiBroker
Smart Order Module brings a 100% end-to-end automated trading solution for Amibroker users to automate their trading ideas with a simple plug-and-play module. Traders have to connect their trading system along with smart order execution to make their system trading life easier.
Supported Broker
Interactive Brokers (US Market, International and Indian Markets)

As of June 3, 2013, the auto-trading interface IBController became open-source, allowing for community contributions and enhancements.

Enable ActiveX and Socket Clients turned ON in TWS (Configure->API menu in TWS)

Ensure Same Socket Port is used in IB Controller also

Get the IB Controller Unlock Code
In order to use the IB controller you have to accept the terms and agreement of Amibroker and Get the Unlock Code to start using the IB Controller. Once you got the Unlock Code key in the values in the IB Controller to start your automated trading.

How to use the smart order module?
1)Apply your trading system on a new blank chart
2)Save the Smart Order Module to any folder of your choice
3)drag and drop the Smart order Module on top of the trading system
4)Configure Smart order Module parameters
5)Enable the Algo Mode and Start 100% Smart Automation.
Interactive Brokers Order Controls

Parameter | Description |
---|---|
Trading Symbol | Interactive Broker Trading Symbol |
Order Types | Defines the order types to be used when placing trades through Interactive Brokers, e.g., Market Orders (MKT) or Limit Orders (LMT). |
Quantity | Specifies the quantity of shares or contracts to trade |
Time in Force | Determines how long an order remains active before it is canceled, e.g., DAY or GTC (Good Till Canceled). |
Transmit | Controls whether the order is immediately transmitted to the exchange or requires manual confirmation. AUTO – Fully Automated Mode, SEMIAUTO – Semi Auto Mode |
Button Trading Module | Provides functionality for manual order placement through the user interface with buttons for Buy, Sell, Exit Buy, and Exit Sell actions. BE– Buy Entry, BX – Buy Exit, SE – Short Entry, SX – Short Exit |
Algo Status | Allows enabling or disabling the algorithm, as well as setting it to only allow long or short positions. |
Voice Alerts | Enables voice alerts for order placements. |
Entry Delay | 0 – No Delay , 1 – Candle Completion |
Exit Delay | 0 – No Delay , 1 – Candle Completion |
Follow the thread in order to get the Trading Symbol for Interactive Brokers.
Smart Chart Order Module Logic
PlaceOrder Logic
Step | Condition | Action | Description |
---|---|---|---|
1 | Check Connection to IB | Proceed if connected; Otherwise, halt. | Ensures that there’s a live connection to Interactive Brokers (IB) before attempting to place any orders. |
2 | Determine Open Position Size | Retrieve the current position size for the specified trading symbol. | Identifies whether there is an existing position for the symbol in question and the size of that position. |
3 | No Open Position | Place a new order with specified parameters (action, orderqty, ordertype, etc.). | If there’s no open position, the script proceeds to place a new order based on the strategy’s current trade signal. |
4 | Open Position Found & Opposite Action Required | If an opposite action is needed (e.g., existing short position but buy signal generated), place an order to reverse the position by ordering double the quantity to close and open new. | Aims to reverse an existing position based on the new signal by closing the current position and simultaneously opening a new position. |
5 | Open Position Matches Action | Log message indicating no action taken due to existing position matching the intended action. | Prevents adding to an existing position (no pyramiding) by skipping the order if the current signal matches the existing position. |
ExitOrder Logic
Step | Condition | Action | Description |
---|---|---|---|
1 | Check Connection to IB | Proceed if connected; Otherwise, halt. | Ensures that there’s a live connection to Interactive Brokers (IB) before attempting to execute any exit orders. |
2 | Determine Open Position Size | Retrieve the current position size for the specified trading symbol. | Identifies whether there is an existing open position for the symbol in question and the size of that position. |
3 | No Open Position Found | Log message indicating no open position found, hence no exit action taken. | If there’s no open position, no exit order is placed, and the script logs a message indicating such. |
4 | Open Position Found & Exit Action Matches Required Direction | Place an order to exit the position with the specified parameters (action, orderqty, ordertype, etc.). | Executes an exit order for the existing position based on the strategy’s exit signal, effectively closing the position. |
5 | Voice Alert Enabled & Open Position Existed | Voice alert stating “Exit Order Placed” if a position was found and an exit order was successfully placed. | Optionally provides a voice alert for the trader to indicate that an exit order has been placed, assuming the feature is enabled. |
IBKR Smartorder Chart Module – Amibroker AFL Code
Attach the following code to your strategy to convert your Amibroker Strategy completely automated.
_SECTION_BEGIN("IBKR - Order Controls");
RequestTimedRefresh(1, False);
strategy = ParamStr("Strategy Name", "Amiboker Strategy");
symbol = ParamStr("Trading Symbol","ESM4-CME-FUT");
ordertype = ParamList("OrderType","MKT|LMT",0);
quantity = Param("Quantity",1,1,100000,1);
LimitPrice = 0;
StopPrice =0;
TimeInForce = ParamList("Time in force","DAY|GTC|IOC|GTD",1);
Transmit = ParamList("Transmit","AUTO|SEMIAUTO",0);
if(Transmit=="AUTO")
{
Transmit = True;
}
else if(Transmit=="SEMIAUTO")
{
Transmit = False;
}
Entrydelay = Param("Entry Delay",0,0,1,1);
Exitdelay = Param("Exit Delay",0,0,1,1);
EnableButton = ParamList("Button Trading","Disable|Enable",0);
VoiceAlert = ParamList("Voice Alert","Disable|Enable",1);
EnableAlgo = ParamList("AlgoStatus","Disable|Enable|LongOnly|ShortOnly",0);
resp = "";
//Static Variables for Order protection
static_name_ = Name()+GetChartID()+interval(2)+strategy;
static_name_algo = Name()+GetChartID()+interval(2)+strategy+"algostatus";
AlgoBuy = lastvalue(Ref(Buy,-Entrydelay));
AlgoSell = lastvalue(Ref(Sell,-Exitdelay));
AlgoShort = lastvalue(Ref(Short,-Entrydelay));
AlgoCover = lastvalue(Ref(Cover,-Exitdelay));
//IBKR Dashboard
GfxSelectFont( "BOOK ANTIQUA", 14, 100 );
GfxSetBkMode( 1 );
if(EnableAlgo == "Enable")
{
AlgoStatus = "Algo Enabled";
GfxSetTextColor( colorGreen );
GfxTextOut( "Algostatus : "+AlgoStatus , 20, 40);
if(Nz(StaticVarGet(static_name_algo),0)!=1)
{
_TRACE("Algo Status : Enabled");
StaticVarSet(static_name_algo, 1);
}
}
if(EnableAlgo == "Disable")
{
AlgoStatus = "Algo Disabled";
GfxSetTextColor( colorRed );
GfxTextOut( "Algostatus : "+AlgoStatus , 20, 40);
if(Nz(StaticVarGet(static_name_algo),0)!=0)
{
_TRACE("Algo Status : Disabled");
StaticVarSet(static_name_algo, 0);
}
}
if(EnableAlgo == "LongOnly")
{
AlgoStatus = "Long Only";
GfxSetTextColor( colorYellow );
GfxTextOut( "Algostatus : "+AlgoStatus , 20, 40);
if(Nz(StaticVarGet(static_name_algo),0)!=2)
{
_TRACE("Algo Status : Long Only");
StaticVarSet(static_name_algo, 2);
}
}
if(EnableAlgo == "ShortOnly")
{
AlgoStatus = "Short Only";
GfxSetTextColor( colorYellow );
GfxTextOut( "Algostatus : "+AlgoStatus , 20, 40);
if(Nz(StaticVarGet(static_name_algo),0)!=3)
{
_TRACE("Algo Status : Short Only");
StaticVarSet(static_name_algo, 3);
}
}
//Button Trading Module
X0 = 20;
Y0 = 100;
X1 = 60;
LBClick = GetCursorMouseButtons() == 9; // Click
MouseX = Nz(GetCursorXPosition(1)); //
MouseY = Nz(GetCursorYPosition(1)); //
procedure DrawButton (Text, x1, y1, x2, y2, colorFrom, colorTo)
{
GfxSetOverlayMode(0);
GfxSelectFont("Verdana", 9, 700);
GfxSetBkMode(1);
GfxGradientRect(x1, y1, x2, y2, colorFrom, colorTo);
GfxDrawText(Text, x1, y1, x2, y2, 32|1|4|16);
}
GfxSetTextColor(colorWhite);
//PlaceOrder Sends Market Order Returns response on Succesful PlaceOrder
function PlaceOrder(action,orderqty) {
orderid = "";
ibc = GetTradingInterface("IB");
// check if we are connected OK
if( ibc.IsConnected() )
{
openpos = ibc.GetPositionSize( symbol );
// check if we do not have already open position on this stock
if( openpos == 0)
{
// transmit order
orderid = ibc.PlaceOrder( symbol, action, orderqty , ordertype, LimitPrice , StopPrice , TimeInForce , Transmit );
_TRACE("Trading Symbol :"+symbol+" Quantity :"+orderqty+" Action :"+action);
_TRACE("Trading Symbol :"+symbol+"Orderid :"+orderid);
if(VoiceAlert == "Enable")
Say( "Order Placed" );
}
// reverse the position if open position is found
if( (openpos < 0 AND action == "BUY") OR
(openpos > 0 AND action == "SELL"))
{
// transmit order
orderid = ibc.PlaceOrder( symbol, action, 2*orderqty , ordertype, LimitPrice , StopPrice , TimeInForce , Transmit );
_TRACE("Trading Symbol :"+symbol+" Quantity :"+2*orderqty+" Action :"+action);
_TRACE("Trading Symbol :"+symbol+"Orderid :"+orderid);
if(VoiceAlert == "Enable")
Say( "Order Placed" );
}
// reverse the position if open position is found
if( (openpos > 0 AND action == "BUY") OR
(openpos < 0 AND action == "SELL"))
{
_TRACE("Cannot Add to the existing open position - pyramiding is not accepted ");
}
}
return resp;
}
function ExitOrder(action,orderqty) {
orderid = "";
ibc = GetTradingInterface("IB");
// check if we are connected OK
if( ibc.IsConnected() )
{
openpos = ibc.GetPositionSize( symbol );
// check if we do not have already open position on this stock
if( openpos == 0)
{
// transmit order
//orderid = ibc.PlaceOrder( symbol, action, orderqty , ordertype, LimitPrice , StopPrice , TimeInForce , Transmit );
_TRACE("No Open Position Found. Hence no action taken");
}
// reverse the position if open position is found
if( (openpos < 0 AND action == "BUY") OR
(openpos > 0 AND action == "SELL"))
{
// transmit order
orderid = ibc.PlaceOrder( symbol, action, orderqty , ordertype, LimitPrice , StopPrice , TimeInForce , Transmit );
_TRACE("Trading Symbol :"+symbol+" Quantity :"+orderqty+" Action :"+action);
_TRACE("Trading Symbol :"+symbol+"Orderid :"+orderid);
}
}
if(VoiceAlert == "Enable" AND openpos != 0)
Say( "Exit Order Placed" );
return resp;
}
//Execution Module
if(EnableAlgo != "Disable")
{
lasttime = StrFormat("%0.f",LastValue(BarIndex()));
SetChartBkColor(colorDarkGrey);
if(EnableButton == "Enable")
{
DrawButton("BE", X0, Y0, X0+X1, Y0+50, colorGreen, colorGreen);
CursorInBEButton = MouseX >= X0 AND MouseX <= X0+X1 AND MouseY >= Y0 AND MouseY <= Y0+50;
BEButtonClick = CursorInBEButton AND LBClick;
DrawButton("BX", X0+65, Y0, X0+X1+65, Y0+50, colorGreen, colorGreen);
CursorInBXButton = MouseX >= X0+65 AND MouseX <= X0+X1+65 AND MouseY >= Y0 AND MouseY <= Y0+50;
BxButtonClick = CursorInBXButton AND LBClick;
DrawButton("SE", X0, Y0+55, X0+X1, Y0+105, colorRed, colorRed);
CursorInSEButton = MouseX >= X0 AND MouseX <= X0+X1 AND MouseY >= Y0+55 AND MouseY <= Y0+105;
SEButtonClick = CursorInSEButton AND LBClick;
DrawButton("SX", X0+65, Y0+55, X0+X1+65, Y0+105, colorRed, colorRed);
CursorInSXButton = MouseX >= X0+65 AND MouseX <= X0+X1+65 AND MouseY >= Y0+55 AND MouseY <= Y0+105;
SXButtonClick = CursorInSXButton AND LBClick;
if( BEButtonClick AND StaticVarGet(Name()+GetChartID()+"BEAlgo")==0 )
{
PlaceOrder("BUY",quantity);
StaticVarSet(Name()+GetChartID()+"BEAlgo",1);
}
else
{
StaticVarSet(Name()+GetChartID()+"BEAlgo",0);
}
if( SEButtonClick AND StaticVarGet(Name()+GetChartID()+"SEAlgo")==0 )
{
PlaceOrder("SELL",quantity);
StaticVarSet(Name()+GetChartID()+"SEAlgo",1);
}
else
{
StaticVarSet(Name()+GetChartID()+"SEAlgo",0);
}
if( BXButtonClick AND StaticVarGet(Name()+GetChartID()+"BXAlgo")==0 )
{
ExitOrder("SELL",quantity);
StaticVarSet(Name()+GetChartID()+"BXAlgo",1);
}
else
{
StaticVarSet(Name()+GetChartID()+"BXAlgo",0);
}
if( SXButtonClick AND StaticVarGet(Name()+GetChartID()+"SXAlgo")==0 )
{
ExitOrder("BUY",quantity);
StaticVarSet(Name()+GetChartID()+"SXAlgo",1);
}
else
{
StaticVarSet(Name()+GetChartID()+"SXAlgo",0);
}
}//button trading ends
if(EnableAlgo == "Enable")
{
if (AlgoBuy==True AND AlgoCover == True AND StaticVarGet(static_name_+"buyCoverAlgo")==0 AND StaticVarGetText(static_name_+"buyCoverAlgo_barvalue") != lasttime )
{
PlaceOrder("BUY",2*quantity);
StaticVarSetText(static_name_+"buyCoverAlgo_barvalue",lasttime);
StaticVarSet(static_name_+"buyCoverAlgo",1); //Algo Order was triggered, no more order on this bar
}
else if ((AlgoBuy != True OR AlgoCover != True))
{
StaticVarSet(static_name_+"buyCoverAlgo",0);
StaticVarSetText(static_name_+"buyCoverAlgo_barvalue","");
}
if (AlgoBuy==True AND AlgoCover != True AND StaticVarGet(static_name_+"buyAlgo")==0 AND StaticVarGetText(static_name_+"buyAlgo_barvalue") != lasttime)
{
// Long Entry
PlaceOrder("BUY",quantity);
StaticVarSetText(static_name_+"buyAlgo_barvalue",lasttime);
StaticVarSet(static_name_+"buyAlgo",1); //Algo Order was triggered, no more order on this bar
}
else if (AlgoBuy != True)
{
StaticVarSet(static_name_+"buyAlgo",0);
StaticVarSetText(static_name_+"buyAlgo_barvalue","");
}
if (AlgoSell==true AND AlgoShort != True AND StaticVarGet(static_name_+"sellAlgo")==0 AND StaticVarGetText(static_name_+"sellAlgo_barvalue") != lasttime)
{
// Long Exit
ExitOrder("SELL",quantity);
StaticVarSetText(static_name_+"sellAlgo_barvalue",lasttime);
StaticVarSet(static_name_+"sellAlgo",1); //Algo Order was triggered, no more order on this bar
}
else if (AlgoSell != True )
{
StaticVarSet(static_name_+"sellAlgo",0);
StaticVarSetText(static_name_+"sellAlgo_barvalue","");
}
if (AlgoShort==True AND AlgoSell==True AND StaticVarGet(static_name_+"ShortSellAlgo")==0 AND StaticVarGetText(static_name_+"ShortSellAlgo_barvalue") != lasttime)
{
// reverse Short Entry
PlaceOrder("SELL",2*quantity);
StaticVarSetText(static_name_+"ShortsellAlgo_barvalue",lasttime);
StaticVarSet(static_name_+"ShortSellAlgo",1); //Algo Order was triggered, no more order on this bar
}
else if ((AlgoShort != True OR AlgoSell != True))
{
StaticVarSet(static_name_+"ShortSellAlgo",0);
StaticVarSetText(static_name_+"ShortsellAlgo_barvalue","");
}
if (AlgoShort==True AND AlgoSell != True AND StaticVarGet(static_name_+"ShortAlgo")==0 AND StaticVarGetText(static_name_+"ShortAlgo_barvalue") != lasttime)
{
// Short Entry
PlaceOrder("SELL",quantity);
StaticVarSetText(static_name_+"ShortAlgo_barvalue",lasttime);
StaticVarSet(static_name_+"ShortAlgo",1); //Algo Order was triggered, no more order on this bar
}
else if (AlgoShort != True )
{
StaticVarSet(static_name_+"ShortAlgo",0);
StaticVarSetText(static_name_+"ShortAlgo_barvalue","");
}
if (AlgoCover==true AND AlgoBuy != True AND StaticVarGet(static_name_+"CoverAlgo")==0 AND StaticVarGetText(static_name_+"CoverAlgo_barvalue") != lasttime)
{
// Short Exit
ExitOrder("BUY",quantity);
StaticVarSetText(static_name_+"CoverAlgo_barvalue",lasttime);
StaticVarSet(static_name_+"CoverAlgo",1); //Algo Order was triggered, no more order on this bar
}
else if (AlgoCover != True )
{
StaticVarSet(static_name_+"CoverAlgo",0);
StaticVarSetText(static_name_+"CoverAlgo_barvalue","");
}
}
else if(EnableAlgo == "LongOnly")
{
if (AlgoBuy==True AND StaticVarGet(static_name_+"buyAlgo")==0 AND StaticVarGetText(static_name_+"buyAlgo_barvalue") != lasttime)
{
// Long Entry
PlaceOrder("BUY",quantity);
StaticVarSetText(static_name_+"buyAlgo_barvalue",lasttime);
StaticVarSet(static_name_+"buyAlgo",1); //Algo Order was triggered, no more order on this bar
}
else if (AlgoBuy != True)
{
StaticVarSet(static_name_+"buyAlgo",0);
StaticVarSetText(static_name_+"buyAlgo_barvalue","");
}
if (AlgoSell==true AND StaticVarGet(static_name_+"sellAlgo")==0 AND StaticVarGetText(static_name_+"sellAlgo_barvalue") != lasttime)
{
// Long Exit
ExitOrder("SELL",quantity);
StaticVarSetText(static_name_+"sellAlgo_barvalue",lasttime);
StaticVarSet(static_name_+"sellAlgo",1); //Algo Order was triggered, no more order on this bar
}
else if (AlgoSell != True )
{
StaticVarSet(static_name_+"sellAlgo",0);
StaticVarSetText(static_name_+"sellAlgo_barvalue","");
}
}
else if(EnableAlgo == "ShortOnly")
{
if (AlgoShort==True AND StaticVarGet(static_name_+"ShortAlgo")==0 AND StaticVarGetText(static_name_+"ShortAlgo_barvalue") != lasttime)
{
// Short Entry
PlaceOrder("SELL",quantity);
StaticVarSetText(static_name_+"ShortAlgo_barvalue",lasttime);
StaticVarSet(static_name_+"ShortAlgo",1); //Algo Order was triggered, no more order on this bar
}
else if (AlgoShort != True )
{
StaticVarSet(static_name_+"ShortAlgo",0);
StaticVarSetText(static_name_+"ShortAlgo_barvalue","");
}
if (AlgoCover==true AND StaticVarGet(static_name_+"CoverAlgo")==0 AND StaticVarGetText(static_name_+"CoverAlgo_barvalue") != lasttime)
{
// Short Exit
ExitOrder("BUY",quantity);
StaticVarSetText(static_name_+"CoverAlgo_barvalue",lasttime);
StaticVarSet(static_name_+"CoverAlgo",1); //Algo Order was triggered, no more order on this bar
}
else if (AlgoCover != True)
{
StaticVarSet(static_name_+"CoverAlgo",0);
StaticVarSetText(static_name_+"CoverAlgo_barvalue","");
}
}
}