Amibroker Button Trading on chart

I am trying to do button trading through Amibroker. (It fires orders to my broker, which is working fine)

It is only the buttons which are giving me problems.

I have 2 buttons, BUY and SELL. When I click BUY, MIS pops up, I click on MIS > BO > CNC it should cycle between the 3 states (MIS, BO, CNC). Finaly it should take Y-axis price position as ENTRY Price where I click on my chart. (I have text boxes for BO SL and BO Take Profit)

These buttons are not able to do this. Also, Y-axis price not taken but some other lower price taken as Entry Price. Can I have some help or insight on this problem ??

Also there is a great file GfxToolbox.afl which is uploaded in Amibroker community codes, I have used that file...

#include_once "C:\\Amibroker\\Formulas\\Include\\GfxToolbox.afl"

SetTradeDelays(0, 0, 0, 0);
SetPositionSize(1, spsShares);
Symbol = Name() + "-EQ";

prefix = "Order" + GetChartID() + Name();

if (StaticVarGet(prefix + "Initialized") != 1) {
    StaticVarSet(prefix + "BuyState", 0);
    StaticVarSet(prefix + "SellState", 0);
    StaticVarSet(prefix + "ProductIndex", 0);
    StaticVarSet(prefix + "EntryPrice", 0);
    StaticVarSet(prefix + "SLDiff", 0);
    StaticVarSet(prefix + "ProfitDiff", 0);
    StaticVarSet(prefix + "Initialized", 1);
}

x0 = 50;
y0 = 50;
chartHeight = Status("pxheight") - 100;
chartWidth = Status("pxwidth") - 100;

stateBuy = Nz(StaticVarGet(prefix + "BuyState"), 0);
stateSell = Nz(StaticVarGet(prefix + "SellState"), 0);
productIndex = Nz(StaticVarGet(prefix + "ProductIndex"), 0);
selectedProduct = StrExtract("MIS,BO,CNC", productIndex);
entryPrice = Nz(StaticVarGet(prefix + "EntryPrice"), 0);
slDiff = Nz(StaticVarGet(prefix + "SLDiff"), 0);
profitDiff = Nz(StaticVarGet(prefix + "ProfitDiff"), 0);
args = "";

mouseX = GetCursorXPosition(1);
mouseY = GetCursorYPosition(1);

// BUY button
buyClicked = GfxButton("BUY", x0, y0, 80, 30, colorWhite, colorGreen);
if (buyClicked && stateBuy == 0) {
    stateBuy = 1;
    StaticVarSet(prefix + "BuyState", stateBuy);
    _TRACE("BUY clicked at " + Now());
}

// SELL button
sellClicked = GfxButton("SELL", x0 + 90, y0, 80, 30, colorWhite, colorRed);
if (sellClicked && stateSell == 0) {
    stateSell = 1;
    StaticVarSet(prefix + "SellState", stateSell);
    _TRACE("SELL clicked at " + Now());
}

// Product button (cycle MIS ? BO ? CNC)
productClicked = 0;
if (stateBuy >= 1 || stateSell >= 1) {
    xPos = IIf(stateBuy >= 1, x0, x0 + 90);
    productClicked = GfxButton("Product: " + selectedProduct, xPos, y0 + 40, 80, 30, colorWhite, colorBlue);
    if (productClicked && (stateBuy == 1 || stateSell == 1)) {
        productIndex = (productIndex + 1) % 3;
        selectedProduct = StrExtract("MIS,BO,CNC", productIndex);
        StaticVarSet(prefix + "ProductIndex", productIndex);
        if (stateBuy == 1) stateBuy = 2;
        else if (stateSell == 1) stateSell = 2;
        StaticVarSet(prefix + "BuyState", stateBuy);
        StaticVarSet(prefix + "SellState", stateSell);
        _TRACE("Product clicked: " + selectedProduct + " at " + Now());
    }
}

