Rajandran R Telecom Engineer turned Full-time Derivative Trader. Mostly Trading Nifty, Banknifty, USDINR and High Liquid Stock Derivatives. Trading the Markets Since 2006 onwards. Using Market Profile and Orderflow for more than a decade. Designed and published 100+ open source trading systems on various trading tools. Strongly believe that market understanding and robust trading frameworks are the key to the trading success. Writing about Markets, Trading System Design, Market Sentiment, Trading Softwares & Trading Nuances since 2007 onwards. Author of Marketcalls.in)

Interactive Brokers – Smart Order Chart Trading Module using IB Controller for Amibroker

8 min read

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

ParameterDescription
Trading SymbolInteractive Broker Trading Symbol
Order TypesDefines the order types to be used when placing trades through Interactive Brokers, e.g., Market Orders (MKT) or Limit Orders (LMT).
QuantitySpecifies the quantity of shares or contracts to trade
Time in ForceDetermines how long an order remains active before it is canceled, e.g., DAY or GTC (Good Till Canceled).
TransmitControls whether the order is immediately transmitted to the exchange or requires manual confirmation. AUTO – Fully Automated Mode, SEMIAUTO – Semi Auto Mode
Button Trading ModuleProvides 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 StatusAllows enabling or disabling the algorithm, as well as setting it to only allow long or short positions.
Voice AlertsEnables voice alerts for order placements.
Entry Delay0 – No Delay , 1 – Candle Completion
Exit Delay0 – 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

StepConditionActionDescription
1Check Connection to IBProceed if connected; Otherwise, halt.Ensures that there’s a live connection to Interactive Brokers (IB) before attempting to place any orders.
2Determine Open Position SizeRetrieve 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.
3No Open PositionPlace 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.
4Open Position Found & Opposite Action RequiredIf 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.
5Open Position Matches ActionLog 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

StepConditionActionDescription
1Check Connection to IBProceed if connected; Otherwise, halt.Ensures that there’s a live connection to Interactive Brokers (IB) before attempting to execute any exit orders.
2Determine Open Position SizeRetrieve 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.
3No Open Position FoundLog 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.
4Open Position Found & Exit Action Matches Required DirectionPlace 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.
5Voice Alert Enabled & Open Position ExistedVoice 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","");
            }
        }
        
    }
    
Rajandran R Telecom Engineer turned Full-time Derivative Trader. Mostly Trading Nifty, Banknifty, USDINR and High Liquid Stock Derivatives. Trading the Markets Since 2006 onwards. Using Market Profile and Orderflow for more than a decade. Designed and published 100+ open source trading systems on various trading tools. Strongly believe that market understanding and robust trading frameworks are the key to the trading success. Writing about Markets, Trading System Design, Market Sentiment, Trading Softwares & Trading Nuances since 2007 onwards. Author of Marketcalls.in)

Introducing OpenAlgo V1.0: The Ultimate Open-Source Algorithmic Trading Framework…

OpenAlgo V1.0 is an open-source algorithmic trading platform to automate your trading strategies using Amibroker, Tradingview, Metatrader, Python etc. Designed with the modern trader...
Rajandran R
2 min read

[Live Coding Webinar] Build Your First Trading Bridge for…

In this course, you will be learning to build your own trading bridge using Python. This 60-minute session is perfect for traders, Python enthusiasts,...
Rajandran R
1 min read

[Webinar] Understanding and Mitigating Curve Fitting in System Trading

"Understanding and Mitigating Curve Fitting in System Trading"! This dynamic session aims to equip novice to intermediate traders, quantitative analysts, and financial engineers with...
Rajandran R
1 min read

Leave a Reply

Get Notifications, Alerts on Market Updates, Trading Tools, Automation & More