Got frequent requirements from many traders to automate an Amibroker-based trading system where one single button click from charts could punch orders in multiple accounts (friends & family). Here is the readymade execution module one can plugin send multi orders and easily configure multi-client under the same broker.
This tutorial demonstrates how to send orders from Amibroker to Algomojo using buttons trading to Multiple trading accounts.
Supported Amibroker Version
Amibroker 6.22 or Higher
Who can make use of this module?
Any traders who have access to Amibroker and access to Algomojo Trading Platform can trigger their buy & sell signal generation from their trading system to multiple accounts (friends & family). i.e one Amibroker to fire orders in multiple accounts.
Which brokers are supported?
All the Supported Algomojo Brokers
How many accounts one can connect?
Currently, there is no restriction on the number of clients one can connect.
Multi-Client Account Controls – AFL Coding Block
Multi-client account control block contains the configuration of multiple clients, trading symbols, and trade quantity,api key and api secret. If more clients need to be added then here is the sample format. Client details need to be configured in order to send multiple client accounts.
ver = ParamStr("API Version ","v1");
TotalAccounts = Param("Total Accounts",4,1,100,1);
broker1 =Paramlist("Broker1","an|ab|fs|fy|tc|up|zb|ze",0);
Client1 = paramlist("Client1","Disable|Enable",0);
symbol1 = ParamStr("Trading Symbol1","BHEL");
apikey1 = ParamStr("user_apikey1","xxxxxxxxxxx"); //Enter your API key here
apisecret1 = ParamStr("api_secret1","xxxxxxxxxxx"); //Enter your API secret key here
quantity1 = Param("Quantity1",1,1,10000,1);
broker2 =Paramlist("Broker2","an|ab|fs|fy|tc|up|zb|ze",0);
Client2 = paramlist("Client2","Disable|Enable",0);
symbol2 = ParamStr("Trading Symbol2","BHEL-EQ");
apikey2 = ParamStr("user_apikey2","xxxxxxxxxxx"); //Enter your API key here
apisecret2 = ParamStr("api_secret2","xxxxxxxxxxx"); //Enter your API secret key here
quantity2 = Param("Quantity2",1,1,10000,1);
broker3 =Paramlist("Broker3","an|ab|fs|fy|tc|up|zb|ze",0);
Client3 = paramlist("Client3","Disable|Enable",0);
symbol3 = ParamStr("Trading Symbol3","BHEL-EQ");
apikey3 = ParamStr("user_apikey3","xxxxxxxxxxx"); //Enter your API key here
apisecret3 = ParamStr("api_secret3","xxxxxxxxxxx"); //Enter your API secret key here
quantity3 = Param("Quantity3",1,1,10000,1);
broker4 =Paramlist("Broker4","an|ab|fs|fy|tc|up|zb|ze",0);
Client4 = paramlist("Client4","Disable|Enable",0);
symbol4 = ParamStr("Trading Symbol4","BHEL-EQ");
apikey4 = ParamStr("user_apikey4","xxxxxxxxxxx"); //Enter your API key here
apisecret4 = ParamStr("api_secret4","xxxxxxxxxxx"); //Enter your API secret key here
quantity4 = Param("Quantity4",1,1,10000,1);
Multi Client Button Trading Module – Amibroker AFL
Here is the complete code where the user has to configure the Total Accounts, Client ID, APIKey, API Secret, Trading Size, and Multiplier accordingly.
/*
Algomojo - Multi Client Smart Button Trading Module
Created By : Rajandran R(Founder - Marketcalls / Co-Founder Algomojo )
Created on : 08 Dec 2022.
Website : www.marketcalls.in / www.algomojo.com
*/
/*Button Types
BE - Buy Entry
BX - Buy Exit (Close all the Buy Positions)
SE - Short Entry
SX - Short Exit (Close all the Short Positions)
Close All - Squareoff All the Open Positions from Position Book
*/
_SECTION_BEGIN("Algomojo - Multi Client Smart Button Trading");
// Send orders even if Amibroker is minimized or Chart is not active
RequestTimedRefresh(1, False);
EnableTextOutput(False);
//Creating Input Controls for Setting Order Related Information
ver = ParamStr("API Version ","v1");
TotalAccounts = Param("Total Accounts",4,1,100,1);
broker1 =Paramlist("Broker1","an|ab|fs|fy|tc|up|zb|ze",0);
Client1 = paramlist("Client1","Disable|Enable",0);
symbol1 = ParamStr("Trading Symbol1","BHEL");
apikey1 = ParamStr("user_apikey1","xxxxxxxxxxx"); //Enter your API key here
apisecret1 = ParamStr("api_secret1","xxxxxxxxxxx"); //Enter your API secret key here
quantity1 = Param("Quantity1",1,1,10000,1);
broker2 =Paramlist("Broker2","an|ab|fs|fy|tc|up|zb|ze",0);
Client2 = paramlist("Client2","Disable|Enable",0);
symbol2 = ParamStr("Trading Symbol2","BHEL-EQ");
apikey2 = ParamStr("user_apikey2","xxxxxxxxxxx"); //Enter your API key here
apisecret2 = ParamStr("api_secret2","xxxxxxxxxxx"); //Enter your API secret key here
quantity2 = Param("Quantity2",1,1,10000,1);
broker3 =Paramlist("Broker3","an|ab|fs|fy|tc|up|zb|ze",0);
Client3 = paramlist("Client3","Disable|Enable",0);
symbol3 = ParamStr("Trading Symbol3","BHEL-EQ");
apikey3 = ParamStr("user_apikey3","xxxxxxxxxxx"); //Enter your API key here
apisecret3 = ParamStr("api_secret3","xxxxxxxxxxx"); //Enter your API secret key here
quantity3 = Param("Quantity3",1,1,10000,1);
broker4 =Paramlist("Broker4","an|ab|fs|fy|tc|up|zb|ze",0);
Client4 = paramlist("Client4","Disable|Enable",0);
symbol4 = ParamStr("Trading Symbol4","BHEL-EQ");
apikey4 = ParamStr("user_apikey4","xxxxxxxxxxx"); //Enter your API key here
apisecret4 = ParamStr("api_secret4","xxxxxxxxxxx"); //Enter your API secret key here
quantity4 = Param("Quantity4",1,1,10000,1);
_SECTION_END();
_SECTION_BEGIN("Algomojo - Order Controls");
strategy = ParamStr("Strategy Name", "Ami Strategy");
exchange = ParamList("Exchange","NSE|NFO|BSE|MCX",0);
product = ParamList("Product","CNC|MIS|NRML",1);
pricetype = "MARKET";
price = 0;
disclosed_quantity = 0;
trigger_price = 0;
amo = "NO";
splitorder = ParamList("To Split Orders","NO|YES",0);
split_quantity = Param("Split Quantity",500,1,100000,1);
VoiceAlert = ParamList("Voice Alert","Disable|Enable",1);
Entrydelay = Param("Entry Delay",0,0,1); // 0 - Execution with No Delay after a signal, 1- Execution at the end of the candle
Exitdelay = Param("Exit Delay",0,0,1);
EnableAlgo = ParamList("Algo Mode","Disable|Enable",0); // Algo Mode
static_name_ = Name()+GetChartID()+interval(2)+strategy;
static_name_algo = Name()+GetChartID()+interval(2)+strategy+"algostatus";
//StaticVarSet(static_name_algo, -1);
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);
}
}
resp = "";
//PlaceOrder Sends Market Order Returns response on Succesful PlaceOrder
function PlaceOrder(action)
{
api_data = "";
//Creating the Trading Bridge
algomojo=CreateObject("AMAMIBRIDGE.Main");
//Preparing the API data
for(i=1;i<=TotalAccounts;i++)
{
if(varget("Client"+i)=="Enable") //if the clients are enable state
{
api_data = "{ \"broker\": \""+varget("broker"+i)+"\",
\"strategy\":\""+strategy+"\",
\"exchange\":\""+exchange+"\",
\"symbol\":\""+varget("symbol"+i)+"\",
\"action\":\""+action+"\",
\"product\":\""+product+"\",
\"pricetype\":\""+pricetype+"\",
\"quantity\":\""+varget("quantity"+i)+"\",
\"price\":\""+price+"\",
\"disclosed_quantity\":\""+disclosed_quantity+"\",
\"trigger_price\":\""+trigger_price+"\",
\"amo\":\""+amo+"\",
\"splitorder\":\""+splitorder+"\",
\"split_quantity\":\""+split_quantity+"\" }";
_TRACE("Broker API Request"+api_data);
resp=algomojo.AMDispatcher(varget("apikey"+i), varget("apisecret"+i),"PlaceOrder",api_data,"am",ver);
_TRACE("API Response : "+resp);
}//end if loop
}//end of for loop
if(VoiceAlert == "Enable")
Say( "Order Placed" );
}
function ExitOrder(action,position_size) {
//Creating the Trading Bridge
algomojo=CreateObject("AMAMIBRIDGE.Main");
//Preparing the API data
for(i=1;i<=TotalAccounts;i++)
{
if(varget("Client"+i)=="Enable") //if the clients are enable state
{
api_data = "{ \"broker\": \""+varget("broker"+i)+"\",
\"strategy\":\""+strategy+"\",
\"exchange\":\""+exchange+"\",
\"symbol\":\""+varget("symbol"+i)+"\",
\"action\":\""+action+"\",
\"product\":\""+product+"\",
\"pricetype\":\""+pricetype+"\",
\"quantity\":\""+"0"+"\",
\"price\":\""+price+"\",
\"position_size\":\""+position_size+"\",
\"disclosed_quantity\":\""+disclosed_quantity+"\",
\"trigger_price\":\""+trigger_price+"\",
\"amo\":\""+amo+"\",
\"splitorder\":\""+splitorder+"\",
\"split_quantity\":\""+split_quantity+"\" }";
_TRACE("Broker API Request"+api_data);
resp=algomojo.AMDispatcher(varget("apikey"+i), varget("apisecret"+i),"PlaceSmartOrder",api_data,"am",ver);
_TRACE("API Response : "+resp);
}//end if loop
}//end of for loop
if(VoiceAlert == "Enable")
Say( "Order Placed" );
}
function Squareoffall()
{
//Creating the Trading Bridge
algomojo=CreateObject("AMAMIBRIDGE.Main");
for(i=1;i<=TotalAccounts;i++)
{
if(varget("Client"+i)=="Enable") //if the clients are enable state
{
api_data = "{ \"broker\": \""+varget("broker"+i)+"\" }";
_TRACE("Squareoff API Request"+api_data);
//Sending The Broker Request for NetOpenPositions
resp=algomojo.AMDispatcher(varget("apikey"+i), varget("apisecret"+i),"SquareOffAllPosition",api_data,"am",ver);
_TRACE("Squareoff API Response : "+resp);
}//end if loop
}//end of for loop
if(VoiceAlert == "Enable")
Say( "Order Placed" );
return resp;
}
_SECTION_BEGIN("Button Trading - Algomojo For Old Amibroker Versions");
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);
if(EnableAlgo == "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;
DrawButton("SQUAREOFF", X0, Y0+110, X0+X1+65, Y0+155, colorRed, colorRed);
CursorInCXButton = MouseX >= X0 AND MouseX <= X0+X1+65 AND MouseY >= Y0+110 AND MouseY <= Y0+155;
CXButtonClick = CursorInCXButton AND LBClick;
if( BEButtonClick AND StaticVarGet(Name()+GetChartID()+"BEAlgo")==0 )
{
PlaceOrder("BUY");
StaticVarSet(Name()+GetChartID()+"BEAlgo",1);
}
else
{
StaticVarSet(Name()+GetChartID()+"BEAlgo",0);
}
if( SEButtonClick AND StaticVarGet(Name()+GetChartID()+"SEAlgo")==0 )
{
PlaceOrder("SELL");
StaticVarSet(Name()+GetChartID()+"SEAlgo",1);
}
else
{
StaticVarSet(Name()+GetChartID()+"SEAlgo",0);
}
if( BXButtonClick AND StaticVarGet(Name()+GetChartID()+"BXAlgo")==0 )
{
ExitOrder("SELL",0);
StaticVarSet(Name()+GetChartID()+"BXAlgo",1);
}
else
{
StaticVarSet(Name()+GetChartID()+"BXAlgo",0);
}
if( SXButtonClick AND StaticVarGet(Name()+GetChartID()+"SXAlgo")==0 )
{
ExitOrder("BUY",0);
StaticVarSet(Name()+GetChartID()+"SXAlgo",1);
}
else
{
StaticVarSet(Name()+GetChartID()+"SXAlgo",0);
}
if( CXButtonClick AND StaticVarGet(Name()+GetChartID()+"CXAlgo")==0 )
{
Squareoffall();
StaticVarSet(Name()+GetChartID()+"CXAlgo",1);
}
else
{
StaticVarSet(Name()+GetChartID()+"CXAlgo",0);
}
}
_SECTION_END();
_SECTION_BEGIN("Price");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = "");
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
_SECTION_END();