// BO SL and Profit inputs (only in State 2+)
if ((stateBuy >= 2 || stateSell >= 2) && selectedProduct == "BO") {
    xPos = IIf(stateBuy >= 2, x0, x0 + 90);
    slValue = EditNumber(1, slDiff, xPos, y0 + 80, 80, 20, colorBlack, colorWhite);
    profitValue = EditNumber(2, profitDiff, xPos, y0 + 120, 80, 20, colorBlack, colorWhite);
    slDiff = slValue;
    profitDiff = profitValue;
    StaticVarSet(prefix + "SLDiff", slDiff);
    StaticVarSet(prefix + "ProfitDiff", profitDiff);
}

// Chart click to set entry price and place order
mouseClicked = GetCursorMouseButtons() == 9 && mouseY > y0 + 150;
if ((stateBuy >= 2 || stateSell >= 2) && mouseClicked) {
    yPos = GetCursorYPosition(0);  // Chart Y in price units
    priceMin = Status("axisminy");
    priceMax = Status("axismaxy");
    priceRange = priceMax - priceMin;
    pixelsPerUnit = chartHeight / priceRange;
    entryPrice = priceMax - (yPos / pixelsPerUnit);
    StaticVarSet(prefix + "EntryPrice", entryPrice);
    
    if (stateBuy >= 2) {
        action = "B";
        stateBuy = 3;  // Order pending
    } else if (stateSell >= 2) {
        action = "S";
        stateSell = 3;  // Order pending
    }
    StaticVarSet(prefix + "BuyState", stateBuy);
    StaticVarSet(prefix + "SellState", stateSell);
    
    args = "\"" + Symbol + "\" " + "\"" + action + "\" " + "\"" + selectedProduct + "\" " + 
           StrFormat("%.2f", entryPrice);
    if (selectedProduct == "BO") {
        args += " " + StrFormat("%.2f", slDiff) + " " + StrFormat("%.2f", profitDiff);
    }
    ShellExecute("d:\\Python\\python.exe", "d:\\amibrokme\\place_order.py " + args, "d:\\amibrokme\\");
    _TRACE("Order executed: " + args + " at " + Now());
    
    StaticVarSet(prefix + "BuyState", 0);
    StaticVarSet(prefix + "SellState", 0);
    StaticVarSet(prefix + "ProductIndex", 0);
}

Title = "Buy State: " + stateBuy + " | Sell State: " + stateSell + " | Product: " + selectedProduct + 
        " | Entry Price: " + NumToStr(entryPrice, 1.2) + " | Args: " + args + 
        " | BuyClick: " + buyClicked + " | SellClick: " + sellClicked + 
        " | ProductClick: " + productClicked + " | Mouse: " + mouseClicked + 
        " X:" + mouseX + " Y:" + mouseY;

Udated code, but still glitchy. Y-level Prices being picked up properly now. Still Glitchy and not Flawless !

#include_once "C:\\Amibroker\\Formulas\\Include\\GfxToolbox.afl"

SetTradeDelays(0, 0, 0, 0);
SetPositionSize(1, spsShares);
Symbol = Name() + "-EQ";

prefix = "Order" + GetChartID() + Name();

if (StaticVarGet(prefix + "Initialized") != 1) {
    StaticVarSet(prefix + "BuyState", 0);
    StaticVarSet(prefix + "SellState", 0);
    StaticVarSet(prefix + "ProductIndex", 0);
    StaticVarSet(prefix + "EntryPrice", 0);
    StaticVarSet(prefix + "SLDiff", 0);
    StaticVarSet(prefix + "ProfitDiff", 0);
    StaticVarSet(prefix + "Initialized", 1);
}

x0 = 50;
y0 = 50;

stateBuy = Nz(StaticVarGet(prefix + "BuyState"), 0);
stateSell = Nz(StaticVarGet(prefix + "SellState"), 0);
productIndex = Nz(StaticVarGet(prefix + "ProductIndex"), 0);
selectedProduct = StrExtract("MIS,BO,CNC", productIndex);
entryPrice = Nz(StaticVarGet(prefix + "EntryPrice"), 0);
slDiff = Nz(StaticVarGet(prefix + "SLDiff"), 0);
profitDiff = Nz(StaticVarGet(prefix + "ProfitDiff"), 0);
args = "";

mouseX = GetCursorXPosition(1);
mouseY = GetCursorYPosition(1);

