Algo Trading Bots 6.0.4
11 August 2026
This release has upgrade notes. Read them before updating — they describe behaviour changes that need your attention.
Algo Trading Bots v6.0.4
Release Date: August 11, 2026 Tags: BOTS, ORDERS, MARKETPLACE, MONEY, SETTINGS, RISK, RELIABILITY, PERFORMANCE, DATABASE, BUG-FIXES
Overview
A correctness release for the strategy marketplace, the engine's safety switches and the money figures this add-on publishes, carrying a backend performance pass with it.
Two of the repairs move money. A marketplace purchase whose platform fee failed part-way through paid the seller the full price on top of the fee that had already been credited, and a bot deployed from a purchased strategy ran the seller's current configuration rather than the one the buyer paid for. Neither is corrected retrospectively, so read Upgrade Notes and check what you already have.
The trading-mode and order-type switches on the settings screen now do what they say. If live trading or paper trading is switched off on your install today, updating will stop the bots trading in that mode right now — that is the one decision this release asks you to make before you start it.
Requires Core v6.6.3.
Update Instructions
pnpm updatorNo setting changes are required and no data is rewritten. Two database indexes are created the first time the backend starts afterwards, and four switches you may already have set now take effect — see Upgrade Notes.
Upgrade Notes
Purchases already made may have paid the seller more than the buyer paid
The platform fee on a marketplace purchase credits the Super Admin's wallet before it writes the revenue record, and both happen inside the purchase. A failure between the two — a lock-wait timeout on a busy install is the realistic one — left the credit standing while the purchase read it as "no fee was taken" and paid the seller the whole price. On a 100 USDT strategy at the default 10% fee, the buyer paid 100 and 110 left the platform. From this release the purchase refuses and rolls back instead, so nothing half-lands.
- If you charge a marketplace platform fee, reconcile past completed purchases: compare what each seller was credited against the fee recorded on the same purchase. A purchase that recorded no fee while your revenue records show one for the same moment is one of these.
- Nothing is corrected automatically. Any adjustment is yours to make.
A bot built from a purchased strategy may be running a configuration nobody sold
A purchase freezes the strategy as it was bought, and deployment was meant to use that frozen copy. It used the seller's live row instead, so a seller who edited their strategy after the sale changed what every later buyer deployed — including edits that had gone back into the review queue and had been approved by nobody. A strategy bought to trade 25 a day could deploy trading 5,000 a minute against the buyer's real balance, while the purchase record still said it had sold the original.
- Existing bots keep whatever configuration they were created with. Review the running bots on your install that were created from a marketplace purchase, and compare each one's configuration against the strategy the buyer actually paid for.
- Deployments made from this release forward use the purchased copy.
Switching a trading mode off now stops the bots already running in it
Until now the live and paper switches only refused new starts. Bots already running carried on trading, and the periodic sync put any that fell out of the engine straight back in.
- Check Admin → Trading Bot → Settings before you update. If live trading or paper trading is switched off, every bot running in that mode will be stopped within about thirty seconds of the backend coming back up.
- A stopped bot is written as stopped, so it does not return on the next pass, and its audit trail records that it was stopped. The audit entry does not say which switch did it — the switch is named in the backend log, so that is where to look to tell one of these apart from a bot a user stopped.
- Both switches ship on, and an install that has never touched them sees no change.
Switching market or limit orders off now blocks the trades it names
The same is true of the two order-type switches: they were saved, read back and enforced nowhere.
- If market orders are switched off, every strategy that trades at market — DCA, indicator, trailing-stop and rules-driven custom bots — will be refused the trades it proposes, strategy-driven exits included, and will say so on the bot's screen. Stop-loss and take-profit exits are on a separate path and still execute.
- If limit orders are switched off, grid bots cannot place their rungs.
- Both ship on. Switch either off only as a deliberate incident measure, and expect open positions to sit until you switch it back.
The first backend start after updating takes longer
Two indexes are added to the bot tables, and they are created by the schema sync when the backend starts — not by anything you run.
- On an installation with a long order history, that first start takes noticeably longer than a normal one while the indexes are built. Let it finish; every later start is normal again.
- Nothing else is required from you, and no bot data is rewritten.
Added
Indexes on the bot and bot-order tables
- Added an index over a bot's orders by bot and status together. Three things the engine asks several times every five seconds for every running bot — which orders are still working, how much capital is committed, whether a price level already has an order on it — filter on exactly that pair. Until now it could narrow by the bot or by the status but not both, so each of those reads still walked every order that bot has ever placed, filled and cancelled alike.
- Added an index for the pending-exit drain. The sweep that looks for live bots still owing an exit runs every thirty seconds and could previously narrow no further than "live", which on a busy installation is every bot there is.
A suspended strategy can no longer be deployed
- Added a check on deployment for a strategy you have pulled from the marketplace. Suspending one used to remove it from the storefront and from nothing else, so every earlier buyer could keep spinning up new live bots on it indefinitely. Existing bots are untouched — this stops new ones being created.
Changed
The engine's thirty-second sync
- Changed the periodic sync to read the rows of the bots it is holding in one query per five hundred bots, rather than one query each. On a host running two hundred bots that is one read every thirty seconds instead of two hundred, and it is the same work the sync always did.
- Changed nothing about how a bot is evicted or stopped. Both decisions that destroy something — dropping a bot whose record has gone, and stopping one an operator has stopped elsewhere — still re-read that bot's own row first, so a bot started while the sweep was in flight is never torn down on stale information. The refresh side also refuses to install an older snapshot of a bot over a newer one the trading loop has already written.
Trading fee lookups
- Changed the market's own taker rate to be reused for ten seconds rather than read from the database on every tick of every bot with working orders. The window is deliberately short because that rate is recorded onto each trade and reserves the headroom an order is placed with: an admin who edits a market's fee sees bot trades priced at the new rate within a couple of ticks. A market that does not exist yet is never cached, so a market created while bots are running is picked up immediately rather than being pinned to the fallback rate.
Marketplace strategy ratings
- Changed the hourly job that recalculates each published strategy's star rating to total every strategy's reviews in a single query instead of one query per strategy. The averages and review counts are unchanged, and only approved reviews count towards them, exactly as before.
Fixed
The trading-mode switches were not a stop, only a door
An operator who switches live trading off is asking for real-money trading to stop. What the switch actually did was refuse new starts and resumes. Bots that were already running kept ticking and kept placing orders, and the thirty-second sync re-adopted any that were evicted, because neither consulted the setting — so during an incident the only way to halt live trading was to find and stop two hundred bots by hand.
- Fixed both mode switches so the engine acts on the bots it is already holding: it refuses to adopt a bot whose mode is switched off, and stops the ones already resident, writing the stop to the bot and filing its stop in the audit trail. The switch that caused it is named in the backend log rather than on the audit entry.
- Applies to the live and paper switches only. A bot with an unrecognised mode is left alone deliberately — this is a stop for the two modes it names, not a list of the only modes allowed, and refusing anything else would quietly stop bots nobody disabled.
The market and limit order switches were enforced nowhere
The platform-wide order-type gate keyed off the order type the strategy had declared, and the one place that reaches the gate never passed it along. So the setting saved, read back and displayed correctly while every bot on the install carried on trading exactly as before — an operator switching market orders off during a thin-book incident watched every bot that trades at market, DCA and custom rules included, cross the spread on the very next five-second tick.
- Fixed the gate by forwarding the declared order type, so both switches now refuse the trades they name and the refusal is shown on the bot with its reason.
- The gate stands aside for a signal that carries no order type at all rather than refusing it. Every strategy this add-on ships declares one, so none of them is exempt — the allowance exists so a switch can never refuse a trade it was unable to classify.
A purchased strategy deployed whatever the seller was selling that day
A purchase stores a frozen copy of the strategy as sold, and deployment was supposed to build the bot from it. It preferred the seller's live row and read a configuration field that a live row does not have, so the frozen copy was never consulted and the seller's current settings won every time. A seller can replace that configuration at any point — doing so sends the strategy back into the review queue — so what the buyer's bot deployed had been reviewed by nobody, against the buyer's real balance, while the purchase record still named the version that was sold.
- Fixed the deployment source: the copy frozen at purchase is now the authority, and the live row is used only for purchases made before that copy was recorded.
- Fixed a purchase that no longer resolves to any deployable strategy being turned into a bot the engine cannot run. It is now refused with a message.
A marketplace purchase could pay the seller the full price on top of the platform fee
Fee collection reports the same empty answer for two entirely different things: "there was never a fee to take" and "I credited the Super Admin and then failed". The purchase read both as the first. Because the failure leaves the credit standing — the database undoes the statement that failed, not the whole purchase — a fee that broke half-way meant the Super Admin kept 10, the seller was paid the full 100 the buyer had been debited, and both were committed together.
- Fixed the split by deciding before the call whether a fee is genuinely due, from the fee amount and who the Super Admin is, rather than inferring it from the result afterwards. A fee that was due but did not complete now aborts the purchase and takes the phantom credit back with it, and the buyer is not charged at all.
- Unchanged for every purchase where no fee was ever going to be taken — no fee configured, no Super Admin, or the buyer being the Super Admin. The seller is still paid the gross in those cases, and the record still says no fee was charged.
No strategy in the marketplace ever showed a review
The public reviews endpoint asked for the reviewer under a name the data model does not use, which made it fail on every single call for every strategy. Buyers saw a reviews panel that never loaded, and none of the moderation behind it could reach anyone: approving a review published nothing and rejecting one hid nothing, because nothing was ever served.
- Fixed the endpoint, so reviews load and the moderation queue finally has an effect — only approved reviews are served, and a rejected one stays invisible.
- Fixed the shape the reviewer comes back in at the same time. Repairing the query alone would have published a blank name beside every review, because the card reads a single display name and the stored record holds the parts separately.
A strategy's page failed to open, on some installations and not others
Everything a strategy carries beyond its name — its tags, the markets it was written for, the configuration a buyer's bot starts from — is stored as structured data. Whether the platform handed that back as structure or as unread text depended on which database an installation runs, and nothing in an operator's own configuration told the two apart. On an installation that got the text form the screens reading it did not degrade, they broke: every strategy page in the marketplace failed to open, tags or no tags, because an empty list is still text; the admin page for the same strategy broke the same way, on its tags and on the panel naming its markets; and a buyer sent on from a purchase to deploy landed on a trade screen for a market that does not exist.
- Fixed every place this add-on stores structured data — a bot's configuration, a strategy's listing, a purchase, a trade's context and the audit trail — so the same shape is served on every installation, whatever database is underneath.
- The frozen copy a purchase holds is one of those places, which makes this the other half of the deployment repair above: that repair reads the frozen copy, and where the copy came back as text there was nothing in it to read, so deployment fell straight back to the seller's current configuration exactly as before. On the affected installations both halves are needed before a buyer deploys what they paid for.
- Installations running MariaDB are the ones this affected. On MySQL the same screens already worked, which is why it went unseen for so long, and those installations see no difference.
Every trade in a bot's history was shown as a zero, in green
The bot detail page read its profit column from a field the trade rows do not carry. An absent number rendered as 0.00, tinted green as a gain — so a bot's whole trade history looked like a flat line of break-even wins, losing trades included, whatever it had actually done.
- Fixed the trade history to read the profit recorded on the trade. Losses now show as losses.
A paid strategy's performance figures were zeros for every strategy on the platform
The four cards on the tab a buyer uses to decide whether to pay — total trades, win rate, average profit and maximum drawdown — were read from a set of figures the platform does not publish, and an absent figure rendered as zero. Every strategy in the marketplace, brand new or long proven, advertised 0 trades, a 0.0% win rate, 0.00% average profit and no drawdown, so they all looked identical and all looked like failures.
- Fixed the tab to show a dash where the platform has no measurement, while a genuine zero still shows as zero. Per-strategy performance is not something the platform tracks yet, and a dash is the honest rendering of that until it does.
The reported money totals added different currencies together, and simulated profit to real profit
A bot's profit, volume and allocated capital are all denominated in the quote asset of the pair it trades, and a paper bot's profit is simulated — it moves nothing and credits nobody. Three places added them all into one running total regardless. A live ETH/BTC bot down 0.004 BTC beside a paper BTC/USDT bot up 1,200 simulated USDT was reported as a profit of 1,199.996, a number in no currency at all, with nothing in the answer saying which unit it was in or that nearly all of it was imaginary. The percentages built on those totals were wrong for the same reason. How far each one reached differs: the bot dashboard's own web page regroups by mode and quote asset in the browser, so there the blended total was published to the API and to every non-web client reading it, while the allocation view and the seller's earnings page rendered the blended figure on screen as it stood.
- Fixed the bot dashboard totals. Profit and volume now cover real bots only and name the unit they are quoted in; where a user genuinely trades more than one quote asset the amounts are priced into USD before they are added, and any currency this install has no rate for is listed alongside the figure rather than counted as zero. The simulated totals are reported separately instead of being folded in, and each bot in the list now carries its own quote asset.
- Fixed the allocation view, which labelled every bot's capital as USDT no matter what it was in — half a bitcoin and five thousand tether came back as
5000.5USDT, and the utilisation and profit percentages were ratios of that mixture. Capital is now grouped under the asset it is actually held in, paper allocation is reported apart from real allocation, and the summary names its own unit. - Fixed a seller's earnings. What a seller had earned on a 40 USDT listing and on a 0.004 BTC listing was added straight together into
36.0036and rendered with a dollar sign — understating the seller by roughly the entire bitcoin sale — and the six-month earnings chart plotted the same mixture month by month. Both are now grouped by the currency each sale was charged in and, where a seller has been paid in more than one, priced into USD before they are summed. The total names its unit, and each listing carries the currency it was priced in.
Two paper bots on the same currency could erase one another's trades
A paper balance belongs to a user and a currency, not to a bot, so two paper bots trading the same quote asset share one balance. The entry side of a paper trade locked that balance before writing it; the exit side did not. When the two landed in the same five-second batch, the exit read the balance from before the entry was written and saved its own answer over the top — the entry's debit simply vanished, and the balance drifted upward by exactly one entry every time the two collided. No real money is involved, but a paper run exists to produce a balance you can believe.
- Fixed the exit to settle under the same lock the entry takes, so the two can no longer overwrite each other.
- Fixed a failed paper settlement stranding the bot's capital. If the settlement could not start — a busy database under fan-out is the way it happened — the position was already recorded as closed while the capital behind it was never released, and the bot lost that headroom permanently. The failure is now contained and logged, and the capital is released either way.
The order engine logged a database state instead of the reason an order stopped
Everything the engine records for a single order is one piece of database work. A check that refused an order undid that work itself before raising its reason, and the error handler behind it then tried to undo the same work a second time. The second attempt fails, and it fails before the handler ever reaches the reason it was handed — so what an operator found in the log was the state that piece of work had been left in, naming no cause and suggesting no remedy, for a bot that had stopped for a reason the engine knew perfectly well.
- Fixed the order engine reporting its own refusals and its own errors. Three places in it raised a specific reason and had it replaced by a transaction message before it was logged, which left an operator investigating a stopped bot with nothing to investigate.
- Fixed the same handler in the strategy marketplace and the background job, where a failure at the moment work was committed was reported as a transaction state rather than as the error that actually occurred.