DEXBot2 uses four independent grid recalculation triggers to keep the trading grid synchronized with market conditions and bot funds.
| Mechanism | Trigger | Config | Location | Scope |
|---|---|---|---|---|
| AMA Delta | Market price moved significantly | AMA_DELTA_THRESHOLD_PERCENT |
general.settings.json |
Global (all bots) |
| Grid Price Offset | Offset changes the resolved grid reference | gridPriceOffsetPct |
bots.json |
Per-bot |
| RMS Divergence | Grid state diverged from blockchain | RMS_PERCENTAGE |
general.settings.json |
Global (all bots) |
| Regeneration | Available funds exceed threshold | GRID_REGENERATION_PERCENTAGE |
constants.js |
Per-side (BUY/SELL) |
Each mechanism is independent and can be configured separately. They don't interfere with each other.
Applies a signed percentage offset to the resolved gridPrice reference, producing an effective center for grid bound calculations without altering the raw reference price.
Why it matters: Lets you shift the grid center relative to the active reference price without changing the underlying reference source.
File: profiles/bots.json (per bot)
{
"gridPrice": "market",
"gridPriceOffsetPct": 1.5
}Parameters:
gridPrice: Can bepool,market,ama/ama1..ama4, a positive number, ornullgridPriceOffsetPct: Signed percentage offset (-10to+10). Formula:effectiveCenter = resolvedGridPrice × (1 + offset/100). Set to0to disable the offset
initializeGrid()resolves the currentgridPricereference using the configured mode- For non-AMA references (
pool,market, numeric, ornull -> startPrice) it appliesgridPriceOffsetPctdirectly before deriving min/max bounds - For AMA references,
price_adapterpersists the effective AMA center soinitializeGrid()can consume it without double-applying the offset - Recalculation for non-AMA offsets is handled independently by whichever workflow updates the bot and writes
recalculate.<botKey>.trigger(for example dynamic-weight updates)
Offset Trigger:
[price_adapter] Offset change detected for <botKey>: 0% → 1.5%
Monitors the Adaptive Moving Average (AMA) of market prices. When the AMA center price deviates from the last recorded center by more than the threshold, a grid recalculation is triggered.
Why it matters: Big market moves require repositioning the grid to stay centered around the new market price.
File: profiles/general.settings.json
{
"MARKET_ADAPTER": {
"AMA_DELTA_THRESHOLD_PERCENT": 1
}
}Parameters:
AMA_DELTA_THRESHOLD_PERCENT: Percentage change in AMA center that triggers grid reset- Default:
1% - Range:
0.1to50.0(configurable via CLI and bot editor) - Example: If set to
1, grid recalculates when AMA center moves ±1% from last center
- Default:
node market_adapter/price_adapter.js --deltaPercent 2File: profiles/bots.json (per bot)
{
"ama": {
"enabled": true,
"erPeriod": 10, // Efficiency Ratio lookback period (candles)
"fastPeriod": 2, // Fast smoothing period for trending markets
"slowPeriod": 30 // Slow smoothing period for choppy markets
}
}AMA Parameters:
enabled: Whether to track AMA and trigger grid resets (true/false)erPeriod: How many candles to look back for trend detection- Higher values: More stable, slower response (ER=107 very stable)
- Lower values: More responsive, catches quick moves (ER=15 very responsive)
- Default:
10(balanced)
fastPeriod: Smoothing constant for trending markets- Lower = faster response
- Default:
2(most responsive)
slowPeriod: Smoothing constant for choppy/sideways markets- Higher = more lag, filters noise
- Default:
30(conservative)
- Market Adapter (
market_adapter/price_adapter.js) runs continuously - Loads per-bot AMA configuration (or uses defaults)
- Calculates AMA from 1h candlestick closing prices
- Tracks the AMA center price for each bot
- When
|currentAMA - lastRecordedAMA| >= AMA_DELTA_THRESHOLD_PERCENT:- Creates
market_adapter/state/recalculate.<botKey>.triggerfile - DEXBot's main loop detects the trigger and calls
Grid.recalculateGrid()
- Creates
- Last recorded center is updated after recalculation
Increase threshold (e.g., 1% → 2%) if:
- Grid recalculates too frequently (excessive churn)
- Market is choppy/sideways
- You want fewer but larger recalculations
Decrease threshold (e.g., 1% → 0.5%) if:
- Grid reacts too slowly to market moves
- Market is trending strongly
- You want grid to follow price more closely
Compares the calculated grid (in-memory state) with the persisted grid (blockchain state). When divergence exceeds a threshold, the grid is regenerated to re-sync with reality.
Why it matters: Order fills, rotations, and fee deductions cause the persisted grid to drift from the calculated state. RMS divergence detects and corrects this drift.
File: profiles/general.settings.json
{
"GRID_LIMITS": {
"GRID_COMPARISON": {
"RMS_PERCENTAGE": 14.3
}
}
}Parameters:
RMS_PERCENTAGE: Root Mean Square divergence threshold- Default:
14.3%(balanced) - Range:
0to100+ - Set to
0to completely disable RMS checks
- Default:
| RMS % | Avg Error | Description |
|---|---|---|
| 0 | N/A | Disabled (no checks) |
| 4.5% | ~1.0% | Very strict (frequent regens) |
| 9.8% | ~2.2% | Strict |
| 14.3% | ~3.2% | Default (balanced) |
| 20.1% | ~4.5% | Lenient |
| 31.7% | ~7.1% | Very lenient |
| 44.7% | ~10% | Extremely lenient |
- Grid Engine (
modules/order/grid.js) calculates the ideal grid state - Compares with the actual blockchain grid state after fills/rotations
- Computes RMS divergence metric:
RMS = √(mean of ((calculated - persisted) / persisted)²) - If
RMS >= RMS_PERCENTAGE:- Triggers
Grid.updateGridOrderSizes()to regenerate - Calls
compareGrids()to report detailed divergence metrics
- Triggers
- Grid sizes are recalculated and updated
Increase threshold (e.g., 14.3% → 20%) if:
- Grid regens too frequently (expensive due to order updates)
- You're comfortable with more fill/rotation drift
- Blockchain latency causes false positives
Decrease threshold (e.g., 14.3% → 9.8%) if:
- You want tighter sync with blockchain state
- You want to catch drift earlier
- Fill/rotation operations are causing noticeable size errors
Disable (set to 0) if:
- You want to rely ONLY on AMA triggers (Issue #5: RMS Divergence Check Disabling)
- You want to prevent automatic grid regeneration from divergence alone
- You manually trigger grid regens via other mechanisms
Monitors available funds on each side (BUY/SELL). When accumulated fill proceeds exceed the threshold, the grid is regenerated to re-utilize the freed capital.
Why it matters: As orders fill, capital is freed. Regeneration re-allocates this capital back into active orders instead of leaving it idle.
File: modules/constants.js
GRID_LIMITS: {
GRID_REGENERATION_PERCENTAGE: 3,
// ...
}Parameters:
GRID_REGENERATION_PERCENTAGE: Percentage of allocated capital that can accumulate as free funds before triggering regen- Default:
3% - Example: 20 orders × 100 BTS = 2000 BTS grid
- Triggers when availableFunds ≥ 60 BTS (3% of 2000)
- Allows ~3 fill-proceeds to accumulate before resize
- Default:
- OrderManager tracks available funds per side (BUY and SELL separately)
- Allocated capital = number of active orders × size per order
- When
availableFunds / allocatedCapital × 100 >= GRID_REGENERATION_PERCENTAGE:- Triggers
Grid.recalculateGrid()on that side only - Recalculates order sizes to incorporate freed capital
- Maintains asymmetric fills (BUY fills don't trigger SELL regen)
- Triggers
- After regen, available funds are re-allocated into active orders
Increase threshold (e.g., 3% → 5%) if:
- Grid regens too frequently
- You want to accumulate more fill proceeds before rebalancing
- You prefer stability over utilization
Decrease threshold (e.g., 3% → 1%) if:
- You want to re-utilize capital more aggressively
- You have high fill rates
- Available funds sitting idle bothers you
On the first cycle for a bot (when no centerPrice baseline exists yet), the price adapter must persist the initial AMA center to disk before advancing the in-memory baseline. This ordering prevents a dangerous split where the order engine reads stale or missing snapshot data while the adapter believes it succeeded.
processBot()detects the bootstrap case (centerPriceis not yet set).- It calls
writeBotGridPriceCenter(botKey, referencePrice, { amaCenterPrice, gridPriceOffsetPct, effectiveCenterPrice }). - If the write succeeds (returns anything other than
false): the in-memory baseline (centerPrice,amaCenterPrice,gridPriceOffsetPct,lastGridResetAt) is set. No recalculation trigger is created during bootstrap — the bot enters normal delta-comparison behavior on subsequent cycles. - If the write fails (returns
false): the in-memory baseline is left unset,triggerSuppressedReasonis set toama_center_persist_failed, and no recalculation trigger is written. The next cycle will retry the bootstrap from scratch.
Bootstrap persistence failure:
triggerSuppressedReason: 'ama_center_persist_failed'
If this appears repeatedly, check:
- disk space and write permissions on the state directory
- whether
writeBotGridPriceCenteris correctly wired in the service deps
All four mechanisms are independent:
- Grid price offset is triggered by offset parameter changes
- AMA delta is triggered by market price changes
- RMS divergence is triggered by blockchain state drift
- Regeneration is triggered by available funds
- They can all fire at the same time without conflict
- All four are INDEPENDENT — no priority or suppression
- Each can be configured and disabled separately
- Disabling one doesn't affect the others
Example 1: Conservative Grid (Tight Sync)
{
"MARKET_ADAPTER": {
"AMA_DELTA_THRESHOLD_PERCENT": 0.5 // Respond to small moves
},
"GRID_LIMITS": {
"GRID_REGENERATION_PERCENTAGE": 1, // Regen frequently
"GRID_COMPARISON": {
"RMS_PERCENTAGE": 9.8 // Tight divergence tolerance
}
}
}- Grid follows price closely
- Frequently re-utilizes freed capital
- Detects drift early
- Cost: More recalculations, higher blockchain fees
Example 2: Aggressive Grid (High Utilization)
{
"MARKET_ADAPTER": {
"AMA_DELTA_THRESHOLD_PERCENT": 2 // Ignore minor moves
},
"GRID_LIMITS": {
"GRID_REGENERATION_PERCENTAGE": 5, // Regen sparingly
"GRID_COMPARISON": {
"RMS_PERCENTAGE": 0 // Disable RMS checks
}
}
}- Grid adapts only to major price moves
- Accumulates capital before rebalancing
- No automatic drift correction
- Benefit: Fewer recalculations, lower fees
Example 3: Balanced (Default)
{
"MARKET_ADAPTER": {
"AMA_DELTA_THRESHOLD_PERCENT": 1 // Standard threshold
},
"GRID_LIMITS": {
"GRID_REGENERATION_PERCENTAGE": 3, // Moderate utilization
"GRID_COMPARISON": {
"RMS_PERCENTAGE": 14.3 // Balanced tolerance
}
}
}- Default for most bots
- Balances responsiveness and cost
- Good for: Normal trading conditions
Check the logs for these messages:
AMA Delta Trigger:
[price_adapter] Creating trigger: market_adapter/state/recalculate.<botKey>.trigger
RMS Divergence Trigger:
[grid] compareGrids: RMS divergence 18.5% exceeds threshold 14.3%
[grid] updateGridOrderSizes: Regenerating grid due to divergence
Regeneration Trigger:
[grid] Grid regeneration triggered: available 3.2% >= threshold 3.0%
❌ Don't: Set RMS_PERCENTAGE to 0 without understanding consequences
- Grid will never auto-correct blockchain state drift
- Manual intervention required if major divergence occurs
❌ Don't: Set AMA_DELTA_THRESHOLD_PERCENT too low (< 0.5%)
- Grid regens constantly (high fees)
- May never stabilize in choppy markets
❌ Don't: Disable AMA without disabling AMA configuration
- Orphaned
amasection in bots.json - Confusing configuration state
✅ Do: Understand your market's volatility
- Trending markets: Lower AMA_DELTA_THRESHOLD_PERCENT
- Choppy markets: Raise both AMA_DELTA_THRESHOLD_PERCENT and RMS_PERCENTAGE
- High-fill markets: Lower GRID_REGENERATION_PERCENTAGE
✅ Do: Monitor grid recalculation frequency
- Log output should show recalcs are balanced
- Adjust thresholds if too frequent or too rare
- Issue #5: RMS Divergence Check Disabling — Ability to set
RMS_PERCENTAGE: 0to disable checks - Feature: AMA Integration — Future work to use AMA prices in grid calculations (not just triggers)
- Issue #1: Fund Validation Bug — Fixed validation logic for order batch placement
modules/constants.js— Default configuration valuesmodules/account_bots.js— Bot configuration schema and defaultsmarket_adapter/price_adapter.js— AMA calculation and trigger logicmodules/order/grid.js— RMS divergence check and grid comparisonmodules/order/manager.js— Regeneration threshold logicprofiles/general.settings.json— User-editable configurationprofiles/bots.json— Per-bot configuration including AMA