// Update entryPrice dynamically with mouse movement
if (mouseY > y0 + 150) {  // Only update below buttons
    rawPrice = GetCursorYPosition(0);  // Current price at cursor
    entryPrice = Round(rawPrice / 0.05) * 0.05;  // Snap to nearest 0.05
    StaticVarSet(prefix + "EntryPrice", entryPrice);
    _TRACE("Mouse moved: Raw Price = " + NumToStr(rawPrice, 1.2) + ", Snapped Entry Price = " + NumToStr(entryPrice, 1.2) + " at " + Now());
}

// BUY button
buyClicked = GfxButton("BUY", x0, y0, 80, 30, colorWhite, colorGreen);
if (buyClicked && stateBuy == 0) {
    stateBuy = 1;
    productIndex = 0;  // Start at MIS
    StaticVarSet(prefix + "BuyState", stateBuy);
    StaticVarSet(prefix + "ProductIndex", productIndex);
    _TRACE("BUY clicked at " + Now());
}

// SELL button
sellClicked = GfxButton("SELL", x0 + 90, y0, 80, 30, colorWhite, colorRed);
if (sellClicked && stateSell == 0) {
    stateSell = 1;
    productIndex = 0;  // Start at MIS
    StaticVarSet(prefix + "SellState", stateSell);
    StaticVarSet(prefix + "ProductIndex", productIndex);
    _TRACE("SELL clicked at " + Now());
}

// Product button (cycle MIS → BO → CNC)
productClicked = GfxButton("Product: " + selectedProduct, 
                          IIf(stateBuy >= 1, x0, x0 + 90), y0 + 40, 80, 30, colorWhite, colorBlue);
if (productClicked && (stateBuy >= 1 || stateSell >= 1)) {
    productIndex = (productIndex + 1) % 3;
    selectedProduct = StrExtract("MIS,BO,CNC", productIndex);
    if (stateBuy == 1) stateBuy = 2;
    if (stateSell == 1) stateSell = 2;
    StaticVarSet(prefix + "ProductIndex", productIndex);
    StaticVarSet(prefix + "BuyState", stateBuy);
    StaticVarSet(prefix + "SellState", stateSell);
    _TRACE("Product clicked: " + selectedProduct + " at " + Now());
}

// BO SL and Profit inputs
if ((stateBuy >= 2 || stateSell >= 2) && selectedProduct == "BO") {
    xPos = IIf(stateBuy >= 2, x0, x0 + 90);
    slValue = EditNumber(1, slDiff, xPos, y0 + 80, 80, 20, colorBlack, colorWhite);
    profitValue = EditNumber(2, profitDiff, xPos, y0 + 120, 80, 20, colorBlack, colorWhite);
    slDiff = slValue;
    profitDiff = profitValue;
    StaticVarSet(prefix + "SLDiff", slDiff);
    StaticVarSet(prefix + "ProfitDiff", profitDiff);
}

// Chart click to place order
mouseClicked = GetCursorMouseButtons() == 9 && mouseY > y0 + 150;
if ((stateBuy >= 2 || stateSell >= 2) && mouseClicked) {
    if (stateBuy >= 2) action = "B";
    else if (stateSell >= 2) action = "S";
    
    args = "\"" + Symbol + "\" " + "\"" + action + "\" " + "\"" + selectedProduct + "\" " + 
           StrFormat("%.2f", entryPrice);
    if (selectedProduct == "BO") {
        args += " " + StrFormat("%.2f", slDiff) + " " + StrFormat("%.2f", profitDiff);
    }
    ShellExecute("d:\\Python\\python.exe", "d:\\amibrokme\\place_order.py " + args, "d:\\amibrokme\\");
    _TRACE("Order executed: " + args + " at " + Now());
    
    StaticVarSet(prefix + "BuyState", 0);
    StaticVarSet(prefix + "SellState", 0);
    StaticVarSet(prefix + "ProductIndex", 0);
}

Title = "Buy State: " + stateBuy + " | Sell State: " + stateSell + " | Product: " + selectedProduct + 
        " | Entry Price: " + NumToStr(entryPrice, 1.2) + " | Args: " + args + 
        " | BuyClick: " + buyClicked + " | SellClick: " + sellClicked + 
        " | ProductClick: " + productClicked + " | Mouse: " + mouseClicked + 
        " X:" + mouseX + " Y:" + mouseY;

