How the Market Works
DynaTrade is not a fixed-price shop. It is an economic engine where prices respond to real player activity and update in scheduled cycles.
This page explains how trades become pressure, how pressure becomes price movement, and how the runtime stays safe across restarts and crashes.
Philosophy
DynaTrade is built around a simple principle: calibrate the market, not the player.
The plugin reacts to market-level conditions — item volume, demand pressure, volatility, and participation patterns. It adapts sensitivity, widens spreads when conditions are uncertain, and classifies market states so operators can understand what is happening.
It does not assign hidden trust scores, label players as suspicious, build long-term player reputation, or automatically punish players based on trading behavior.
The market adapts. Players are not profiled.
The cycle model
Every price change in DynaTrade passes through a cycle. A cycle:
- Collects all buy and sell activity since the last cycle
- Calculates price movement for each affected item
- Applies mean reversion to items that drifted from baseline
- Saves the updated market state to disk
- Applies the new prices to the live runtime
Prices do not change after every trade. They change when the next cycle runs.
In the current public technical-preview docs, the most important operator-facing fact is that pricing remains cycle-based rather than click-by-click. You can force an immediate cycle with /dt cycle.
The three-price model
Each tradable item has three visible values:
| Value | What it means |
|---|---|
| Market price | The internal reference price used by the economic model |
| Buy price | What players pay: market price * (1 + buy-spread) |
| Sell price | What players receive: market price * (1 - sell-spread) |
Example with default spreads (buy-spread: 0.06, sell-spread: 0.10):
Market price: 100
Buy price: 106
Sell price: 90
The spread creates friction so players cannot instantly buy and sell the same item for profit.
How trades create market pressure
When a player buys or sells an item, the trade becomes a market signal for that item and direction.
Signals are held in the transaction buffer until the next cycle runs. At cycle time, DynaTrade compares accumulated buy and sell volume and calculates market pressure (deltaM).
- High buy volume relative to sell volume creates upward pressure
- High sell volume relative to buy volume creates downward pressure
- Balanced activity creates low net pressure
DynaTrade also considers how many unique players contributed to the dominant side of that pressure in the current cycle.
This is base pricing behavior in the current line:
- if valid participation data exists, pressure is normalized automatically
- if participation data is missing or invalid, raw pressure is preserved exactly
This lets DynaTrade distinguish one-player bulk volume from broader server participation with the same total volume.
The current line also includes active participation reach. Once the cycle already has full participation confidence, DynaTrade can soften that confidence when the same unique-player count represents only a small share of the currently active economy participants.
Separately, the current runtime can also compute a momentum signal from recent completed cycles. That signal does not change the core market price by itself. It is used only by the optional quote-adjustment layer when that layer is enabled.
The pricing pipeline
For each item with pending signals, the cycle runs this pipeline:
1. Calculate market pressure (deltaM) from buy/sell volume vs. reference volume (vref).
The effective (calibrated) VREF is used when calibration is active and warmed up.
2. Normalize pressure by current-cycle player participation, when participation data exists
3. Optionally refine full-confidence participation using active participation reach
4. Project the new price based on sigma and adjusted deltaM
5. Apply mean reversion toward the configured baseline
6. Apply the max variation cap for that cycle
7. Clamp the result to the configured floor and ceiling
8. Settle exactly on the baseline if the result lands very close to it
Items without new trade activity in a cycle can still be processed for mean reversion if their price remains displaced from baseline.
Key tuning parameters
| Parameter | What it controls |
|---|---|
sigma |
How strongly the item reacts to buy/sell pressure |
vref |
Reference volume for pressure scaling |
player-aware-pressure.target-participation-players |
Unique players on the dominant side needed for full participation confidence |
player-aware-pressure.min-participation-factor |
Minimum factor used when participation exists but is still below target |
player-aware-pressure.active-participation-reach.enabled |
Turns the active-reach refinement on or off without disabling base player-aware normalization |
player-aware-pressure.active-participation-reach.min-active-reach-factor |
Lower bound for the active-reach factor |
player-aware-pressure.active-participation-reach.active-participant-floor |
Minimum active-economy participant count considered by the reach layer |
player-aware-pressure.active-participation-reach.active-participant-cap |
Maximum active-economy participant count considered by the reach layer |
player-aware-pressure.active-participation-reach.reach-weight |
How strongly active reach influences the final factor |
gamma |
Mean reversion strength |
max-var-percent |
Maximum allowed price movement in one cycle |
min-price-factor |
Price floor relative to base price |
max-price-factor |
Price ceiling relative to base price |
calibration.enabled |
Master switch for VREF calibration |
calibration.smoothing-alpha |
EMA smoothing factor for observed VREF |
calibration.max-effective-vref-multiplier |
Upper bound for effective VREF relative to configured VREF |
calibration.min-samples |
Minimum observed cycles before calibration activates |
calibration.blend-weight |
Blend between configured and smoothed observed VREF |
These can be set globally, per category, or per item. See Configuration for details.
VREF calibration
VREF calibration adjusts the volume reference used in pressure calculation so that high-volume items are not dominated by normal activity. DynaTrade tracks observed trade volume per item across cycles, applies EMA smoothing, and blends the result with the configured VREF.
Key behaviors:
- calibration updates only during pricing cycles with trade activity
- calibrated state is persisted in
market-state.ymland restored after restart or reload - the first cycles after startup use configured VREF until enough samples accumulate
- if calibration state is missing or invalid, configured VREF is always used as a safe fallback
/dt itemshows a-- Calibration --section with state, VREF ratio, sample counts, and cap status
Risk, volatility, and adaptive spread
Once an item has enough calibration data, DynaTrade also derives an item-level risk score and volatility profile from aggregate market behavior. Thin markets are dampened so a small amount of activity does not overstate uncertainty.
The resulting adaptive-spread bonus can adjust the live buy and sell quotes within the configured maximum. It is used only when calibration is enabled, the item is calibrated, valid risk data exists, and the momentum quote-adjustment layer is not active. In every other case, DynaTrade uses the configured spread unchanged.
/dt item <item> exposes the risk score, volatility profile, thin-market/dampening state, adaptive-spread bonus, maximum bonus, active flag, and the reason the adjustment is active or suppressed.
Mean reversion and idle recovery
DynaTrade uses two mechanisms to pull prices back toward baseline:
Mean reversion
Applies every cycle and gently pulls the price toward its base value.
Idle recovery
Applies a stronger correction when an item has been inactive for several cycles and is still meaningfully displaced from baseline.
Idle recovery tuning:
idle-cycle-thresholdidle-deviation-percent-thresholdidle-deviation-absolute-thresholdinactive-gamma
Market state persistence
After every cycle, DynaTrade writes state to disk:
| File | Purpose |
|---|---|
market-state.yml |
Authoritative current market state |
pending-signals.yml |
Snapshot of accepted but not yet processed signals |
pending-signals.log |
Append-only accepted trade journal for recovery |
cycle-checkpoint.yml |
Write-ahead record of a prepared cycle result |
trade-runtime-state.yml |
Staged runtime retry state for prepared trades |
pending-deliveries.yml |
Unresolved purchase deliveries, sell-compensation item obligations, and pending Vault credits |
Do not edit these files manually.
market-state.yml in the current line can also persist bounded analytics history,
calibration state, and momentum windows used by the runtime.
Recovery and crash safety
On startup, DynaTrade:
- Loads the last confirmed
market-state.yml - Checks for a prepared
cycle-checkpoint.yml - Restores accepted trade signals from
pending-signals.logwhen needed - Converts stale item-delivery or Vault-credit
IN_PROGRESSrecords toMANUAL_REVIEW
If market-state.yml is critically invalid, DynaTrade does not silently reset the economy. It blocks startup of the market runtime instead.
Malformed auxiliary recovery files are quarantined instead of crashing the runtime.
Full flow
Player buys or sells
-> trade is validated and admitted
-> runtime apply is queued with a per-player UUID lock
-> Vault and Bukkit-side apply completes
-> the applied trade is journaled durably
-> signal enters the in-memory transaction buffer
-> next cycle drains the buffer
-> pricing pipeline runs per item
-> cycle checkpoint is written
-> market-state.yml is updated
-> in-memory prices are replaced
-> checkpoint and auxiliary pending state are cleaned up
Summary
- Prices update in cycles, not per transaction
- Trade volume becomes market pressure
- Player participation can soften that pressure automatically
- Active participation reach can refine fully-saturated participation
- Recovery preserves accepted trades across restarts and crashes
- Ambiguous item delivery or Vault credit is held for manual review instead of automatic duplication
See Trade Consistency and Recovery for the rationale and accepted trade-offs.