Module H · Real-Time, Alerts & Automation - Chapter 35

Automating Orders with OpenAlgo

Send your AFL signals to OpenAlgo to place real orders - button and signal-based automation, in sandbox first.

RealtimeOpenAlgo
What you'll learn
  • ·AmiBroker to OpenAlgo
  • ·The order API call
  • ·Button trading module
  • ·Signal-based auto orders
  • ·Sandbox (analyzer) mode first
  • ·Safety & confirmation

An alert tells you a signal fired. This chapter closes the last gap - turning that signal into an actual order, automatically. The bridge that makes it safe and broker-agnostic is OpenAlgo: a free, open-source platform you run on your own computer. It exposes one clean, consistent order API at http://127.0.0.1:5000, and behind the scenes it translates that single API into whatever brokerage account you connect. Your AFL only ever speaks to OpenAlgo; OpenAlgo handles the messy, broker-specific details.

Good to know

InternetOpenURL is AmiBroker's window to the outside world. The very same call that sends a Telegram message can hand an order to OpenAlgo - which then talks to whatever broker you use.

That design is a gift to a system trader. The exact same InternetOpenURL mechanism you used to message Telegram last chapter can now send an order request - and because everything routes through one local endpoint, you write your automation once and never rewrite it if you change brokers. But first, the rule that must come before any of it.

Sandbox first, always

OpenAlgo has a sandbox trading mode - the analyzer mode - where orders are fully simulated and nothing ever reaches the exchange. This is where you live until you have watched the system place dozens of correct simulated orders, on the right symbol, in the right direction, with no duplicates.

Heads up

Keep OpenAlgo in sandbox trading (analyzer mode) while you build and test. Every order you fire is simulated, so a coding mistake costs you nothing but a log line. Going live - switching analyzer off - must be a slow, deliberate, fully-conscious decision you make after the system has behaved perfectly in sandbox, never something that happens by accident because you forgot to check a toggle.

With that rule front and centre, let us wire AmiBroker to OpenAlgo.

The order API call

OpenAlgo's place-order endpoint accepts a small JSON packet: your API key, a strategy name, the symbol and exchange, the action, the product and the quantity. The API key is your credential - read it from a placeholder so you never paste a real key into shared code.

apikey   = "OPENALGO_API_KEY";          // PLACEHOLDER - paste your real key locally
host     = "http://127.0.0.1:5000";     // OpenAlgo runs on your own machine
endpoint = host + "/api/v1/placeorder";

strategy = "Amibroker";
symbol   = "RELIANCE";
exchange = "NSE";
product  = "MIS";
quantity = 1;

To send an order we build the JSON body, set a header, and POST it with InternetPostRequest. Wrapping it in a function keeps every call identical - we just pass the action, "BUY" or "SELL".

function PlaceOrder(action, quantity)
{
    postData =
        "{\"apikey\": \""   + apikey   + "\", " +
         "\"strategy\": \"" + strategy + "\", " +
         "\"symbol\": \""   + symbol   + "\", " +
         "\"action\": \""   + action   + "\", " +
         "\"exchange\": \"" + exchange + "\", " +
         "\"pricetype\": \"MARKET\", " +
         "\"product\": \""  + product  + "\", " +
         "\"quantity\": \"" + quantity + "\"}";

    InternetSetHeaders("Content-Type: application/json\r\n");
    _TRACE("Sending: " + postData);          // log every request

    ih = InternetPostRequest(endpoint, postData);
    if (ih)
    {
        response = "";
        while ((line = InternetReadString(ih)) != "") response += line;
        _TRACEF("OpenAlgo response: %s", response);
        InternetClose(ih);
    }
}

Notice the _TRACE lines. Every order request and its response is written to AmiBroker's log window, so you always have a paper trail of exactly what was sent and what came back - invaluable when something looks off.

Manual button trading: click to send

The friendliest first automation is a panel of on-chart buttons you click yourself - buy, sell, exit, close-all. There is no auto-firing here, so it is the perfect way to confirm your OpenAlgo connection works before trusting it with signals. The author's button module draws each button with the Gfx functions and watches the mouse:

RequestTimedRefresh(1, False);

LBClick = GetCursorMouseButtons() == 9;     // left button held
MouseX  = Nz(GetCursorXPosition(1));
MouseY  = Nz(GetCursorYPosition(1));

procedure DrawButton(Text, x1, y1, x2, y2, colFrom, colTo)
{
    GfxSelectFont("Verdana", 9, 700);
    GfxSetBkMode(1);
    GfxGradientRect(x1, y1, x2, y2, colFrom, colTo);
    GfxDrawText(Text, x1, y1, x2, y2, 32 | 1 | 4 | 16);
}

DrawButton("BUY", 20, 100, 80, 150, colorGreen, colorGreen);
buyClicked = MouseX >= 20 AND MouseX <= 80 AND MouseY >= 100 AND MouseY <= 150 AND LBClick;

// fire once per physical click, not on every refresh while held
if (buyClicked AND StaticVarGet("btnBuy") == 0)
{
    PlaceOrder("BUY", quantity);
    StaticVarSet("btnBuy", 1);
}
else if (!buyClicked) StaticVarSet("btnBuy", 0);