You are aware that you can place orders using built-in tool
https://www.amibroker.com/guide/w_placeorder.html

1 Like

Wow I was not aware I could go that way. Thanks Tomasz !

But in any case the code has been perfected and working as intended below...

For anyone who requires it...

#include_once "C:\\Amibroker\\Formulas\\Include\\GfxToolbox.afl"

SetTradeDelays(0, 0, 0, 0);
SetPositionSize(1, spsShares);
Symbol = Name() + "-EQ";

prefix = "Order" + GetChartID() + Name();

if (StaticVarGet(prefix + "Initialized") != 1) {
    StaticVarSet(prefix + "BuyState", 0);
    StaticVarSet(prefix + "SellState", 0);
    StaticVarSet(prefix + "ProductIndex", 0);
    StaticVarSet(prefix + "EntryPrice", 0);
    StaticVarSet(prefix + "SLDiff", 0);
    StaticVarSet(prefix + "ProfitDiff", 0);
    StaticVarSet(prefix + "Initialized", 1);
}

x0 = 50;
y0 = 50;

stateBuy = Nz(StaticVarGet(prefix + "BuyState"), 0);
stateSell = Nz(StaticVarGet(prefix + "SellState"), 0);
productIndex = Nz(StaticVarGet(prefix + "ProductIndex"), 0);
selectedProduct = StrExtract("MIS,BO,CNC", productIndex);
entryPrice = Nz(StaticVarGet(prefix + "EntryPrice"), 0);
slDiff = Nz(StaticVarGet(prefix + "SLDiff"), 0);
profitDiff = Nz(StaticVarGet(prefix + "ProfitDiff"), 0);
args = "";

mouseX = GetCursorXPosition(1);
mouseY = GetCursorYPosition(1);

// Unique IDs for EditNumber based on ChartID
chartId = GetChartID();
baseId = 1000 + abs(chartId); // e.g., 1001, 1002 for ChartID=1
slId = baseId + 1;            // e.g., 1002
profitId = baseId + 2;        // e.g., 1003

// Initialize productClicked
productClicked = 0;

// Update entryPrice dynamically across entire chart
rawPrice = GetCursorYPosition(0);
entryPrice = Round(rawPrice / 0.05) * 0.05;
StaticVarSet(prefix + "EntryPrice", entryPrice);
_TRACE("Mouse moved: Raw Price = " + NumToStr(rawPrice, 1.2) + ", Snapped Entry Price = " + NumToStr(entryPrice, 1.2) + " at " + Now());

// Reset button
resetClicked = GfxButton("R", x0 - 40, y0, 30, 30, colorWhite, colorGrey40);
if (resetClicked) {
    StaticVarSet(prefix + "BuyState", 0);
    StaticVarSet(prefix + "SellState", 0);
    StaticVarSet(prefix + "ProductIndex", 0);
    StaticVarSet(prefix + "EntryPrice", 0);
    StaticVarSet(prefix + "SLDiff", 0);
    StaticVarSet(prefix + "ProfitDiff", 0);
    stateBuy = 0;
    stateSell = 0;
    productIndex = 0;
    entryPrice = 0;
    slDiff = 0;
    profitDiff = 0;
    _TRACE("Reset clicked at " + Now());
}

// BUY button
buyClicked = GfxButton("BUY", x0, y0, 80, 30, colorWhite, colorGreen);
if (buyClicked && stateBuy == 0) {
    stateBuy = 1;
    productIndex = 0;
    StaticVarSet(prefix + "BuyState", stateBuy);
    StaticVarSet(prefix + "ProductIndex", productIndex);
    _TRACE("BUY clicked at " + Now());
}

// SELL button
sellClicked = GfxButton("SELL", x0 + 90, y0, 80, 30, colorWhite, colorRed);
if (sellClicked && stateSell == 0) {
    stateSell = 1;
    productIndex = 0;
    StaticVarSet(prefix + "SellState", stateSell);
    StaticVarSet(prefix + "ProductIndex", productIndex);
    _TRACE("SELL clicked at " + Now());
}

