# Button Trading Module (Modern)

This AmiBroker order pad lets you place **instant BUY or SELL orders directly from your chart** using OpenAlgo. Just enter your **OpenAlgo API key** (from your OpenAlgo app), fill in the **symbol, quantity, product type (MIS/CNC/NRML), and exchange (like NSE)**, then click the green BUY or red SELL button. Make sure **OpenAlgo is running.**

All orders are **market orders** sent immediately, and you can see the detailed request and response in the AmiBroker **Trace Window** for full transparency.

```clike
///Rajandran R - Creator of OpenAlgo
//website - openalgo.in / marketcalls.in
//OpenAlgo - Amibroker Button Trading Module (Modern) v1.0
//Date - 03/07/2025
_SECTION_BEGIN("OpenAlgo Button Trading Module (Modern)");

//Note : This Amibroker AFL Works only on 6.35 or higher version only.

/* -----------------Globals-----------------------------------------------  */
global _x0, _y0, IDset;
_x0   = 20;
_y0   = 20;
IDset = 0;

DT_CENTER  = 1;
DT_VCENTER = 4 | 32;
RequestTimedRefresh( 1, False );

/* ---------------- helper ------------------------------------------------ */
procedure GfxSetColors( fg, bg )
{
    GfxSetTextColor( fg );  GfxSetBkColor( bg );
    GfxSelectPen( fg );     GfxSelectSolidBrush( bg );
}

function PointInside( px, py, x, y, w, h )
{
    x += _x0;  y += _y0;
    return ( px>=x AND px<=x+w AND py>=y AND py<=y+h );
}

/* --------------------------------------------------------------------------
   LeftClickInside – single-return version
   -------------------------------------------------------------------------- */
function LeftClickInside( x, y, w, h )
{
    /* default = NO click */
    hit = False;                         // ? initialise return flag (scalar)

    mb  = GetCursorMouseButtons();       //   current mouse-button state
    if ( mb & 8 )                        //   8 = left button pressed
    {
        px = GetCursorXPosition( 1 );    //   cursor X (pixels)
        py = GetCursorYPosition( 1 );    //   cursor Y (pixels)

        /* set flag only if pointer is inside the rectangle */
        if ( PointInside( px, py, x, y, w, h ) )
            hit = True;
    }

    /* SINGLE exit-point */
    return hit;                          // always one scalar value
}

/* ---------------- Static-var state helpers ------------------------------ */
function _GetState( id ){ return Nz( StaticVarGet("GFX_"+id+GetChartID()),0 ); }
procedure _SetState( id, v ){ StaticVarSet("GFX_"+id+GetChartID(),v); }

/* -----------------------  GfxSelect  (patched) -------------------------- */
function GfxSelect( id, csv, x, y, w, h, fg, bg )
{
    x += _x0;  y += _y0;

    s  = _GetState( id );   if( s == 0 ) s = -1;        // closed initially
    cnt= StrCount( csv, "," ) + 1;

    /* mouse */
    if( s < 0 )                               // closed – header only
    {
        if( LeftClickInside( x-_x0, y-_y0, w, h ) ) s = -s;      // open
    }
    else                                      // open
    {
        // ***** PATCHED LINE *****
        if( LeftClickInside( x-_x0, y-_y0, w, (cnt+1)*h ) )
        {
            py = GetCursorYPosition(1);
            idx= round( 0.5 + ( py-(y-_y0) )/h );
            if( idx>1 ) s = -(idx-1); else s = -s;
        }
    }
    _SetState( id, s );

    sel = abs(s) - 1;                         // 0-based index

    /* draw */
    GfxSetColors( fg, bg );
    GfxRoundRect( x, y, x+w, y+h, 5, 5 );
    GfxDrawText( StrExtract(csv,sel), x,y,x+w,y+h, DT_CENTER|DT_VCENTER );

    if( s > 0 )
    {
        GfxSetColors( bg, fg );
        for( i = 0; i < cnt; i++ )
        {
            yy = y + (i+1)*h;
            GfxRectangle( x, yy, x+w, yy+h );
            GfxDrawText( StrExtract(csv,i), x,yy,x+w,yy+h,
                         DT_CENTER|DT_VCENTER );
        }
    }
    return sel;                               // ONE return
}

/* ------------------ OpenAlgo HTTP poster (unchanged) ------------------- */
function PostOA( host, act, qty, apiKey, sym, exch, iprod )
{
    url  = host + "/api/v1/placeorder";
    body = "{\"apikey\":\""+apiKey+"\","+
           "\"strategy\":\"Amibroker\","+
           "\"symbol\":\""+sym+"\","+
           "\"action\":\""+act+"\","+
           "\"exchange\":\""+exch+"\","+
           "\"pricetype\":\"MARKET\","+
           "\"product\":\""+iprod+"\","+
           "\"quantity\":\""+qty+"\"}";

    _TRACEF("OpenAlgo request : %s",body);

    InternetSetHeaders("Content-Type: application/json\r\n");
    ih = InternetPostRequest(url,body);
    if( ih )
    {
        rsp = "";
        while( ( iln = InternetReadString(ih) ) != "" ) rsp += iln;
        _TRACEF("OpenAlgo response: %s",rsp);
        InternetClose(ih);
    }
    else _TRACE("OpenAlgo HTTP post failed");
    return 0;
}


/*---------------------------------------------------------------------------
      VERSION CHECK  (GUI code only if >= 6.35)
---------------------------------------------------------------------------*/
ReqVer = 6.35;
if ( Version() < ReqVer )
{
    /* old release – show banner, nothing more */
    SetChartOptions(0,chartShowDates);
    GfxSetBkColor(colorBlack);
    GfxSetTextColor(colorRed);
    GfxSelectFont("Arial",16,700);
    GfxTextOut("This AFL needs AmiBroker 6.35 or later",40,40);
}

/*---------------------------------------------------------------------------
      Amibroker GUI and GFX Controls to Place Order in OpenAlgo
---------------------------------------------------------------------------*/

else 
{

/* ----------------------------- Layout ---------------------------------- */
row  = 35; lblW = 60; gap = 7; tbW = 210; ddW = 110; btnW = 90; btnH = 30;
GfxSetTextColor(colorWhite); GfxSetBkColor(colorBlack);

/* Host */
GfxDrawText("Host",_x0,_y0,_x0+lblW,_y0+row,DT_VCENTER);
rc = GuiEdit(++IDset,_x0+lblW+gap,_y0,tbW,25,notifyEditChange);
if(rc==guiNew)GuiSetText("http://127.0.0.1:5000",IDset);
hostURL = GuiGetText(IDset);

/* Buttons (top-right) */
btnY  = _y0;
btnBX = _x0+lblW+gap+tbW+40;
GuiButton("BUY" ,++IDset,btnBX       ,btnY,btnW,btnH,notifyClicked); buyID = IDset;
GuiButton("SELL",++IDset,btnBX+btnW+20,btnY,btnW,btnH,notifyClicked); sellID= IDset;
GuiSetColors(buyID ,buyID ,1,colorWhite,colorGreen,colorWhite);
GuiSetColors(sellID,sellID,1,colorWhite,colorRed ,colorWhite);

/* API key */
yy = _y0+row;
GfxDrawText("API Key",_x0,yy,_x0+lblW,yy+row,DT_VCENTER);
rc = GuiEdit(++IDset,_x0+lblW+gap,yy,tbW,25,notifyEditChange);
if(rc==guiNew)GuiSetText("******",IDset);
apiKey = GuiGetText(IDset);

/* Symbol */
yy += row;
GfxDrawText("Symbol",_x0,yy,_x0+lblW,yy+row,DT_VCENTER);
rc = GuiEdit(++IDset,_x0+lblW+gap,yy,tbW,25,notifyEditChange);
if(rc==guiNew)GuiSetText("RELIANCE",IDset);
symbol = GuiGetText(IDset);

/* Quantity */
yy += row;
GfxDrawText("Qty",_x0,yy,_x0+lblW,yy+row,DT_VCENTER);
rc = GuiEdit(++IDset,_x0+lblW+gap,yy,80,25,notifyEditChange);
if(rc==guiNew)GuiSetText("1",IDset);
qtyVal = StrToNum(GuiGetText(IDset));

/* Product & Exchange */
yy += row;
iprodIdx = GfxSelect("iprod","MIS,CNC,NRML",
                     _x0+lblW+gap,yy,ddW,28,colorWhite,colorRed);
exchIdx  = GfxSelect("exch" ,"NSE,NFO,BSE,BFO,MCX,CDS",
                     _x0+lblW+gap+ddW+20,yy,ddW+25,28,colorWhite,colorBlue);

iprod    = StrExtract("MIS,CNC,NRML",iprodIdx);
exchange = StrExtract("NSE,NFO,BSE,BFO,MCX,CDS",exchIdx);

/* -------------------- event loop -------------------- */
for( i=0;(cid=GuiGetEvent(i,0))>0;i++ )
{
    if( GuiGetEvent(i,1) == notifyClicked )
    {
        if( cid == buyID )
            PostOA(hostURL,"BUY" ,qtyVal,apiKey,symbol,exchange,iprod);
        if( cid == sellID )
            PostOA(hostURL,"SELL",qtyVal,apiKey,symbol,exchange,iprod);
    }
}



/* Chart */
SetChartOptions(0,chartShowArrows|chartShowDates);
Plot(Close,"Price",colorDefault,styleCandle);
_N( Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}}  O %g H %g L %g C %g (%.1f%%)  "
       +"Qty %g  iprod %s  Exch %s",
       O,H,L,C,SelectedValue(ROC(C,1)),qtyVal,iprod,exchange));
}
_SECTION_END();

```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.openalgo.in/trading-platform/amibroker/button-trading-module-modern.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