The same static-variable trick from the alerts chapter appears again: a held mouse button refreshes many times, so we latch a flag to guarantee exactly one order per click. Add matching buttons for SELL and a "CLOSE ALL" that hits OpenAlgo's closeposition endpoint, and you have a complete manual dashboard.

Note

OpenAlgo also ships a dedicated AmiBroker order module, so you do not have to hand-write the JSON if you prefer not to. Whether you use the module or the raw InternetPostRequest shown here, the request that travels to http://127.0.0.1:5000 is identical - the platform is the same either way.

Signal-based auto orders

Once the buttons prove the pipe works, you can let signals pull the trigger. The structure is the alert pattern from the last chapter with PlaceOrder swapped in for Say - and the same once-per-bar suppression, because an auto-trader that double-fires is far worse than a duplicate Telegram message.

Buy  = Cross(EMA(Close, 10), EMA(Close, 20));
Sell = Cross(EMA(Close, 20), EMA(Close, 10));

EnableAlgo = ParamList("Algo Mode", "Disable|Enable", 0);   // OFF by default

static_name_ = Name() + GetChartID() + Interval(2);
lastBar      = StrFormat("%0.f", LastValue(BarIndex()));

if (EnableAlgo == "Enable")
{
    // --- fresh BUY, once per bar ---
    if (LastValue(Buy) AND StaticVarGetText(static_name_ + "buyBar") != lastBar)
    {
        PlaceOrder("BUY", quantity);
        StaticVarSetText(static_name_ + "buyBar", lastBar);
    }

    // --- fresh SELL, once per bar ---
    if (LastValue(Sell) AND StaticVarGetText(static_name_ + "sellBar") != lastBar)
    {
        PlaceOrder("SELL", quantity);
        StaticVarSetText(static_name_ + "sellBar", lastBar);
    }
}

Two deliberate safeguards are built in. EnableAlgo defaults to Disable, so the system never trades until you consciously flip it on - the software equivalent of a safety catch. And the bar-fingerprint check means a signal that stays true all bar still places exactly one order. Combined with OpenAlgo's sandbox mode, you now have three independent layers of protection between a stray idea and a real fill.

Key idea

Three safety layers, all on at once while you learn: (1) OpenAlgo in sandbox/analyzer mode so fills are simulated, (2) EnableAlgo defaulting to Disable so nothing fires until you choose, and (3) once-per-bar dedupe so a signal can never place a second order on the same bar. Remove them one at a time, deliberately, only when each has earned your trust.

Ready-made OpenAlgo modules

You do not have to build all of this from scratch. OpenAlgo publishes a library of ready-made AmiBroker modules - drop-in formulas for the most common automation jobs, each with its own setup guide. Use them as-is, or read them to learn the patterns. Every link below opens that module's documentation, where the install steps and the API-key field are spelled out:

Setup and data

  • Amibroker Plugin - the data and order bridge that connects AmiBroker to OpenAlgo; install this first.
  • AmiQuotes - bulk-download historical data into AmiBroker's database through OpenAlgo.

Manual (button) trading

Automated execution

Turning spot/futures signals into options

Scanning and alerts

Tip

These modules are the fastest safe route to live automation: start with the Button Trading Module (Modern) to confirm your OpenAlgo connection with manual clicks, then graduate to an automated module like the SmartOrder Chart Module - always in sandbox (analyzer) mode first. Each page lists exactly what to install and where to paste your API key.

Going live, carefully

When the system has placed clean simulated orders for long enough that you trust it completely, going live is a single conscious step: turn OpenAlgo's analyzer mode off, then flip EnableAlgo to Enable. Start with the smallest possible quantity, watch the first real fills against your _TRACE log, and scale up only once reality matches the simulation. This is education, not advice - the responsibility for every live order is yours.

Tip

Keep your sandbox and live runs on separate strategy names (the strategy field). That way OpenAlgo's order book clearly separates your test orders from your real ones, and you can audit each independently.

Try it yourself

  • Install and start OpenAlgo, confirm it answers at http://127.0.0.1:5000, and leave it in sandbox/analyzer mode.
  • Add the button panel to a chart and click BUY - watch the simulated order appear in OpenAlgo and the response land in AmiBroker's log.
  • Attach the signal-based block to your EMA crossover and let it fire simulated orders for a full session with EnableAlgo on but analyzer still on.
  • Read every _TRACE response and check the symbol, action and quantity are exactly what you intended before you ever consider going live.

Recap

  • OpenAlgo runs locally at http://127.0.0.1:5000 and turns one clean order API into orders for whatever broker you use.
  • AFL sends orders with the same internet functions as alerts - InternetPostRequest (or the OpenAlgo module) with a small JSON body and your apikey.
  • A button module lets you click to send orders - the ideal way to prove the connection before automating.
  • Signal-based orders reuse the once-per-bar dedupe so a signal places exactly one order.
  • Keep three safety layers - sandbox mode, an Algo toggle defaulting to off, and dedupe - and treat going live as a slow, deliberate choice.

Next we step back and look at the whole journey - what you can now build, where to go deeper, and the habits that turn a hobby into a craft.