0bps

Strategy vault / Other

Iceberg Order Buy

Iceberg order means that when investors conduct large-amount transactions, in order to avoid excessive impact on the market, the large order is automatically split into multiple orders, and small orders are…

JavaScriptOther
Author
Zero
Complexity
Intermediate · 86 lines
Parameters
8

Iceberg order means that when investors conduct large-amount transactions, in order to avoid excessive impact on the market, the large order is automatically split into multiple orders, and small orders are automatically placed based on the current latest buy/sell price and the price strategy set by the customer. When the previous order is fully completed or the latest price deviates significantly from the current order price, the order is automatically re-entered. example: If the single average fluctuation points are set to 10 then: The quantity of each order is 90% to 110% of the average value of a single order, and the order price is the latest buying price * (1 - order depth). A new order will be placed after all the previous orders are completed. When the latest transaction price is more than the order depth * 2 from the order, the order will be automatically canceled and the order will be re-entrusted. Stop placing orders when the strategy's total trading volume equals its total order quantity. Stop the order when the latest transaction price of the market is higher than the highest bid price, and resume the order when the latest transaction price is lower than the highest bid price again.

Parameters

NameDefaultWhat it controls
TotalBuyNet10000Total purchase amount (yuan))
AvgBuyOnce100Average quantity per purchase (CNY))
FloatPoint10Single average floating point number (percentage)
EntrustDepth0.1Order depth (percentage)
MaxBuyPrice20000Highest buy price (yuan)
Interval1000Retry on failure (milliseconds))
MinStock0.0001Minimum transaction volume
LoopIntervaltruePrice polling interval (seconds)

Source JavaScript



function CancelPendingOrders() {
    while (true) {
        var orders = _C(exchange.GetOrders);
        if (orders.length == 0) {
            return;
        }

        for (var j = 0; j < orders.length; j++) {
            exchange.CancelOrder(orders[j].Id);
            if (j < (orders.length-1)) {
                Sleep(Interval);
            }
        }
    }
}

var LastBuyPrice = 0;
var InitAccount = null;

function dispatch() {
    var account = null;
    var ticker = _C(exchange.GetTicker);
    // The distance between the latest transaction price and the order exceeds the order depth.*2Automatically cancel the order and place a new one
    if (LastBuyPrice > 0) {
        // Order not completed
        if (_C(exchange.GetOrders).length > 0) {
            if (ticker.Last > LastBuyPrice && ((ticker.Last - LastBuyPrice) / LastBuyPrice) > (2*(EntrustDepth/100))) {
                Log('Deviated too much, Latest transaction price:', ticker.Last, 'order price', LastBuyPrice);
                CancelPendingOrders();
            } else {
                return true;
            }
        } else {
            account = _C(exchange.GetAccount);
            Log("Buy order completed, Total cost:", _N(InitAccount.Balance - account.Balance), "Average buying price:", _N((InitAccount.Balance - account.Balance) / (account.Stocks - InitAccount.Stocks)));
        }
        LastBuyPrice = 0;
    }
    
    
    // Order price is the latest buy1price*(1-Commission Depth)
    var BuyPrice = _N(ticker.Buy * (1 - EntrustDepth/100));
    if (BuyPrice > MaxBuyPrice) {
        return true;
    }
    
    if (!account) {
        account = _C(exchange.GetAccount);
    }


    if ((InitAccount.Balance - account.Balance) >= TotalBuyNet) {
        return false;
    }
    
    var RandomAvgBuyOnce = (AvgBuyOnce * ((100 - FloatPoint) / 100)) + (((FloatPoint * 2) / 100) * AvgBuyOnce * Math.random());
    var UsedMoney = Math.min(account.Balance, RandomAvgBuyOnce, TotalBuyNet - (InitAccount.Balance - account.Balance));
    
    var BuyAmount = _N(UsedMoney / BuyPrice);
    if (BuyAmount < MinStock) {
        return false;
    }
    LastBuyPrice = BuyPrice;
    exchange.Buy(BuyPrice, BuyAmount, 'Cost: ', _N(UsedMoney), 'Last transaction price', ticker.Last);
    return true;
}

function main() {
    if (exchange.GetName().indexOf('Futures_') != -1) {
        throw "Spot only supported";
    }
    CancelPendingOrders();
    InitAccount = _C(exchange.GetAccount);
    Log(InitAccount);
    if (InitAccount.Balance < TotalBuyNet) {
        throw "Insufficient account balance";
    }
    LoopInterval = Math.max(LoopInterval, 1);
    while (dispatch()) {
        Sleep(LoopInterval * 1000);
    }
    Log("All commissions completed", _C(exchange.GetAccount));
}

Published by Zero on the FMZ strategy square · last modified 2020-03-08. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.

Build this with AgenKit

A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.

in Claude Code, Cursor, Codex & 4 more
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/Iceberg-Order-Buy.md
  1. npx agenkit install engineering-kit in your project
  2. Paste the command into your agent and approve each phase
  3. Get tests, backtest, risk controls and a paper-trading switch

Understand it first

Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.

Related specs

esc

Try , , or .

↑↓ move↵ open