Gross Exposure Flattener
What it does
Reduces a fixed matched slice from both long and short when total gross exposure is high, balanced enough, and already profitable.
Why this exists
In hedge mode, long and short positions are independent. A healthy pair can grow both sides at the same time, which increases gross exposure even when net exposure stays small.
The flattener trims that matched exposure without trying to rebalance the pair. It places one reduce-only order on the long side and one reduce-only order on the short side, using the same base quantity for both sides.
For all config fields, see Config Reference.
How it works
The check runs from the short-mode grid after normal exposure evaluation.
| Check | Passes when |
|---|---|
| Gross exposure | longUsd + shortUsd is at or above maxGrossPositionUsd * triggerGrossPct |
| Balance | abs(longUsd - shortUsd) / grossUsd is at or below maxNetToGrossPct |
| PnL | Combined unrealised PnL meets minCombinedUnrealisedPnlUsd |
| Slice PnL | Estimated PnL for the fixed slice meets minEstimatedFlattenPnlUsd |
| Minimum position | The slice would leave both sides above the reserve quantity |
| Confirmation count | consecutiveTriggers qualifying checks have happened in a row |
| Cooldown | No flatten attempt started for this symbol during cooldownMinutes |
| Profit Lock | Profit Lock is not controlling the symbol |
When all checks pass:
- The bot pauses that symbol.
- It cancels all open orders for the symbol.
- It refreshes positions and rebuilds the fixed slice plan.
- It reduces the larger-notional side first.
- If the first leg lands exactly on target, it reduces the other side by the same quantity.
- It refreshes positions, clears stale rebalancer state after a position change, and restarts the symbol.
If the initial cancel-all step fails, the bot aborts before placing reduce orders and logs an error. If the first reduce leg does not reach its exact target, the second leg is not placed.
Fixed slice behavior
flattenUsdPerSide is a USD value, not a target gross exposure.Example:
flattenUsdPerSide = 1000 and mark price is $2. The bot computes a base quantity of 500, rounds it down to the exchange qtyStep, then tries to reduce 500 base units from the long position and 500 base units from the short position.The slice is not shrunk to fit a small side. If the configured slice would fully close a side or breach
minPositionQty, the attempt is skipped.Configuration placement
You can place the block globally under
defaults:"defaults": {
"flattener": {
"enabled": false,
"triggerGrossPct": 0.5,
"flattenUsdPerSide": 1000,
"maxNetToGrossPct": 0.25,
"minCombinedUnrealisedPnlUsd": 25,
"minEstimatedFlattenPnlUsd": 5,
"consecutiveTriggers": 2,
"cooldownMinutes": 15
}
}
The feature stays off until you set
enabled to true. Only enabled short-mode rows can trigger it. Long-mode rows can inherit the block from defaults, but they do not evaluate it.Pair-level opt-in works too:
"pairs": {
"HYPEUSDT": [
{ "enabled": true, "mode": "long" },
{
"enabled": true,
"mode": "short",
"flattener": { "enabled": true, "flattenUsdPerSide": 500 }
}
]
}
Interaction with other features
| Feature | Interaction |
|---|---|
| Exposure Guard | Supplies the exposure evaluation points that can trigger checks. |
| Profit Lock | Skips while Profit Lock controls the symbol. |
| Rebalancer | Cleared after a position-changing flatten so the restarted grid uses fresh baselines. |
| Short Inventory Refill | Independent trigger path. Both use the same symbol lock, so they do not mutate the same symbol at the same time. |
| Short Size Guard | May change future short order size after the symbol resumes. |
| Hedge Throttle | May widen future short spacing after the symbol resumes. |
Tuning tips
| If you want... | Adjust this |
|---|---|
| Earlier checks | Lower triggerGrossPct or lower maxGrossPositionUsd carefully |
| Smaller trims | Lower flattenUsdPerSide |
| More balanced trims | Lower maxNetToGrossPct |
| More profit confirmation | Raise minCombinedUnrealisedPnlUsd or minEstimatedFlattenPnlUsd |
| Fewer attempts | Raise consecutiveTriggers or cooldownMinutes |
Troubleshooting
| Symptom | Likely cause |
|---|---|
| Feature never triggers | Gross exposure is below threshold, PnL is too low, net-to-gross is too high, cooldown is active, Profit Lock is active, or enabled: false at the effective scope |
| It skips near a tiny position | The fixed slice would breach the reserve quantity or fully close a side |
| Only one reduce order happens | The first reduce leg did not reach its exact target, so the second leg was not placed |
| Cancel failure stops the attempt | Initial cancel-all failure is treated as a hard abort before reduce orders |
| No effect after a config edit | Save the config, then restart the bot so it runs with the new settings |