Order Transaction cost rules

OrderTransactionCostRule fires when an order/trade is calculated. In addition to the Shared API, these rules can inspect the triggering order and trade.

This is the only rule type with an AllowManualCosts flag. Manual costs are added after the costs are calculated. So if the manual costs are 5, and the rule calculated 15, the total costs will be 20.

Cost Collection Orders will never have costs. For a cost collection order, no LUA expression is evaluated as the costs are always 0. (by design)

order

The order that triggered the rule.

Method Returns Description
order.type() OrderType The order’s type.
order.isBuy() boolean Buy-like order (Buy, AssetMix, ObligatedBuy, ObligatedAssetMixBuy).
order.isSell() boolean Sell-like order (Sell, AssetMixSell, ProRata).
order.isSwitch() boolean Switch-like order (Switch, InternalSwitch, IndirectSwitch, Rebalance).
order.isRefund() boolean Refund order.
order.isReInvest() boolean ReInvest order.
order.isCorrection() boolean Correction order.
order.isPeriodical() boolean Whether the order is a periodical (recurring) order.

trade

The trade within the order.

Method Returns Description
trade.type() TradeType Buy or Sell.
trade.calculatePercentage(p) number The cost for a percentage p of the trade, using the exact same gross/net grossing-up logic the legacy cost engine uses. Prefer this over multiplying trade.value() yourself as it has net/gross amount calculation logic built-in
trade.value() number The traded value, resolved from the trade’s gross/net and unit/value basis.

Enums

The following enum globals are available for comparisons against order.type() / trade.type():

Global Members
OrderType Buy, Sell, IndirectSwitch, Switch, ProRata, ReInvest, Refund, AssetMix, Rebalance, Correction, InternalSwitch, AssetMixSell, ObligatedBuy, ObligatedAssetMixBuy
TradeType Buy, Sell
TradeExecutionType ValueBased, UnitBased (trade.executionType() does not exist yet)
TradePriceType Gross, Net (trade.priceType() does not exist yet)

Examples

-- 0.25% of the traded value
return trade.calculatePercentage(0.25)
-- Flat 2.50 on buys, nothing on sells
if order.isBuy() then
  return 2.5
end
return 0
-- Tiered: 0.2% on trades over 10,000, otherwise 0.3%
if trade.value() > 10000 then
  return trade.calculatePercentage(0.2)
end
return trade.calculatePercentage(0.3)
-- Different percentages for every order type
buyPercentage = 0.2
periodicalBuyPercentage = 0.3
sellPercentage = 0.1
periodicalSellPercentage = 0.2
switchBuyPercentage = 0.01
switchSellPercentage = 0.01
refundPercentage = 0.5
reinvestPercentage = 0.05

if order.isBuy() then
    if order.isPeriodical() then
        return trade.calculatePercentage(periodicalBuyPercentage)
    else
        return trade.calculatePercentage(buyPercentage)
    end

elseif order.isSell() then
    if order.isPeriodical() then
        return trade.calculatePercentage(periodicalSellPercentage)
    else
        return trade.calculatePercentage(sellPercentage)
    end

elseif order.isSwitch() then
    if trade.type() == TradeType.Buy then
        return trade.calculatePercentage(switchBuyPercentage)
    end

    if trade.type() == TradeType.Sell then
        return trade.calculatePercentage(switchSellPercentage)
    end

elseif order.isRefund() then
    return trade.calculatePercentage(refundPercentage)

elseif order.isReInvest() then
    return trade.calculatePercentage(reinvestPercentage)
end

return 0

Back to top

© 2026 Pengine.