// Product button (only when BUY or SELL is active)
if (stateBuy >= 1 || stateSell >= 1) {
    productClicked = GfxButton("Product: " + selectedProduct, 
                              IIf(stateBuy >= 1, x0, x0 + 90), y0 + 40, 80, 30, colorWhite, colorBlue);
    if (productClicked) {
        productIndex = (productIndex + 1) % 3;
        selectedProduct = StrExtract("MIS,BO,CNC", productIndex);
        if (stateBuy == 1) stateBuy = 2;
        if (stateSell == 1) stateSell = 2;
        StaticVarSet(prefix + "ProductIndex", productIndex);
        StaticVarSet(prefix + "BuyState", stateBuy);
        StaticVarSet(prefix + "SellState", stateSell);
        _TRACE("Product clicked: " + selectedProduct + " at " + Now());
    }
}

// BO SL and Profit inputs
if ((stateBuy >= 2 || stateSell >= 2) && selectedProduct == "BO") {
    xPos = IIf(stateBuy >= 2, x0, x0 + 90);
    slValue = EditNumber(slId, slDiff, xPos, y0 + 80, 80, 20, colorBlack, colorWhite);
    profitValue = EditNumber(profitId, profitDiff, xPos, y0 + 120, 80, 20, colorBlack, colorWhite);
    slDiff = slValue;
    profitDiff = profitValue;
    StaticVarSet(prefix + "SLDiff", slDiff);
    StaticVarSet(prefix + "ProfitDiff", profitDiff);
}

// Chart click to place order (anywhere on chart, restricted above buttons)
mouseClicked = GetCursorMouseButtons() == 9;
if ((stateBuy >= 2 || stateSell >= 2) && mouseClicked && mouseY > y0 + 150) {
    if (stateBuy >= 2) action = "B";
    else if (stateSell >= 2) action = "S";
    
    args = "\"" + Symbol + "\" " + "\"" + action + "\" " + "\"" + selectedProduct + "\" " + 
           StrFormat("%.2f", entryPrice);
    if (selectedProduct == "BO") {
        args += " " + StrFormat("%.2f", slDiff) + " " + StrFormat("%.2f", profitDiff);
    }
    ShellExecute("d:\\Python\\python.exe", "d:\\amibrokme\\place_order.py " + args, "d:\\amibrokme\\");
    _TRACE("Order executed: " + args + " at " + Now());
    
    StaticVarSet(prefix + "BuyState", 0);
    StaticVarSet(prefix + "SellState", 0);
    StaticVarSet(prefix + "ProductIndex", 0);
}

Title = "Buy State: " + stateBuy + " | Sell State: " + stateSell + " | Product: " + selectedProduct + 
        " | Entry Price: " + NumToStr(entryPrice, 1.2) + " | Args: " + args + 
        " | BuyClick: " + buyClicked + " | SellClick: " + sellClicked + 
        " | ProductClick: " + IIf(stateBuy >= 1 || stateSell >= 1, productClicked, 0) + 
        " | ResetClick: " + resetClicked + " | Mouse: " + mouseClicked + " X:" + mouseX + " Y:" + mouseY;

I had multiple _trace() in code as you can see, but they were there for Debug purposes, Can I remove them, will it increase load on CPU if I keep them ??

I am trying to keep the code as lightweight and efficient as possible, but dont want to mess it up with too changes. Please if anyone has suggestions kindly provide!

Hi
During develop a code maybe has multiple lines of _trace() function, the easier way is to turn them ON/OFF is with a parameter

example with ParamTrigger()

 DebugOn = ParamTrigger("DebugView","Press Once");

if(DebugOn) 	_TRACE("#, Message = " +msgid );
//..... more of your code and  then 

if(DebugOn) 	_TRACE("#, Message of = " + close);

or with ParamToggle()

 TraceOn =   ParamToggle("DebugView 2", "No|Yes" ); 
if(TraceOn ) 	_TRACE("#, Message2 = " + msgid);
3 Likes

Thanks tor the tip, PanoS. But I removed all _Trace() functions !

1 Like