← Back to Home

PulseXBot Documentation

Complete reference for PulseXBot v7.0 — Phase 7: Pyramid Sizing · Compound Mode · Freefall Protection · Capital Stages · Climb Protection · RSI Dynamic Sizing · Volume Monitoring · Multi-Timeframe RSI · Event-Driven Recalibration · Stuck Deploy. Covers every configuration setting, the full trading engine, all safety systems, the web dashboard, and the terminal interface. All platforms: Windows, macOS, Linux.

Quick Start

PulseXBot is a self-contained trading bot — download the zip for your operating system, edit two text files, and run the launcher. No additional software to install, no command-line tooling required.

Downloads

🪟
Windows
Windows 10 / 11 · Unzip and run · No installation needed
PulseXBot-Setup.zip
🍎
macOS
Intel + Apple Silicon (M1/M2/M3/M4) · Run Start-PulseXBot.sh
PulseXBot-Setup-Mac.zip
🐧
Linux
Ubuntu · Debian · Fedora · x64 · Run Start-PulseXBot.sh
PulseXBot-Setup-Linux.zip
  1. 1
    Download for your platform

    Click the download card above for your operating system.

  2. 2
    Extract the zip to a folder

    Right-click → Extract All. Example: C:\PulseXBot\ on Windows, ~/PulseXBot/ on Mac/Linux.

  3. 3
    Create your .env file

    Copy .env.example in the bot folder, rename the copy to .env, open in any text editor, fill in your values. See .env Setup.

  4. 4
    Configure your pairs

    Open corebot-config.js in any text editor. Set which PulseChain tokens to trade and how much PLS to allocate per pair. Leave other values as "AUTO" the first time.

  5. 5
    Start the bot

    Windows: double-click Start-PulseXBot.bat
    macOS / Linux: open a terminal in the bot folder and run ./Start-PulseXBot.sh

  6. 6
    Open the dashboard

    Navigate to http://localhost:5555 in your browser to see live prices, positions and P&L.

Always use a dedicated trading wallet — not your main wallet. Only deposit funds you are comfortable putting at risk. The bot has full access to the wallet's funds.

Requirements

🪟 Windows
  • Windows 10 or 11 (64-bit)
  • No other software needed
🍎 macOS
  • macOS 12 or later
  • Intel or Apple Silicon
  • No other software needed
🐧 Linux
  • Any modern x64 distro
  • Ubuntu, Debian, Fedora
  • No other software needed

Resources

ResourceDetail
RAM~150 MB per running pair
Disk~100 MB for the bot, ~50 MB for logs (rotates automatically)
NetworkAlways-on internet, low-latency to PulseChain RPC
WalletHot wallet funded with PLS (and optionally PXB tokens for licensing)
BrowserAny modern browser for the dashboard (Chrome, Firefox, Safari, Edge)

Installation

🪟 Windows

  1. 1
    Download

    PulseXBot-Setup.zip from pulsexbot.com

  2. 2
    Extract to a folder

    Right-click the zip → Extract All. Example: C:\PulseXBot\

  3. 3
    Create your .env file

    Copy .env.example → rename to .env → open in Notepad → fill in your private key. See .env Setup below.

  4. 4
    Edit corebot-config.js

    Open in Notepad or VSCode. Set your trading pairs and PLS budget.

  5. 5
    Start the bot

    Double-click Start-PulseXBot.bat — it launches the trading bot.

  6. 6
    Open dashboard

    Go to http://localhost:5555 in your browser.

C:\PulseXBot\
  ├── PulseXBot.exe           ← the bot (double-click or run via .bat)
  ├── Start-PulseXBot.bat     ← recommended launcher — double-click to start
  ├── corebot-config.js       ← your trading config (edit this first)
  ├── .env.example            ← copy and rename to .env
  ├── .env                    ← (you create this — holds your private key)
  ├── .lic                    ← trial/license tracker (do not delete)
  ├── README.md               ← quick start guide
  ├── PulseXBotlogo.png       ← bot logo
  ├── dai-grid-state.json     ← state file per pair (created on first run)
  ├── dai-grid-logs/          ← log folder per pair (created on first run)
  │   ├── trades.log
  │   ├── errors.log
  │   ├── trades.csv
  │   └── daily-summary.log
  └── state-backups/          ← daily state backups (created automatically)
The dashboard is built into the bot — there is no separate HTML file to open. Once the bot is running, simply navigate to http://localhost:5555 in your browser to access the live dashboard.

🍎 macOS (Intel + Apple Silicon)

  1. 1
    Download

    PulseXBot-Setup-Mac.zip — works on all Macs (Intel and M1/M2/M3/M4)

  2. 2
    Unzip

    Double-click the zip in Finder — it extracts automatically. Move the folder to your preferred location.

  3. 3
    Open Terminal in the folder

    Right-click the folder → "New Terminal at Folder", or in Terminal: cd ~/PulseXBot

  4. 4
    Create your .env file

    cp .env.example .env
    Then edit .env in any text editor (Notes, TextEdit, VSCode).

  5. 5
    Edit corebot-config.js

    Open in any text editor and set your trading pairs.

  6. 6
    Start the bot

    ./Start-PulseXBot.sh
    This makes the binary executable, removes the macOS quarantine flag automatically, and launches the bot.

  7. 7
    Open dashboard

    Go to http://localhost:5555 in your browser.

The first time you run the launcher, macOS may ask you to confirm you want to run an app from an unidentified developer. The launcher script handles the quarantine flag automatically — just confirm if Finder prompts.

🐧 Linux

  1. 1
  2. 2
    Extract

    unzip PulseXBot-Setup-Linux.zip -d ~/PulseXBot && cd ~/PulseXBot

  3. 3
    Create .env

    cp .env.example .env && nano .env

  4. 4
    Edit corebot-config.js

    nano corebot-config.js

  5. 5
    Start the bot

    ./Start-PulseXBot.sh

  6. 6
    Keep running 24/7

    For VPS or unattended operation, use screen or tmux to keep the bot running after disconnecting your SSH session.

.env File Setup

The .env file holds your PulseChain wallet private key and RPC settings. It must be in the same folder as the bot binary.

💡
Easiest way: The zip includes a .env.example file. Copy it, rename the copy to .env (remove the .example part), then open it in your text editor and fill in your values.

Your .env file should contain exactly this:

# PulseChain RPC endpoints
RPC_URL=https://rpc.pulsechain.com
RPC_URL_BACKUP=https://rpc-pulsechain.g4mm4.io

# Your trading wallet private key — KEEP THIS SECRET
PRIVATE_KEY=YOURPRIVATEKEYHERE
🚨
Never share your private key with anyone. Never upload your .env file to GitHub or any public place. Use a dedicated trading wallet — not your main wallet. The bot needs the private key to sign transactions on PulseChain.

How to export your private key from MetaMask

  1. Click the account icon in MetaMask
  2. Go to Settings → Security & Privacy
  3. Click Export Private Key
  4. Enter your MetaMask password
  5. Copy the key exactly — 64 characters (or 66 with the leading 0x)

Available RPC Endpoints

URLNotes
https://rpc.pulsechain.comOfficial — use as primary
https://rpc-pulsechain.g4mm4.ioCommunity — good backup
https://pulsechain.publicnode.comPublicNode alternative
https://rpc.pulsechain.g4mm4.ioAlternative
💡
Always set both RPC_URL and RPC_URL_BACKUP. If the primary fails 3 times in a row, the bot automatically switches to the backup and keeps trading. It also polls the primary every 5 minutes and switches back when it's healthy.

Config File Setup

Once your .env file is ready, open corebot-config.js in any text editor (Notepad, Notepad++, VSCode, TextEdit, nano). This is where you tell the bot which tokens to trade and how much PLS to use.

💡
First time? You only need to set TOTAL_PLS and the token fields for each pair. Leave everything else as "AUTO" — the bot will calibrate all other parameters automatically on first run.

The only settings you must fill in

SettingWhat to putExample
TOKEN_ADDRESSThe contract address of the token you want to trade (from PulseX or PulseScan)0xefD766cCb38EaF1dfd701853BFCe31359239F305
SYMBOLShort name of the token — used in logs and dashboard onlyDAI
TOTAL_PLSHow much PLS to allocate to this trading pair. Must be in your wallet before starting.4600000
TOKEN_DECIMALSThe token's decimal places — check PulseScan. Most tokens use 18.18

Everything else — leave as "AUTO"

All other settings like BUY_OFFSETS, SELL_LEVELS, TRAIL_DISTANCE_PCT, RESERVE_PLS, SLIPPAGE_PERCENT and more are set to "AUTO" by default. The auto-tune system measures live market conditions on first start and calculates optimal values for each. You do not need to touch these.

Adding a trading pair — minimal example

Inside the PAIRS array in corebot-config.js, each pair looks like this:

{
  TOKEN_ADDRESS:  "0xefD766cCb38EaF1dfd701853BFCe31359239F305",  // token contract address
  SYMBOL:         "DAI",            // display name
  TOKEN_DECIMALS: 18,               // from PulseScan token page
  TOTAL_PLS:      4600000,          // PLS budget for this pair
  RISK_PROFILE:   "AUTO",           // AUTO, CONSERVATIVE, BALANCED, or AGGRESSIVE
  BUY_OFFSETS:    "AUTO",           // leave as AUTO — auto-tune sets this
  SELL_LEVELS:    "AUTO",           // leave as AUTO
  RESERVE_PLS:    "AUTO",           // leave as AUTO
  // ... all other settings left as "AUTO"
}
You can add multiple pairs by adding more blocks inside the PAIRS array, separated by commas. Each pair needs its own TOTAL_PLS budget — make sure your wallet has enough PLS to cover all pairs combined before starting.
🚨
Never put your private key in corebot-config.js. The private key belongs only in the .env file. The config file contains no sensitive information and can be shared safely.

First Run

The first time you launch, each pair goes through these steps:

  1. 1
    Wallet check

    The bot reads your PLS and token balances and logs them.

  2. 2
    Router approval

    If the wallet has never sold this token via the PulseX router, an unlimited approval transaction is sent (one-time, ~1.5K PLS gas). Subsequent runs skip this.

  3. 3
    Auto-tune calibration

    The bot samples price for ~3 minutes to measure volatility (ATR), liquidity, and the prevailing trend. It then derives optimal grid offsets, sell targets, trail distance, slippage tolerance, and reserve sizing.

  4. 4
    Grid seed

    Buy levels are placed at calculated offsets below the current price. The grid is now live.

  5. 5
    Dashboard online

    Open http://localhost:5555 in your browser. Each pair appears as a card with live price, position, and trade log.

Once trading begins, the bot fills levels as price drops, sells them in two tiers as price rises, and recycles each level back to WAITING when fully sold. After every level on a pair has sold at least once, the cycle completes and the grid reseeds at the new market price.


How Grid Trading Works

A grid bot places a series of buy orders at fixed offsets below the current market price and matching sell orders above each buy. When price drops to a buy offset, the bot purchases tokens. When price rises to that level's sell target, the bot sells those tokens for a profit. The cycle repeats indefinitely, capturing money from natural up-and-down price movement.

PulseXBot's grid is multi-level: typically 3 to 5 main levels spaced from -0.8% to -10% below the seed price (auto-tuned per token based on volatility). Each level holds a portion of the pair's TOTAL_PLS budget. Levels operate independently — L1 can be filled and trailing while L3 is still waiting for a deeper drop.

Lifecycle of a single level

StatusMeaning
WAITINGTrigger price not yet reached. Bot is monitoring.
FILLEDBuy executed. Tokens are held; sell tiers are armed.
CLOSEDAll sell tiers complete. Level recycles to WAITING immediately after the final sell confirms.
RESERVEDeep-DCA reserve level — held back, only activates in deep oversold conditions.

Partial Tier Sells (30% / 70% split)

When a level fills, two sell tiers are created. The first tier sells 30% of the position immediately at a low fixed target above the buy price (locks in early profit). The second tier holds the remaining 70% with a trailing stop, riding price upward until a retracement triggers the exit.

This split solves a fundamental tradeoff: pure fixed-target selling exits too early on big moves; pure trailing exits too late when price pops then dumps. Selling 30% fixed and 70% trailing captures both — guaranteed early profit plus extended upside.

Tier-1 fixed sell

Auto-tuned to ~65% of the main sell percentage. For example, if the main sell is +3.35%, tier 1 fires at +2.18%. Sells 30% of the position, no trailing.

Tier-2 trailing sell

Triggers at the main sell percentage (e.g. +3.35%). Once armed, it tracks the highest price seen and only fires when price retreats by the configured trail distance (typically 0.8%–1.35%).

Buy gas is charged once, on whichever tier sells first. Tier-2 trail sells show buy 0 in the gas breakdown because tier 1 already paid the original buy cost.

Trailing Stop Sells

The trailing stop is the engine behind tier 2 (and the optional global trail). When price climbs above the trigger threshold, the trail "arms." From that moment forward, every tick checks if price made a new high. If yes, the high is updated and the stop moves up to high × (1 - TRAIL_DISTANCE_PCT/100). The stop never moves down. When price retreats to the stop, the bot sells.

Trade-off

A wider trail distance lets the price run further before stopping out (catches bigger moves) but gives back more from the peak. A tighter distance locks in profit closer to peak but exits earlier on small wiggles. Auto-tune picks the value based on each token's volatility (ATR%).

Example

L1 buy at 9.443
Tier 2 armed at 9.737 (+3.09% above buy)
Trail distance = 0.85%
Price climbs to peak 9.823 → trail high = 9.823, trail stop = 9.740
Price retreats to 9.741 → trail stop hit → sell at +3.16% gross

Deep-DCA Reserve Levels

Deep-DCA is an emergency capital tool. A portion of each pair's budget (auto-tuned, typically 10–18%) is held back from the main grid and assigned to three reserve levels at deeper offsets — for example, -12%, -18%, -26.4% below the seed price.

Reserve levels stay in RESERVE status, dormant, until all three conditions are met:

When all three trigger, reserve levels activate to WAITING status. They behave exactly like main levels from there — fill on price drop, sell on rise, recycle. The triple-condition gate prevents reserves from deploying during ordinary volatility; they only fire during meaningful crashes.

💡
Reserve levels not activating during a cycle is normal. They're insurance, not a regular profit driver. Cycles complete based on main-level activity only — see Cycle Completion.

Auto-Shift Grid

If the price climbs above the seed price by a configurable threshold (auto-tuned, typically 1–3.5%) and no levels are currently filled, the bot reseeds the entire grid at the new higher price. This re-anchors the bot to current market rather than leaving the grid stranded below where price is now trading.

Auto-shift only fires when zero levels are filled, by design. Once positions are held, the bot will not chase the price up — it waits for them to sell at their original targets. There is no symmetrical "shift down" — falling price is what fills the grid in the first place, and the deep-DCA reserves cover the bottom.

Stuck-Level Reduction

When a filled level holds for an extended period without selling (the "stuck" condition), the bot gradually reduces its sell targets to encourage exit. Defaults: starts after 6 hours stuck, ramps linearly down to a floor of +1.5% over the following 24 hours.

Hours stuckEffect on sell target
0–6 hNo reduction. Original target.
6–30 hLinear interpolation from original target down to STUCK_REDUCE_MIN_PCT.
30+ hHeld at STUCK_REDUCE_MIN_PCT floor (default 1.5%).

Stuck reduction also tightens the trail distance when STUCK_TRAIL_TIGHTEN is enabled (default on), making the trail exit faster on small reversals rather than waiting for big moves.

The 1.5% minimum is calibrated to be above typical slippage, so reduced targets remain profitable after fees and gas. The loss guard provides the absolute floor — even a fully reduced target won't sell below cost basis.

Cycle Completion

A cycle completes when:

When a cycle completes, the bot logs 🎉 All levels sold!, increments the cycle counter, and reseeds the grid at the new current price. Reserves that never activated do not block cycle completion — they are insurance, not part of the regular cycle.


Auto-Tune Calibration

Auto-tune measures real market conditions for each pair and derives optimal parameters automatically. It runs:

Calibration takes ~3 minutes. During this time the bot samples price, computes ATR (volatility), reads pool liquidity, and selects parameters. It never trades during calibration.

What auto-tune sets

Parameter groupParameters setDriven by
GridBUY_OFFSETS, level count, RESERVE_PLSATR volatility + risk profile
Sell & TrailSELL_LEVELS (pct + portions), TRAIL_TRIGGER_PCT, TRAIL_DISTANCE_PCT, TRAIL_SELL_NOTIFY_PCTATR volatility
RiskSELL_LOSS_GUARD_PCT, STOP_LOSS_PCTRisk profile
SlippageSLIPPAGE_PERCENT, SLIPPAGE_ALERT_PCT, MIN_LIQUIDITY_USDPool liquidity
Deep-DCADEEP_DCA_BUDGET_PCT, DEEP_DCA_OFFSETS, DEEP_DCA_RSI_MAXATR volatility + risk profile
TimingBUY_COOLDOWN_MS, AUTO_SHIFT_PCT, AUTO_SHIFT_COOLDOWN_MS, RESEED_OFFSET_PCT, STAGGER_DELAY_MSATR volatility
Regime indicatorsDCA_BIAS_EXTRA_PCT, MA_PERIOD, RSI_PERIOD, ATR_PERIOD, ATR_ADAPTIVE_SPACING, ATR_LOW/HIGH_VOL_PCT, ATR_MIN/MAX_SPACING_MULT, HIGH_VOL_SKIP_DEEP_LEVELSRisk profile
Stuck recoverySTUCK_REDUCE_START_HOURS, STUCK_REDUCE_MIN_PCT, STUCK_TRAIL_TIGHTENRisk profile
Freefall protectionFREEFALL_DROP_PCT, FREEFALL_CANDLES, FREEFALL_RECOVERY_PCTATR volatility
Capital stagesCAPITAL_STAGE_THRESHOLDS, CAPITAL_STAGE_MULTIPLIERSRisk profile
Climb protectionCLIMB_SENSITIVITY_PCT, CLIMB_EXTRA_GAIN_PCTATR volatility
RSI sizingRSI_OVERSOLD_LVL, RSI_OVERBOUGHT_LVL, RSI_OVERSOLD_MULT, RSI_OVERBOUGHT_MULTRisk profile
Pyramid + compoundLEVEL_WEIGHTS, COMPOUND_PCTRisk profile
Smart partial sellsMIN_VIABLE_PARTIAL_MULTFixed default (3×)
ATR-adaptive sellsATR_ADAPTIVE_SELLS, sell target scaling, trail distance scalingATR volatility (same thresholds as spacing)
Stuck deploySTUCK_DEPLOY_HOURSRisk profile

Calibration takes ~3 minutes per pair. The bot never trades during calibration. Filled positions are fully preserved — they are reattached to the new grid by closest trigger-price match after calibration completes.

Auto-Tune Modal (Dashboard)

Click the ✎ AUTO-TUNE button in the dashboard to open the live override panel. Every calibrated parameter is shown with its current value and can be overridden two ways:

The CALIBRATE button on a token page forces an immediate recalibration for that pair. Useful after a large market move or if you want the bot to re-measure conditions on demand.

The seedGrid preservation system ensures that when the daily 24-hour calibration fires while positions are held, all filled levels are snapshotted before the new grid is built and reattached afterwards. No position data is ever lost across a recalibration.

Market Regimes

The bot tracks six regimes based on price relative to a 20-period moving average, current RSI, and ATR volatility:

RegimeConditionsBot behavior
GRIDPrice near MA20, normal volatilityStandard grid trading. All levels active.
TREND_UPPrice significantly above MA20, risingBuys active but bot is cautious on deep levels. Grid may auto-shift upward.
TREND_DOWNPrice below MA20 by >0.5%, RSI < 50Buys still active. Deep-DCA reserves can activate if RSI also below threshold.
DCARSI below DEEP_DCA_RSI_MAX, sustained dropBuy size boosted by DCA_BIAS_EXTRA_PCT. Deep-DCA reserve levels activate if all main levels filled.
HIGH_VOLATR above ATR_HIGH_VOL_PCT thresholdSkips the deepest HIGH_VOL_SKIP_DEEP_LEVELS levels to preserve capital.
PAUSEDManual pause or SOFT STOP (license expired)No new buys. Existing filled positions still managed — bot will still sell them.

ATR Adaptive Spacing

ATR (Average True Range) measures recent price volatility. The bot uses ATR to scale grid offsets adaptively:

This way the grid responds to current market conditions on every reseed, not just the original calibration. You'll see log lines like:

ATR adaptive spacing: ATR=0.10% → mult=0.73x | offsets [-1.53, -3.3, -5.29, -7.5] (config: [-2.1, -4.52, -7.25, -10.29])

Risk Profiles

Each pair has a RISK_PROFILE that biases auto-tune. Three profiles:

ProfileReserveDeep-DCA %Buy spacing
CONSERVATIVE200K PLS (min)~23%0.85x — tighter
BALANCED (default)200K PLS (min)~18%1.0x — neutral
AGGRESSIVE200K PLS (min)~13%1.15x — wider, deeper buys

Reserve is a gas safety buffer — auto-tune sets it to a minimum of 200,000 PLS regardless of profile. Deep-DCA % varies by profile and volatility (ATR). Exact values shown in the auto-tune log on first run.

You can override at any time by changing RISK_PROFILE in corebot-config.js for the relevant pair. Takes effect on the next calibration.


Level Recycling

When a filled level sells completely, it does not wait for all other levels to sell before resetting. It immediately recycles — returning to WAITING status at its original trigger price and becoming ready to buy again on the next dip. This happens independently per level.

This means a single level can complete multiple buy-sell cycles while other levels are still filled, significantly increasing total trade throughput across the grid.

Day 1: L1 triggers at 98.5 → buys
Day 2: price recovers → L1 sells at +3.5% → L1 recycles to WAITING
Day 3: price dips again → L1 triggers again → L1 buys again
      (L2 and L3 may still be filled from Day 1)

A full cycle completes when ALL main grid levels have sold at least once AND no levels are currently filled. The bot then reseeds at the new market price and the cycle counter increments. Deep-DCA levels that were never activated do not block cycle completion.


Partial Take-Profits — Deep Dive

SELL_LEVELS is an array of sell tier objects that define your complete take-profit strategy. Each tier specifies what percentage of the position it sells, at what price target, and whether it uses a fixed sell or a trailing stop.

Tier object format

{ pct: 2.0, portion: 0.30, trail: false }
  //  pct     = % gain from buy price at which this tier activates
  //  portion = fraction of tokens this tier sells (all tiers must sum to 1.0)
  //  trail   = false → fixed sell at pct target
  //            true  → trailing stop activates at pct, then fires on TRAIL_DISTANCE_PCT retreat

Default AUTO output (30% fixed + 70% trailing)

SELL_LEVELS: [
  { pct: 2.18, portion: 0.30, trail: false },  // 30% sells at +2.18% guaranteed
  { pct: 3.35, portion: 0.70, trail: true  },  // 70% trails from +3.35%
]

Math example — buy 1,000,000 tokens at price 100:

Three-tier example

SELL_LEVELS: [
  { pct: 1.5, portion: 0.25, trail: false },  // 25% at +1.5%
  { pct: 3.0, portion: 0.25, trail: false },  // 25% at +3.0%
  { pct: 5.0, portion: 0.50, trail: true  },  // 50% trails from +5.0%
]

Dashboard display

The tiers: row on each level card shows per-tier status: ✓30% = Tier 1 has sold · ●70% = Tier 2 still waiting to sell.

Buy gas is charged once, on whichever tier sells first. Subsequent tier sells show buy gas: 0 in the breakdown — the original buy gas was already accounted for on the first tier.

Deep-DCA — Deep Dive

Deep-DCA is an emergency averaging system. A portion of TOTAL_PLS (set by DEEP_DCA_BUDGET_PCT) is held back from the main grid and assigned to hidden reserve levels at much deeper offsets. These levels stay in RESERVE status — dormant — until all three conditions are met simultaneously:

  1. ALL main grid levels are filled (main budget fully deployed)
  2. Market regime is TREND_DOWN or DCA (sustained downtrend)
  3. RSI is below DEEP_DCA_RSI_MAX (deeply oversold)

When all three trigger, reserve levels activate to WAITING and behave exactly like main levels — fill on price drop, sell on recovery, recycle. The triple-condition gate prevents reserves from firing during normal volatility; they are designed for genuine crashes.

Why it helps

Buying at much lower prices lowers the average entry cost across the whole position, bringing the main grid's original sell targets back within reach without needing a full price recovery.

Main grid: 4 levels bought at avg 100, sell targets at ~103.5
Price crashes to 75. RSI = 18. All main levels filled.
Deep-DCA activates 3 reserve levels → fills at 85, 75, 65.
New blended avg entry across 7 positions: ~87
Bot now needs price to recover to ~90 to break even (vs 103.5 before)

Budget split math

TOTAL_PLS: 5,000,000   DEEP_DCA_BUDGET_PCT: 20

Deep-DCA reserve: 1,000,000 PLS  (held back — 3 reserve levels × 333,333 PLS each)
Main grid budget: 4,000,000 PLS  (÷ 4 levels = 1,000,000 PLS per main level)
💡
Reserve levels not activating during a cycle is completely normal. They are insurance, not a regular profit driver. Cycle completion is determined by main-level activity only.

Stuck Level Recovery — Deep Dive

A level is "stuck" when it was filled (bought) but price has not recovered enough to reach the sell target for an extended period. After STUCK_REDUCE_START_HOURS hours the bot begins a linear ramp, gradually reducing the sell target from the original value down to STUCK_REDUCE_MIN_PCT.

Reduction math

Original sell target:       +3.5%
STUCK_REDUCE_MIN_PCT:        1.5%
STUCK_REDUCE_START_HOURS:    6h
Ramp duration:              24h (from first reduction to floor)

Hour 0–6:    No reduction. Target = +3.5%
Hour 6:      Reduction starts.
Hour 6–30:   Linear ramp → target reduces from +3.5% toward +1.5%
Hour 12:     Halfway through ramp → target ≈ +2.5%
Hour 30+:    Target held at +1.5% floor indefinitely

Dashboard shows: "⚡ stuck 8.7h — target reduced to +2.18%"

If STUCK_TRAIL_TIGHTEN is enabled (default), the trailing stop distance is also tightened proportionally, making the trail fire sooner on small reversals as the level ages. The absolute floor is always the higher of STUCK_REDUCE_MIN_PCT and the estimated breakeven price including gas — the bot will never reduce a target to a loss.


Freefall Protection

Freefall protection pauses all new buys when price drops sharply in a short window. It prevents the bot from deploying capital into a market that has not bottomed yet.

How it triggers

Every tick, the bot measures the % price drop over the last FREEFALL_CANDLES 5-minute candles. If the drop exceeds FREEFALL_DROP_PCT, freefall mode activates immediately. Existing filled positions continue to be managed — sells still execute normally. Only new buys are paused.

Recovery

The bot tracks the lowest price seen during freefall. Buying only resumes once price recovers FREEFALL_RECOVERY_PCT% above that low — confirming a genuine bounce rather than a dead-cat recovery.

Auto-tune math

FREEFALL_DROP_PCT = max(2.0%, measured_ATR% × 2.0)
Token ATR = 1.8% → threshold = max(2.0%, 3.6%) = 3.6%
Token ATR = 0.7% → threshold = max(2.0%, 1.4%) = 2.0%  ← floor prevents false triggers

Enable/disable globally with PHASE6_FREEFALL. The dashboard shows a FREEFALL badge on the pair card when active. Terminal log: "⚠ FREEFALL: buying paused — price dropped X%"

Capital Stages

Capital stages protect against committing all your budget in a single prolonged downtrend. As the pair's deployed % climbs through thresholds, each subsequent buy is smaller — and eventually stops entirely until positions are sold and capital is returned.

Default values (BALANCED)

CAPITAL_STAGE_THRESHOLDS:  [0.30, 0.60, 0.85]   ← 30%, 60%, 85% deployed
CAPITAL_STAGE_MULTIPLIERS: [1.0,  0.75, 0.50,  0]

0–30% deployed   → 100% buy size  (multiplier 1.0)
30–60% deployed  →  75% buy size  (multiplier 0.75)
60–85% deployed  →  50% buy size  (multiplier 0.50)
85%+  deployed   → buying stops   (multiplier 0)

Example

TOTAL_PLS = 10,000,000.  L2 base allocation = 2,000,000 PLS.

3,500,000 deployed (35%) → stage 2 → 2,000,000 × 0.75 = 1,500,000 PLS
7,000,000 deployed (70%) → stage 3 → 2,000,000 × 0.50 = 1,000,000 PLS
8,700,000 deployed (87%) → stage 4 → buying stops until a sell completes

Enable/disable globally with PHASE6_CAPITAL_STAGES.

Climb Protection

When price trends strongly above the MA20, the bot raises sell targets automatically — letting winning positions run further rather than exiting at the base target. Targets return to normal the moment price pulls back to the MA20 range.

How it works

Climbing condition: price > MA20 × (1 + CLIMB_SENSITIVITY_PCT / 100). While climbing: effective sell target = base target + CLIMB_EXTRA_GAIN_PCT. The modification is live — no stored state change, so it reverts instantly on pullback.

Example

MA20 = 100.00, CLIMB_SENSITIVITY_PCT = 1.5, CLIMB_EXTRA_GAIN_PCT = 0.7

Climb threshold = 100.00 × 1.015 = 101.50
Price = 102.40 → climbing → sell target: 3.5% + 0.7% = 4.2%
Price = 100.90 → not climbing → sell target: 3.5% (normal)

Enable/disable globally with PHASE6_CLIMB. Terminal log: "📈 CLIMBING — price X% above MA20 — sell targets raised by +Y%"

RSI Dynamic Sizing

Adjusts the PLS spent per buy based on current RSI momentum. Buys more at genuine oversold bottoms and less when the market is overbought. Uses the 1-hour RSI for reliable signals — see Multi-Timeframe RSI.

Default values (BALANCED)

RSI_OVERSOLD_LVL   = 35    RSI_OVERSOLD_MULT   = 1.2
RSI_OVERBOUGHT_LVL = 65    RSI_OVERBOUGHT_MULT = 0.6

Example (base allocation = 1,000,000 PLS)

1h RSI = 28 → oversold    → 1,000,000 × 1.2 = 1,200,000 PLS  (+20%)
1h RSI = 50 → neutral     → 1,000,000 × 1.0 = 1,000,000 PLS  (no change)
1h RSI = 72 → overbought  → 1,000,000 × 0.6 =   600,000 PLS  (−40%)

Enable/disable globally with PHASE6_RSI_SIZING. The multiplier stacks with capital stages — both apply independently before the final buy is submitted.

Pyramid Level Sizing

Allocates more capital to deeper grid levels. The deeper the dip, the bigger the buy — maximising position at better prices. Steepness scales with your risk profile.

Default weights by profile (3 levels)

CONSERVATIVE: [0.267, 0.333, 0.400]  L3 gets 1.50× L1
BALANCED:     [0.222, 0.333, 0.444]  L3 gets 2.00× L1
AGGRESSIVE:   [0.190, 0.333, 0.476]  L3 gets 2.51× L1

Example — BALANCED, 5M PLS total, main grid = 3,936,000 PLS

L1 (22.2%): 3,936,000 × 0.222 =   874,579 PLS  ← shallowest
L2 (33.3%): 3,936,000 × 0.333 = 1,311,869 PLS
L3 (44.4%): 3,936,000 × 0.444 = 1,748,745 PLS  ← deepest, biggest buy

To use equal weighting: LEVEL_WEIGHTS: [0.333, 0.333, 0.333]. Configured per-pair.

Compound Mode

After each profitable sell cycle, a % of net profit is reinvested into the next buy's allocation. Winning pairs grow their effective position size over time using house money.

Example (COMPOUND_PCT = 15)

Sell cycle nets 50,000 PLS profit
Compound bonus = 50,000 × 0.15 = 7,500 PLS

L2 base allocation = 2,000,000 PLS
Next L2 buy = 2,000,000 + 7,500 = 2,007,500 PLS

Default: 0% (CONSERVATIVE/BALANCED — off), 25% (AGGRESSIVE). Recommended starting value if enabling: 10–15%. Configured per-pair via COMPOUND_PCT.

Volume Monitoring

The bot tracks 1-hour DEX trading volume for each pair in real time and displays it as an informational metric on the dashboard. Volume ratio is shown under Market Intel on each pair's page — green when current volume is strong relative to the 24h average, yellow when thin.

What it shows

Volume: 47% of avg   ← 1h volume is below the 24h rolling average (thin)
Volume: 312% of avg  ← 1h volume is 3× normal (strong move, confirmed)

The rolling 24-hour average updates every tick. Use this as context when reviewing positions — high volume during a dip means a more reliable signal; thin volume during a move may be noise.

Multi-Timeframe RSI

The bot calculates RSI on two timeframes simultaneously. Each serves a distinct purpose:

TimeframeUsed forResponds to
5-minute RSIRegime detection (GRID / DCA / HIGH_VOL / TREND_UP / TREND_DOWN)Short-term momentum. Fast.
1-hour RSIBuy sizing (RSI_OVERSOLD_MULT / RSI_OVERBOUGHT_MULT)Sustained momentum. Filters noise.

Why both matter

A 5-minute RSI spike to 25 during a single candle might be a momentary liquidity gap — not a genuine bottom. The 1-hour RSI at 38 confirms the condition is real and sustained before boosting the buy. Both must agree for maximum confidence.

Example:
5m RSI = 24 → TREND_DOWN regime (regime detection fires)
1h RSI = 42 → above RSI_OVERSOLD_LVL (35) → no oversold boost applied
→ regime says oversold but 1h disagrees → normal buy size

5m RSI = 29 → DCA regime
1h RSI = 28 → below RSI_OVERSOLD_LVL (35) → oversold boost applied
→ both timeframes agree → RSI_OVERSOLD_MULT × buy size

Dashboard shows both RSI values in the pair stats panel. Terminal log: "(1h RSI: 28)" appended to buy log lines when 1h RSI differs from 5m.

Event-Driven Recalibration

Beyond scheduled recalibration (every 24h by default), the bot also recalibrates automatically when market conditions change significantly — keeping parameters relevant without waiting for the next timer.

Triggers

Recalibration only fires on a clean grid — when no levels are currently filled. If conditions trigger recalibration but positions are open, it queues and waits for the grid to clear before running. No position is ever disrupted for a recalibration.

Configured via AUTOTUNE_RECAL_MS (timed interval). The CALIBRATE button in the dashboard forces immediate recalibration on demand.

Stuck Deploy

Stuck deploy automatically activates the Deep-DCA reserve levels when ALL main grid levels have been filled and stuck for an extended period. It treats a prolonged full-grid stall as a signal to average down aggressively — without waiting for the RSI gate that normally controls Deep-DCA.

How it differs from normal Deep-DCA

Normal Deep-DCAStuck Deploy
TriggerAll levels filled + RSI below DEEP_DCA_RSI_MAXAll levels filled for STUCK_DEPLOY_HOURS regardless of RSI
PurposeOversold market averagingExtended stall recovery

Example (BALANCED, STUCK_DEPLOY_HOURS = 72)

Monday 09:00   — L1 fills at 100
Monday 11:00   — L2 fills at 97
Monday 15:00   — L3 fills at 94
Thursday 09:00 — 72h+ elapsed, all still stuck → stuck deploy fires
                 → Deep-DCA levels activate at ~85, ~78, ~70
                 → Average entry drops from 97.0 to ~88.5
                 → Main grid sell targets now within reach

Default by profile: CONSERVATIVE 96h, BALANCED 72h, AGGRESSIVE 48h. Enable/disable globally with PHASE6_STUCK_DEPLOY.


Loss Guard (Strict Zero)

The single most important safety feature. Before any sell, the bot estimates the net result after all fees, gas (sell + remaining buy), and slippage. If the estimate is anything below zero, the sell is BLOCKED.

The default threshold is SELL_LOSS_GUARD_PCT: 0 — strict zero. The bot will never voluntarily sell below cost. Stuck-level reduction will keep dropping targets toward 1.5%, but the loss guard provides an absolute floor below that.

Defense in depth — three layers:

  1. Pre-swap estimate — uses the DEX router's getAmountsOut to predict the sell outcome including pool slippage
  2. Full-cost accounting — includes the original buy gas (not just sell gas) and any unpaid buy gas from earlier tier sells
  3. Fail-closed catches — if the estimate itself fails (RPC error, zero liquidity), the bot blocks the sell rather than guessing

When a sell is blocked, you'll see a single line in the log:

[WARN] ⚠ L2: auto-sell BLOCKED — est -3252 PLS (-0.15%), exceeds guard (0%)

This is correct behavior, not an error. The guard is throttled to log once per hour per level — not every tick.

5% Pre-Swap Deviation Check

Before every buy, the bot fetches a fresh price quote from the DEX router and compares it to the last known price from its tick loop. If the fresh quote deviates more than 5%, the buy is skipped with a WARN.

This protects against:

Real example from production:

[WARN] L4: buy SKIPPED (attempt 2) — fresh quote deviates 9.3% from last price
[WARN] L1: buy SKIPPED (attempt 1) — fresh quote deviates 17.0% from last price

Both of those would have resulted in bad fills without the check. The bot retries the buy on the next tick once price stabilizes.

Low-Funds Watchdog

A separate background watchdog runs every 5 minutes. It checks whether the wallet can afford the next pending buy (main level allocation + reserve + 1,000 PLS gas buffer). If not, it sets a soft lowBalanceAlert visible on the dashboard.

The watchdog is smart about what counts as a real shortage:

The same smart check applies at buy time — if all main levels are already filled and a rebuy is attempted, the insufficient-balance log is suppressed so the dashboard stays clean.

The watchdog does not stop trading — the bot's per-trade pre-flight check already blocks individual buys when wallet is too low. The watchdog gives visibility ahead of time so you can top up before a fill is missed.

State File Backups

The bot uses a 3-tier backup system to protect your state files. The most important tier runs synchronously before startup — before loadState() is called — so the on-disk state is always preserved before anything reads or overwrites it.

Tier 1 — Pre-startup snapshot (most important): On every restart, the bot immediately copies each pair's state file to startup.json in state-backups/. This fires before any loading or saving, so if you accidentally run the wrong file or a bad config, the last known-good state is already saved.

Tier 2 — Hourly rolling slots: 12 rotating slots (hourly.1.json through hourly.12.json). One slot is written per restart if the most recently written slot is more than 1 hour old. Gives you 12 hours of hourly history.

Tier 3 — Daily rotating slots: 7 rotating slots (daily.1.json through daily.7.json). One slot is written per restart if the most recently written slot is more than 24 hours old. Gives you 7 days of daily history.

state-backups/
├── hex-grid-state.startup.json       ← overwritten every restart
├── hex-grid-state.hourly.1.json      ← 12 rotating hourly slots
├── hex-grid-state.hourly.2.json
├── ...
├── hex-grid-state.daily.1.json       ← 7 rotating daily slots
├── hex-grid-state.daily.2.json
├── ...
├── ehex-grid-state.startup.json
└── ...

On startup the terminal prints: ✓ Pre-startup backup → state-backups/ (startup + hourly + daily)

To recover from a corrupted or overwritten state file: copy the most recent backup from state-backups/ back over the live state file (rename to remove the suffix) and restart. See Recovery from Mismatch.

State Mismatch Detection

On startup, each pair runs a self-check: does the wallet's actual token balance match what the state file thinks it owns?

Two cases:

  1. Wallet has tokens but state shows zero positions → bot HALTS and pauses the pair. The dashboard shows a STATE MISMATCH alert. User must investigate (or restore a backup) before resuming. This protects against buying more tokens on top of an untracked position.
  2. State tracks more tokens than wallet has → soft WARN every tick. Common during RPC lag at startup; investigate only if it persists.

RPC Auto-Recovery

If the primary PulseChain RPC fails (timeout, connection refused), the bot automatically switches to the backup RPC from your .env and continues trading. After the switch, a recovery watch polls the primary every 5 minutes and switches back when it's healthy again.

If 3 backup attempts also fail, the bot enters a 30-minute cooldown to avoid hammering RPCs. The dashboard shows the active RPC URL and current latency in the header.

RPC Latency Scoring

Beyond failure-based switching, the bot also tracks a rolling average latency (EMA) for each endpoint and proactively switches to the fastest one. Every 20 successful calls it checks whether any other endpoint is more than 30% faster. If so it switches without waiting for a failure.

Primary  rpc.pulsechain.com     → avg 340ms
Backup   rpc-pulsechain.g4mm4.io → avg 180ms
→ 180ms is >30% faster → bot switches proactively
→ [RPC] ⚡ Switching to faster endpoint (180ms vs 340ms)

Atomic State Saves

Every time the bot saves its state file (after every buy, sell, and recycle), it uses an atomic write: the new data is written to a .tmp file first, then the .tmp file is renamed over the real state file in a single OS operation.

This means a crash, power cut, or kill signal at any moment will either leave the old state file intact or the new one complete — never a half-written corrupted file. The 3-tier backup system adds a second layer on top of this.

On-Chain Sell Verification

After every sell transaction is mined (receipt.status === 1), the bot calls balanceOf() on-chain to confirm the tokens actually left the wallet before writing any logs or updating state. This guards against a rare failure mode where an RPC failover returns a stale receipt from a node that hasn't fully synced — the receipt shows success but the tokens never moved.

If tokens are still in the wallet after receipt confirmation, the bot:

  1. Retries the balance check up to 3 times (3 seconds apart)
  2. Sends a Telegram alert: "SELL NOT CONFIRMED ON-CHAIN — retrying automatically"
  3. Throws an error, which restores the level to FILLED so the next tick retries the sell
  4. Keeps retrying indefinitely until the tokens are confirmed gone
  5. Sends a second Telegram: "SELL CONFIRMED ON-CHAIN — tokens confirmed gone" once successful

No logs or state are written until the on-chain balance confirms the sell happened. This ensures your trade history and P&L are always accurate.

Nonce Collision Prevention

Before every buy and approval transaction, the bot checks whether a previous transaction is still pending in the mempool by comparing the wallet's pending nonce against its latest nonce. If a TX is already in flight, the bot waits and retries next tick rather than submitting a conflicting transaction.

This prevents nonce collisions that would cause transactions to fail with replacement transaction underpriced errors — especially important when running on congested networks or when the RPC is lagging.

60-Second Transaction Deadline

Every swap submitted to the PulseX router includes a 60-second on-chain deadline. If the transaction sits in the mempool for longer than 60 seconds without being included in a block, it auto-expires and is never executed.

This protects against sandwich attacks and stale fills — if the market moves significantly while the TX is pending, it simply reverts rather than executing at a bad price. The bot logs the failure and retries on the next tick at the current price.

Chain ID Verification

On startup, the bot reads the actual chain ID from the connected RPC and compares it against CHAIN_ID in your config (default 369 for PulseChain mainnet). If they don't match, the bot refuses to start.

This prevents accidentally trading on a testnet fork or wrong network if the RPC URL is misconfigured.

Startup State Repair

On every restart, the bot automatically scans all levels for inconsistent state left by crashes, unexpected shutdowns, or earlier bot versions. Two repairs run:

These repairs run silently on every restart so you never need to manually edit state files after an unexpected shutdown.


Configuration Overview

All bot settings live in corebot-config.js — a plain text file in your bot folder. Open it with Notepad, Notepad++, TextEdit, or any text editor. The file is divided into three sections:

  1. Network & dashboard — chain ID, router address, dashboard port. Rarely change.
  2. Global tuning — tick interval, CSV logging.
  3. Pairs array — one block per token you trade. This is where you spend most of your time.

Most settings should be left as "AUTO". Auto-tune derives them from real market conditions every 24 hours. Manually overriding bypasses that intelligence — only do it if you have a clear reason.

Network & Dashboard Settings

CHAIN_ID 369
PulseChain mainnet chain ID. Do not change unless you're testing on a fork.
Example: CHAIN_ID: 369
ROUTER_ADDRESS 0x165C…52d9
PulseX V2 router contract address. The bot uses this for all swap transactions and liquidity checks.
Example: ROUTER_ADDRESS: "0x165C3410fC91EF562C50559f7d2289fEbed552d9"
WPLS 0xA1077…9a27
Wrapped PLS contract address. The bot wraps PLS automatically for swaps that require it.
Example: WPLS: "0xA1077a294dDE1B09bB078844df40758a5D0f9a27"
USDC 0x15D38…1f07
USDC contract address. Used to compute dollar-denominated values shown on the dashboard.
Example: USDC: "0x15D38573d2feeb82e7ad5187aB8c1D52810B1f07"
HOST "localhost"
Dashboard server host. Use "0.0.0.0" if you want to access the dashboard from other devices on your network. Do not expose to the public internet without authentication.
Example A (default, local only): HOST: "localhost"
Example B (LAN-accessible): HOST: "0.0.0.0"
PORT 5555
Dashboard server port. Change if 5555 is already in use on your machine.
Example A (default): PORT: 5555
Example B (alternative): PORT: 8080
TX_EXPLORER "https://apphex.win/@/#/tx/"
Block explorer URL prefix. The bot appends transaction hashes for clickable links in the dashboard log.
Example: TX_EXPLORER: "https://apphex.win/@/#/tx/"

Global Settings

CHECK_INTERVAL_MS 5000
How often the tick loop fires (in milliseconds). 5000 = every 5 seconds. With 5 pairs, total tick cycle takes ~5 seconds. Lower = faster reaction but more RPC load. Most users should leave this alone.
Example A (default, 5 sec): CHECK_INTERVAL_MS: 5000
Example B (faster, 3 sec — for fewer pairs only): CHECK_INTERVAL_MS: 3000
Example C (slower, easier on RPC): CHECK_INTERVAL_MS: 10000
CSV_LOGGING true
Whether to write a structured CSV log of every buy and sell to {pair}-grid-logs/trades.csv. Useful for spreadsheet analysis. Set to false if you don't need it.
Example A (on): CSV_LOGGING: true
Example B (off): CSV_LOGGING: false
PRICE_DECIMALS 7
Display precision for prices in logs and the dashboard. Affects readability only — accounting always uses full precision.
Example A (default): PRICE_DECIMALS: 7
Example B (more decimals for low-priced tokens): PRICE_DECIMALS: 10
CALIBRATION_MIN_MS 180000
Minimum time in milliseconds the bot spends sampling price before completing calibration. More time = more accurate ATR measurement. Both CALIBRATION_MIN_MS and CALIBRATION_MIN_SAMP must be satisfied before calibration completes.
Example A (2 min, faster): CALIBRATION_MIN_MS: 120000
Example B (default, 3 min): CALIBRATION_MIN_MS: 180000
Example C (5 min, more accurate): CALIBRATION_MIN_MS: 300000
CALIBRATION_MAX_MS 360000
Maximum calibration time before the bot forces completion regardless of sample count. Prevents waiting forever if price barely moves. Default 6 minutes.
Example A (default): CALIBRATION_MAX_MS: 360000
Example B (10 min max): CALIBRATION_MAX_MS: 600000
CALIBRATION_MIN_SAMP 10
Minimum number of distinct price samples required before calibration completes. Combined with CALIBRATION_MIN_MS. Increase for tokens with infrequent price updates.
Example A (default): CALIBRATION_MIN_SAMP: 10
Example B (more samples for illiquid tokens): CALIBRATION_MIN_SAMP: 20
AUTOTUNE_RECAL_MS 86400000
How often in milliseconds the bot re-runs the full calibration cycle while running. Only fires on a clean grid (no filled levels) to protect open positions. Also triggers automatically on ATR or RSI regime shifts regardless of this timer.
Example A (24h, default): AUTOTUNE_RECAL_MS: 86400000
Example B (12h, more adaptive): AUTOTUNE_RECAL_MS: 43200000
Example C (7 days, set-and-forget): AUTOTUNE_RECAL_MS: 604800000
STATE_DIR ./ (bot folder)
Optional absolute path for state files. Leave commented out to save state alongside the bot binary (default). Useful when running multiple bots or wanting state files in a specific location.
Example: STATE_DIR: "/home/user/pulsexbot/state"
Leave commented out (default): // STATE_DIR: "./state"

Pair Settings — Capital

Each entry inside the PAIRS array configures one token. Required identity fields:

SYMBOL string
Display symbol for this pair. Used for log file names, dashboard tabs, and console output.
Example A: SYMBOL: "PRVX"
Example B: SYMBOL: "EHEX"
Example C: SYMBOL: "PLSX"
TOKEN_ADDRESS string
Contract address of the token you're trading. Get this from PulseScan or DexScreener — copy the exact checksum-cased address.
Example A (PRVX): TOKEN_ADDRESS: "0xf6f8db0aba00007681f8faf16a0fda1c9b030b11"
Example B (EHEX): TOKEN_ADDRESS: "0x57fde0a71132198BBeC939B98976993d8D89D225"
TOKEN_DECIMALS int
Number of decimals the token uses. Get this from the token's contract page on PulseScan. Getting this wrong will cause every swap to fail.
Example A (most ERC-20s): TOKEN_DECIMALS: 18
Example B (HEX-style): TOKEN_DECIMALS: 8
Example C (USDC/USDT): TOKEN_DECIMALS: 6
TOTAL_PLS number 10000000
Total PLS budget allocated to this pair. The bot splits this across grid levels and (if enabled) deep-DCA reserves. Make sure your wallet has at least this much PLS plus 10% headroom for reserve. Changing mid-run: stop the bot, update the value, restart. The new budget takes effect on the next reseed or recalibration. Existing filled positions are preserved.
Example A (small, 1M PLS): TOTAL_PLS: 1000000
Example B (medium, 10M PLS): TOTAL_PLS: 10000000
Example C (large, 50M PLS): TOTAL_PLS: 50000000
RISK_PROFILE enum "BALANCED"
Bias for auto-tune. CONSERVATIVE keeps more reserve and disables deep-DCA. AGGRESSIVE deploys more capital and uses wider/deeper buys. See Risk Profiles.
Example A (low risk, more reserve): RISK_PROFILE: "CONSERVATIVE"
Example B (default, balanced): RISK_PROFILE: "BALANCED"
Example C (high risk, more capital deployed): RISK_PROFILE: "AGGRESSIVE"

Pair Settings — Grid

BUY_OFFSETS array | "AUTO" "AUTO"
The percent offsets below seed price where buy levels sit. Auto-tune typically picks 3–5 offsets. Override only if you have specific levels in mind. Negative numbers, smallest closest to current price.
Example A (default, auto-tuned): BUY_OFFSETS: "AUTO"
Example B (custom 4-level tight grid): BUY_OFFSETS: [-0.8, -1.7, -2.8, -4.5]
Example C (custom 5-level wide grid): BUY_OFFSETS: [-2, -5, -9, -15, -22]
RESERVE_PLS number | "AUTO" "AUTO"
PLS kept in reserve in your wallet at all times — never spent on buys. Auto-tune sets a gas safety buffer with a minimum of 200,000 PLS regardless of profile — scales slightly with level count and profile but always floors at 200K. The reserve protects against running out of PLS if all levels fill simultaneously.
Example A (default, ~200K PLS minimum): RESERVE_PLS: "AUTO"
Example B (manual override, 500K PLS held): RESERVE_PLS: 500000
Example C (no reserve, deploy everything): RESERVE_PLS: 0
DEEP_DCA_BUDGET_PCT number | "AUTO" "AUTO"
Percent of TOTAL_PLS held back for deep-DCA reserve levels. Set to 0 to disable deep-DCA entirely.
Example A (default, 10% by profile): DEEP_DCA_BUDGET_PCT: "AUTO"
Example B (15% reserved for crashes): DEEP_DCA_BUDGET_PCT: 15
Example C (disabled — all capital on main grid): DEEP_DCA_BUDGET_PCT: 0
DEEP_DCA_OFFSETS array | "AUTO" "AUTO"
Three offsets where reserve levels sit. Auto-tune scales by volatility.
Example A (default): DEEP_DCA_OFFSETS: "AUTO"
Example B (mild crashes): DEEP_DCA_OFFSETS: [-12, -18, -26.4]
Example C (deep crashes): DEEP_DCA_OFFSETS: [-20, -35, -50]
DEEP_DCA_RSI_MAX number | "AUTO" 25
RSI threshold below which deep-DCA reserves can activate. Lower = more conservative.
Example A (default, oversold): DEEP_DCA_RSI_MAX: 25
Example B (very oversold only): DEEP_DCA_RSI_MAX: 20
Example C (less strict): DEEP_DCA_RSI_MAX: 30
DCA_BIAS_EXTRA_PCT number | "AUTO" 10
Extra percent added to a level's allocation when buying in DCA regime. Mild buy-the-dip behaviour — the bot spends a little more when price is deeply oversold to lower the average entry cost. Auto-tune accounts for this in the budget calculation, dividing the per-level allocation by the bias multiplier so the total spend never exceeds TOTAL_PLS even if every level fills simultaneously in DCA mode.
Example A (default, +10% boost): DCA_BIAS_EXTRA_PCT: 10
Example B (no boost, equal allocation): DCA_BIAS_EXTRA_PCT: 0
Example C (strong dip-buy, +25%): DCA_BIAS_EXTRA_PCT: 25

Pair Settings — Sells

SELL_LEVELS array | "AUTO" "AUTO"
Two-tier sell config. Tier 1 sells a portion at a fixed target; tier 2 holds the rest with a trailing stop. Auto-tune sets both.
Example A (default, auto-tuned): SELL_LEVELS: "AUTO"
Example B (custom 30/70 with tight targets):
SELL_LEVELS: [{pct: 1.5, portion: 0.3, trail: false}, {pct: 2.5, portion: 0.7, trail: true}]
Example C (single full-trail, no fixed tier 1):
SELL_LEVELS: [{pct: 4, portion: 1.0, trail: true}]
TRAIL_TRIGGER_PCT number | "AUTO" "AUTO"
Percent above buy price where the tier-2 trail arms. Once armed, the trail tracks the running high and sells when price retreats.
Example A (default, auto-tuned): TRAIL_TRIGGER_PCT: "AUTO"
Example B (early trail arming): TRAIL_TRIGGER_PCT: 2.0
Example C (late trail arming): TRAIL_TRIGGER_PCT: 5.0
TRAIL_DISTANCE_PCT number | "AUTO" "AUTO"
How far below the running high the trail stop sits. Smaller = quicker exit on reversal but captures less of big moves.
Example A (default, auto-tuned): TRAIL_DISTANCE_PCT: "AUTO"
Example B (tight trail, exit on small reversal): TRAIL_DISTANCE_PCT: 0.5
Example C (wide trail, ride bigger moves): TRAIL_DISTANCE_PCT: 1.5
TRAIL_SELL_NOTIFY_PCT number | "AUTO" 1.0
Profit threshold (above buy) at which the dashboard notifies "in profit". Display only — does not affect trading.
Example A (default): TRAIL_SELL_NOTIFY_PCT: 1.0
Example B (notify earlier): TRAIL_SELL_NOTIFY_PCT: 0.5
Example C (notifications off — set to large number): TRAIL_SELL_NOTIFY_PCT: 100

Pair Settings — Safety

SELL_LOSS_GUARD_PCT number | "AUTO" 0
Maximum permitted net loss percentage on any auto-sell. Default strict zero — never sell below cost. Set to a negative number to allow small losses if you have a specific reason. Not recommended.
Example A (default, strict — recommended): SELL_LOSS_GUARD_PCT: 0
Example B (allow up to 0.5% loss): SELL_LOSS_GUARD_PCT: -0.5
Example C (allow up to 1% loss): SELL_LOSS_GUARD_PCT: -1.0
STOP_LOSS_PCT number | "AUTO" 0 (off)
If the average entry across filled levels is more than this percent above current price, the pair pauses (no further buys). Default 0 = disabled. Use as a safety brake against catching a falling knife.
Example A (default, off): STOP_LOSS_PCT: 0
Example B (pause if 20% underwater): STOP_LOSS_PCT: 20
Example C (pause if 35% underwater): STOP_LOSS_PCT: 35
SLIPPAGE_PERCENT number | "AUTO" "AUTO"
Max permitted slippage on swaps. Auto-tune scales by liquidity — thin pools get higher tolerance. Failed swaps automatically retry once with a +0.5% bump.
Example A (default, auto-tuned): SLIPPAGE_PERCENT: "AUTO"
Example B (tight, deep liquidity): SLIPPAGE_PERCENT: 0.3
Example C (looser, low liquidity): SLIPPAGE_PERCENT: 1.0
SLIPPAGE_ALERT_PCT number | "AUTO" 2.0
Logs a slippage alert (and surfaces on dashboard) if actual slippage exceeds this. Display only — does not block.
Example A (default): SLIPPAGE_ALERT_PCT: 2.0
Example B (warn earlier): SLIPPAGE_ALERT_PCT: 1.0
Example C (warn only on bad fills): SLIPPAGE_ALERT_PCT: 5.0
MIN_LIQUIDITY_USD number | "AUTO" "AUTO"
Minimum LP USD value below which the bot will not trade this pair. Protects against rug-pulled or near-empty pools.
Example A (default, auto): MIN_LIQUIDITY_USD: "AUTO"
Example B (require strong liquidity): MIN_LIQUIDITY_USD: 100000
Example C (small caps OK): MIN_LIQUIDITY_USD: 20000
BUY_COOLDOWN_MS number | "AUTO" "AUTO"
Minimum time between two buys on the same pair (milliseconds). Prevents rapid double-fills on volatile candles.
Example A (default, auto): BUY_COOLDOWN_MS: "AUTO"
Example B (1-minute lockout): BUY_COOLDOWN_MS: 60000
Example C (no cooldown — risky): BUY_COOLDOWN_MS: 0
AUTO_SHIFT_PCT number | "AUTO" "AUTO"
Percent above seed price at which the bot reseeds upward. Only fires when zero levels are filled. Auto-tune typically picks 1–3.5%.
Example A (default, auto): AUTO_SHIFT_PCT: "AUTO"
Example B (shift early): AUTO_SHIFT_PCT: 1.5
Example C (shift only on big breakouts): AUTO_SHIFT_PCT: 5.0
AUTO_SHIFT_COOLDOWN_MS number | "AUTO" 300000
Minimum time between two auto-shifts (milliseconds). Default 5 minutes. Prevents the grid from chasing chop.
Example A (default, 5 min): AUTO_SHIFT_COOLDOWN_MS: 300000
Example B (10 min): AUTO_SHIFT_COOLDOWN_MS: 600000
Example C (1 hour): AUTO_SHIFT_COOLDOWN_MS: 3600000
RESEED_OFFSET_PCT number | "AUTO" "AUTO"
After a cycle completes, how far above current price to reseed the grid. Small positive number gives the new grid a small upside cushion.
Example A (default, auto): RESEED_OFFSET_PCT: "AUTO"
Example B (seed slightly above current): RESEED_OFFSET_PCT: 0.5
Example C (seed at current price): RESEED_OFFSET_PCT: 0
STAGGER_DELAY_MS number | "AUTO" "AUTO"
Per-tick delay between pairs in the multi-pair tick loop. Prevents RPC bursts. Each pair waits this long before the next ticks.
Example A (default, auto): STAGGER_DELAY_MS: "AUTO"
Example B (faster ticks, more RPC load): STAGGER_DELAY_MS: 100
Example C (slower, kinder to RPC): STAGGER_DELAY_MS: 500

Pair Settings — Indicators

MA_PERIOD number | "AUTO" 20
Period of the moving average used for regime detection. 20 ticks ≈ 100 seconds at the default tick interval.
Example A (default): MA_PERIOD: 20
Example B (faster): MA_PERIOD: 10
Example C (slower): MA_PERIOD: 50
RSI_PERIOD number | "AUTO" 14
RSI period (standard 14). Used for the deep-DCA RSI gate and DCA regime detection.
Example A (default, standard): RSI_PERIOD: 14
Example B (more reactive): RSI_PERIOD: 9
Example C (smoother): RSI_PERIOD: 21
ATR_PERIOD number | "AUTO" 14
Period of ATR (Average True Range) used for adaptive grid spacing.
Example A (default): ATR_PERIOD: 14
Example B (faster): ATR_PERIOD: 7
Example C (smoother): ATR_PERIOD: 28
ATR_ADAPTIVE_SPACING boolean | "AUTO" true
When true, grid offsets scale by current ATR multiplier on every reseed. Disable to use static offsets only.
Example A (default, on): ATR_ADAPTIVE_SPACING: true
Example B (off, fixed offsets): ATR_ADAPTIVE_SPACING: false
ATR_LOW_VOL_PCT number | "AUTO" "AUTO"
ATR threshold below which the bot considers volatility low. Used in adaptive spacing scaling.
Example A (default, auto): ATR_LOW_VOL_PCT: "AUTO"
Example B (manual, very calm): ATR_LOW_VOL_PCT: 0.1
Example C (manual, looser): ATR_LOW_VOL_PCT: 0.3
ATR_HIGH_VOL_PCT number | "AUTO" "AUTO"
ATR threshold above which volatility is considered high. Triggers HIGH_VOL regime and deep-level skipping.
Example A (default, auto): ATR_HIGH_VOL_PCT: "AUTO"
Example B (manual): ATR_HIGH_VOL_PCT: 1.0
Example C (only extreme moves): ATR_HIGH_VOL_PCT: 2.0
ATR_MIN_SPACING_MULT number | "AUTO" 0.7
Lower bound for the ATR spacing multiplier. Prevents the grid from collapsing too tight in extreme low-vol conditions.
Example A (default): ATR_MIN_SPACING_MULT: 0.7
Example B (allow tighter): ATR_MIN_SPACING_MULT: 0.5
Example C (no tightening): ATR_MIN_SPACING_MULT: 1.0
ATR_MAX_SPACING_MULT number | "AUTO" 1.3
Upper bound for the ATR spacing multiplier. Prevents the grid from spreading too wide in extreme high-vol.
Example A (default): ATR_MAX_SPACING_MULT: 1.3
Example B (allow wider): ATR_MAX_SPACING_MULT: 1.7
Example C (no widening): ATR_MAX_SPACING_MULT: 1.0
HIGH_VOL_SKIP_DEEP_LEVELS number | "AUTO" 2
In HIGH_VOL regime, skip the N deepest grid levels — preserves capital for whatever comes next.
Example A (default, skip 2 deepest): HIGH_VOL_SKIP_DEEP_LEVELS: 2
Example B (skip none, fill aggressively): HIGH_VOL_SKIP_DEEP_LEVELS: 0
Example C (skip 3 deepest, very cautious): HIGH_VOL_SKIP_DEEP_LEVELS: 3
AUTO_TUNE boolean true
Enable or disable auto-tune calibration for this specific pair. When false, every "AUTO" field in this pair must be set to a real number or the bot uses built-in defaults. Recommended only for advanced users who want full manual control. Leaving it true is strongly recommended.
Example A (default, auto-tune on): AUTO_TUNE: true
Example B (fully manual, advanced): AUTO_TUNE: false

Pair Settings — Phase 6 & 7

These settings cover the Phase 6 and 7 features. All default to "AUTO" and are calibrated from your RISK_PROFILE. The global PHASE6_* flags in the top of the config must also be true for these to take effect.

LEVEL_WEIGHTS array | "AUTO" "AUTO"
Pyramid level sizing — allocation fractions per level from shallowest to deepest. Weights are normalised automatically. Deeper levels get more capital so the bot buys more at lower prices. Auto-set by risk profile: BALANCED gives L3 exactly 2× L1's capital.
Auto (BALANCED, 3 levels): [0.222, 0.333, 0.444] — L3 gets 2× L1
Equal (flat grid): LEVEL_WEIGHTS: [0.333, 0.333, 0.333]
Steep 4-level pyramid: LEVEL_WEIGHTS: [0.10, 0.20, 0.30, 0.40] — L4 gets 4× L1
Math (BALANCED, 3,936,000 PLS main grid): L1=874K · L2=1,312K · L3=1,749K PLS
FREEFALL_DROP_PCT number | "AUTO" "AUTO"
% price drop over FREEFALL_CANDLES to trigger buying pause. Auto: max(2.0%, ATR% × 2.0). Requires PHASE6_FREEFALL: true globally.
Auto (ATR 1.8%): threshold = max(2.0, 3.6) = 3.6%
Override: FREEFALL_DROP_PCT: 3.0
FREEFALL_CANDLES number | "AUTO" "AUTO"
Number of 5-minute candles to measure the freefall drop over. Auto: 6–20 candles (30–100 minutes). Longer window catches slower crashes; shorter catches flash crashes only.
Override: FREEFALL_CANDLES: 12 ← 60-minute lookback
FREEFALL_RECOVERY_PCT number | "AUTO" "AUTO"
% price recovery from freefall low before buying resumes. Prevents buying into a dead-cat bounce. Auto: 0.5–2.0% scaled with volatility.
Override: FREEFALL_RECOVERY_PCT: 0.8
CAPITAL_STAGE_THRESHOLDS array | "AUTO" "AUTO"
% of TOTAL_PLS deployed that triggers each buy-size reduction stage. Expressed as decimals. Auto (BALANCED): [0.30, 0.60, 0.85] — stages at 30%, 60%, 85% deployed. Requires PHASE6_CAPITAL_STAGES: true globally.
Auto (BALANCED): [0.30, 0.60, 0.85]
Override: CAPITAL_STAGE_THRESHOLDS: [0.35, 0.65, 0.90]
CAPITAL_STAGE_MULTIPLIERS array | "AUTO" "AUTO"
Buy size multiplier at each capital stage. One more entry than thresholds. Last value should be 0 (stop buying when fully deployed). Auto (BALANCED): [1.0, 0.75, 0.50, 0].
Auto (BALANCED): [1.0, 0.75, 0.50, 0]
Math: 35% deployed, L2 base alloc 2,000,000 PLS → 2,000,000 × 0.75 = 1,500,000 PLS
Override: CAPITAL_STAGE_MULTIPLIERS: [1.0, 0.80, 0.60, 0]
RSI_OVERSOLD_LVL number | "AUTO" "AUTO"
1h RSI below this value = oversold = apply RSI_OVERSOLD_MULT (boost buy size). Auto: CONSERVATIVE 30, BALANCED 35, AGGRESSIVE 40. Requires PHASE6_RSI_SIZING: true globally.
Override: RSI_OVERSOLD_LVL: 35
RSI_OVERBOUGHT_LVL number | "AUTO" "AUTO"
1h RSI above this value = overbought = apply RSI_OVERBOUGHT_MULT (reduce buy size). Auto: CONSERVATIVE 60, BALANCED 65, AGGRESSIVE 70.
Override: RSI_OVERBOUGHT_LVL: 65
RSI_OVERSOLD_MULT number | "AUTO" "AUTO"
Buy size multiplier when 1h RSI is oversold. Auto: CONSERVATIVE 1.1, BALANCED 1.2, AGGRESSIVE 1.3.
Math (alloc 1,000,000 PLS, RSI 28, mult 1.2): 1,000,000 × 1.2 = 1,200,000 PLS (+20%)
Override: RSI_OVERSOLD_MULT: 1.2
RSI_OVERBOUGHT_MULT number | "AUTO" "AUTO"
Buy size multiplier when 1h RSI is overbought. Auto: CONSERVATIVE 0.5, BALANCED 0.6, AGGRESSIVE 0.7.
Math (alloc 1,000,000 PLS, RSI 72, mult 0.6): 1,000,000 × 0.6 = 600,000 PLS (−40%)
Override: RSI_OVERBOUGHT_MULT: 0.6
CLIMB_SENSITIVITY_PCT number | "AUTO" "AUTO"
% above MA20 for price to be considered "climbing". While climbing, sell targets are raised by CLIMB_EXTRA_GAIN_PCT. Auto: 1.0–3.0% scaled by ATR. Requires PHASE6_CLIMB: true globally.
Math (MA20 100, sensitivity 1.5%): climbing when price > 101.50
Override: CLIMB_SENSITIVITY_PCT: 1.5
CLIMB_EXTRA_GAIN_PCT number | "AUTO" "AUTO"
Extra % added to sell targets while the climbing condition is active. Reverts instantly when price drops back to MA20 range. Auto: 0.3–1.5% scaled by ATR.
Math (base sell 3.5%, extra 0.7%, climbing): effective target = 4.2%
Override: CLIMB_EXTRA_GAIN_PCT: 0.5
STUCK_DEPLOY_HOURS number | "AUTO" "AUTO"
Hours all main levels must remain filled before Deep-DCA auto-activates regardless of RSI. Auto: CONSERVATIVE 96h, BALANCED 72h, AGGRESSIVE 48h. Requires PHASE6_STUCK_DEPLOY: true globally.
Override: STUCK_DEPLOY_HOURS: 72
ATR_ADAPTIVE_SELLS boolean true
Scale sell targets AND trail distance with current ATR — same principle as ATR_ADAPTIVE_SPACING but applied to take-profit targets. High ATR widens targets (up to 1.5×) and trail (up to 1.6×). Low ATR tightens to 0.85× and 0.80× respectively. Only active when ATR_ADAPTIVE_SPACING is also enabled. Set false to keep fixed sell targets even when grid spacing adapts.
Math (base sell 3.5%, ATR 4.2%, HIGH_VOL threshold 3.0%): atrMult = min(1.5, 1 + (4.2-3.0)/3.0 × 0.5) = 1.2 → effective target = 4.2%
Override: ATR_ADAPTIVE_SELLS: false
MIN_VIABLE_PARTIAL_MULT number 3
Skip the fixed T1 partial sell if the position value is less than this multiple of estimated average gas cost. Prevents wasting a transaction where gas eats most of the profit — the bot trails the full position instead. Uses the pair's rolling average gas per trade for the estimate.
Math (avg gas 300 PLS, mult 3): min viable = 900 PLS
Position 28,904 PLS × 30% T1 = 8,671 PLS → executes (above threshold)
Position 2,000 PLS × 30% T1 = 600 PLS → skips T1, trails full position
Override: MIN_VIABLE_PARTIAL_MULT: 5 (skip more) or 0 (always execute partials)
COMPOUND_PCT number | "AUTO" "AUTO"
After each profitable sell, reinvest this % of net profit into the next buy allocation. Grows position size using house money. Auto: CONSERVATIVE/BALANCED 0% (off), AGGRESSIVE 25%.
Math (sell nets 50,000 PLS, COMPOUND_PCT 15): bonus = 50,000 × 0.15 = 7,500 PLS added to next buy
Override: COMPOUND_PCT: 15 or COMPOUND_PCT: 0 to disable

Pair Settings — Stuck Reduction

STUCK_REDUCE_START_HOURS number | "AUTO" 6
Hours a level must be filled before stuck-reduction starts ramping the sell target down.
Example A (default, 6 hours): STUCK_REDUCE_START_HOURS: 6
Example B (start sooner, 3 hours): STUCK_REDUCE_START_HOURS: 3
Example C (start later, 12 hours): STUCK_REDUCE_START_HOURS: 12
STUCK_REDUCE_MIN_PCT number | "AUTO" 1.5
Floor percent that stuck-reduction will not go below. Always above typical slippage so reduced targets stay profitable.
Example A (default, +1.5%): STUCK_REDUCE_MIN_PCT: 1.5
Example B (more aggressive exit, +1.0%): STUCK_REDUCE_MIN_PCT: 1.0
Example C (preserve more profit, +2%): STUCK_REDUCE_MIN_PCT: 2.0
STUCK_TRAIL_TIGHTEN boolean | "AUTO" true
When true, stuck-reduction also tightens the trail distance for tier 2 — quicker exit on small reversal as the level ages.
Example A (default, on): STUCK_TRAIL_TIGHTEN: true
Example B (keep wide trail even when stuck): STUCK_TRAIL_TIGHTEN: false

Adding a New Pair

Open corebot-config.js, copy an existing block inside the PAIRS array, and edit the identity fields:

{
  // ── Required — fill these in ──
  SYMBOL:              "MYTOKEN",
  TOKEN_ADDRESS:       "0x...your token contract...",
  TOKEN_DECIMALS:      18,          // 18 for most tokens, 8 for HEX/WBTC, 6 for USDC
  TOTAL_PLS:           5000000,
  RISK_PROFILE:        "BALANCED",  // CONSERVATIVE | BALANCED | AGGRESSIVE

  // ── Leave all below as "AUTO" to start ──
  BUY_OFFSETS:              "AUTO",
  RESERVE_PLS:              "AUTO",
  DEEP_DCA_BUDGET_PCT:      "AUTO",
  DEEP_DCA_OFFSETS:         "AUTO",
  DEEP_DCA_RSI_MAX:         "AUTO",
  SELL_LEVELS:              "AUTO",
  TRAIL_TRIGGER_PCT:        "AUTO",
  TRAIL_DISTANCE_PCT:       "AUTO",
  TRAIL_SELL_NOTIFY_PCT:    "AUTO",
  SELL_LOSS_GUARD_PCT:      "AUTO",
  STOP_LOSS_PCT:            "AUTO",
  SLIPPAGE_PERCENT:         "AUTO",
  SLIPPAGE_ALERT_PCT:       "AUTO",
  MIN_LIQUIDITY_USD:        "AUTO",
  BUY_COOLDOWN_MS:          "AUTO",
  AUTO_SHIFT_PCT:           "AUTO",
  AUTO_SHIFT_COOLDOWN_MS:   "AUTO",
  RESEED_OFFSET_PCT:        "AUTO",
  STAGGER_DELAY_MS:         "AUTO",
  DCA_BIAS_EXTRA_PCT:       "AUTO",
  MA_PERIOD:                "AUTO",
  RSI_PERIOD:               "AUTO",
  ATR_PERIOD:               "AUTO",
  ATR_ADAPTIVE_SPACING:     "AUTO",
  ATR_LOW_VOL_PCT:          "AUTO",
  ATR_HIGH_VOL_PCT:         "AUTO",
  ATR_MIN_SPACING_MULT:     "AUTO",
  ATR_MAX_SPACING_MULT:     "AUTO",
  HIGH_VOL_SKIP_DEEP_LEVELS:"AUTO",
  STUCK_REDUCE_START_HOURS: "AUTO",
  STUCK_REDUCE_MIN_PCT:     "AUTO",
  STUCK_TRAIL_TIGHTEN:      "AUTO",
}

Common PulseChain token addresses:

TokenAddressDecimals
HEX0x2b591e99afE9f32eAA6214f7B7629768c40Eeb398
PLSX0x95B303987A60C71504D99Aa1b13B4DA07b0790ab18
INC0x2fa878Ab3F87CC1C9737Fc071108F904c0B0C95d18
EHEX0x57fde0a71132198BBeC939B98976993d8D89D2258
USDC0x15D38573d2feeb82e7ad5187aB8c1D52810B1f076
WETH0x02DcdD04e3F455D838cd1249292C58f3B79e3C3C18
PRVX0xF6f8Db0aBa00007681F8fAF16A0FDa1c9B030b1118
USDT0x0Cb6F5a34ad42ec934882A05265A7d5F59b51A2f6

Save and restart the bot. The new pair runs a fresh 3-minute calibration on first start.

If you have a paid PXB license, make sure you have enough slot capacity for the new pair before adding it. The free trial only covers the first pair.

Web Dashboard

Open the dashboard at http://localhost:5555 (or your configured PORT). It refreshes automatically every 2–5 seconds via WebSocket.

Header bar

ElementMeaning
TOTAL P&LCombined realised profit/loss across all pairs in PLS and USD. Green = profit, red = loss.
PLS PRICECurrent PLS price in USD with 1h, 24h, 7d % change
SERVER pillGreen ● = bot running and connected. Red ○ = bot offline. Hover to see the active RPC endpoint URL. Orange when backup RPC is in use.
≡ menuHamburger menu on smaller screens — shows wallet button and overflow items

Price ticker

Scrolling bar below the header showing live prices for PLS and all active pairs with 1h, 24h, 7d % changes and direction arrows.

Navigation tabs

TabWhat it shows
⊞ ALL PAIRSOverview page — all pairs at a glance, combined P&L card, portfolio chart, weekly activity, recent trade history
EHEX / HEX / etc.Individual token detail page (one tab per active pair)
◀ ▶Scroll tabs when too many to fit in the header
✎ Auto-TuneOpens the auto-tune calibration and override panel

All Pairs overview page

Token Page

Click any pair tab in the navigation bar to open its detailed trading page. The page is split into a left column (grid levels + trade log) and a right column (chart + stats).

Left column header

Token name and icon. Market regime badge (GRID / TREND UP / TREND DOWN / DCA / HIGH VOL / PAUSED). Two action buttons: CALIBRATE (forces immediate recalibration) and AUTO-TUNE (opens the live override modal).

Price position bar

Horizontal bar showing where current price sits relative to the grid. Left edge = deepest buy level. Right edge = seed price. The dot marks current price. Shows current price, % from seed, and direction arrow.

Grid shift meter

Fills as price rises above seed toward the AUTO_SHIFT_PCT threshold. When full, the grid auto-reseeds upward. Shows "shift paused" when any level is filled (auto-shift only fires with zero filled levels).

Grid level cards

One card per level. Each card shows:

ElementMeaning
L3 −1.96%Level number and % offset below seed price
● 80.20 / $0.000059Buy trigger price in PLS and USD. ● = WAITING, ⚡ = FILLED
+0.46%Current price vs this level's trigger (positive = price is above trigger)
→ 81.44 / $0.000060Sell target price in PLS and USD
▲ 1.08%Distance from current price to sell target
FILL / WAIT badgeGreen FILL = filled and price above sell target. Orange FILL = filled, price below target. WAIT = waiting to buy.
tiers: ✓30% ●70%Partial tier status. ✓ = sold, ● = waiting to sell
⚡ stuck 8.7hStuck recovery active. Shows hours stuck and current reduced sell target.
Progress barHow far price is below the sell target. Fills as price approaches.
13% allocationThis level's share of the total pair budget
💰 SELL L3Manual sell button — appears on filled levels. Bypasses all guards, sells immediately at market.

Trade log (collapsible)

Bar at the bottom of the left column. Click to expand — the log fills the column and the grid levels are hidden. Click again to collapse. When expanded, filter buttons appear:

The trade log header shows today's confirmed buy and sell count (e.g. 2 buys · 1 sell). Trades are date-grouped. Today's group is expanded by default. Older dates are collapsible.

Right column — header buttons

ButtonWhat it does
PausePauses new buys. Existing positions still managed. Click again to resume. PAUSED badge appears on pair tab.
Sell AllSells ALL filled positions immediately at market price. Bot reseeds automatically after. Use to fully exit all positions.
ReseedReseeds grid at current price without selling. Use when price has moved far from the current seed.

Right column — Position & Stats

StatMeaning
Token HeldTotal tokens currently held across all filled levels
Allocated PLSTotal PLS budget for this pair with % spent bar
Realised PnLTotal confirmed profit from all completed sells
Budget LeftUnspent PLS remaining for future buys
Total Buys / SellsLifetime buy and sell transaction counts
Gas / MonthEstimated gas cost per month based on recent activity
Trades TodayBuys + sells executed since midnight
CyclesFull grid cycles completed
Auto ShiftsTimes the grid auto-shifted to a new price

Below stats: Weekly Trades bar chart (7-day trade count per day) and Last Cycles showing the most recent completed cycles with PnL and duration.

Water-Level Cards

The pair cards on the overview view feature an animated water level that visually represents the position's underwater/above-water status:

The water color is always blue. A stationary big +/- percent number appears in the bottom-right area:

Terminal Display

The bot also renders a live full-screen terminal display in the console window where it runs. This is useful when running on a VPS via SSH or for users who prefer text-only.

Header strip

💎 PULSEXBOT CORE   PULSECHAIN 369   6 PAIRS                 time 14:39:21   TOTAL P&L +572,461 PLS   WALLET 48,216,132 PLS  $367
RPC ● rpc.pulsechain.com  latency 222ms  fails 0/3                                                  backup: rpc-pulsechain.g4mm4.io
LICENSE  ✓ LICENSED  3 slots active  · 30,000 PXB held        10,000 PXB = 1 slot · add more to unlock extra pairs
PAIRS ● PRVX ◀ PROCESSING | ● EHEX | ● HEX | ● USDC | ● PDAI | ● WETH                              ● live  ○ stale  ◌ processing

The header has four rows: (1) bot identity, time, total P&L, wallet balance; (2) active RPC and health; (3) live license status (updates every second); (4) per-pair status indicators.

License row states

StateDisplay
Free trialLICENSE ✓ FREE TRIAL 47 days remaining · 1 slot active
Trial < 1 dayLICENSE ✓ FREE TRIAL 18h remaining · 1 slot active
LicensedLICENSE ✓ LICENSED 3 slots active · 30,000 PXB held
Grace periodLICENSE ⚠ GRACE PERIOD 19h remaining
Soft stopLICENSE ✗ SOFT STOP — BUYS PAUSED no PXB held
RPC errorLICENSE ⚠ PXB CHECK PENDING (RPC error — retrying)

Per-pair summary table

ColumnMeaning
● PAIRStatus dot (green = healthy) and pair symbol
MODECurrent mode: GRID, DCA, PAUSED, RESEED, IDLE, CALIBRATING
PRICE ▲/▼Current price + 1h direction arrow
$0.0…USD price
seedThe price the grid is anchored to
avgVolume-weighted average entry across filled levels
(±X%)Current price vs avg entry (red = underwater, green = profit)
✓ LIQ $XLiquidity check + USD pool size
PnL ±X PLSLifetime realized PnL for this pair
B/STotal buys/sells
cycCycles completed

Per-level table (focused pair)

ColumnMeaning
L#Level number (L1 = shallowest)
OFFOffset percent below seed (e.g. -2.1%)
BUY TRIGGERTrigger price (token / PLS)
USDTrigger price in USD
SELL TARGETTier 2's sell target (or for filled levels, the active target)
USDSell target in USD
DIST ▲/▼Distance from current price to trigger (▲ above, ▼ below)
P&LNet unrealized PnL on this level (only shown for FILLED levels)
ALLOCPLS allocated to this level

Footer

TOTALS B/S 23/26  TODAY 19  CYCLES 11  WALLET 48,216,132 PLS $367            dashboard http://localhost:5555

Aggregates across all pairs plus a reminder of the dashboard URL.


License System

PulseXBot uses the PXB token for licensing. Each pair you actively trade requires a slot, and slots are unlocked by holding PXB tokens in the bot's wallet. The license check happens on startup and periodically while running — no internet license server, no user accounts. Just on-chain verification.

Free Trial

Your first 60 days are completely free. One pair runs with full functionality — auto-tune, partial take-profits, Deep-DCA, dashboard, everything. No PXB required. The trial starts the first time you run the bot and is tracked in the .lic file in your bot folder.

After 60 days you get a 24-hour grace period, then new buys pause. Existing open positions continue to be managed — the bot will still sell them. To continue trading, acquire PXB tokens (see Buying PXB).

🚨
Do NOT edit the .lic file. It is cryptographically signed with your wallet address. Editing trialStart, graceSince, or any other field breaks the signature and triggers an immediate soft stop — new buys paused. The bot detects tampering on every startup and logs "LICENSE FILE TAMPERED". Deleting the file restarts your 60-day trial from today.
On macOS and Linux, files starting with a dot are hidden by default. To see the .lic file in Finder press Cmd+Shift+. — in a terminal it appears with ls -la.

Buying PXB Tokens

PXB trades on PulseX. The dashboard has a built-in "Buy PXB" modal that constructs the swap for you. Or buy directly on PulseX using PLS.

Once tokens are in your trading wallet, restart the bot. Slot count is read from balance on startup.

Slots Explained

Hold PXB in your trading wallet (same wallet as your .env private key). Slots are checked live — buying more PXB activates a new slot within seconds; selling PXB deactivates it.

PXB heldSlotsActive pairs
0 (trial)11 pair free for 60 days
10,000 PXB11 pair — forever while holding
20,000 PXB22 pairs
30,000 PXB33 pairs
60,000 PXB66 pairs
N × 10,000 PXBNN pairs — slots scale linearly with no cap

Slots are calculated as floor(PXB balance / 10,000) — there is no upper limit. Hold more PXB, run more pairs.

If you have fewer slots than configured pairs, extra pairs show a 🔒 Slot Required notice in the dashboard and do not trade.

PXB contract address: 0x24698062D05D4E38190751B4708111Ff3a3ea65C


Log Files

The bot creates two categories of log files: a session log in the bot folder capturing everything the terminal prints, and per-pair log files in each pair's log folder.

Session log (bot folder)

Every time the bot starts, it creates a timestamped session log file directly in the bot folder:

session-2026-06-03_02-18-00.log

This file captures every line that appears in the terminal — startup banners, pre-startup backup confirmations, RPC events, all pair log lines, warnings, errors, and shutdown messages — with a timestamp on each line. It is the complete record of that run. Files older than 14 days are auto-pruned on startup. If the dashboard terminal panel scrolls something off, this file always has it.

Per-pair log files (SYMBOL-grid-logs/)

Each pair creates its own log folder containing:

FileContentsBest for
trades.logFull timestamped log of every event — buys, sells, regime changes, auto-tune, warnings, errors, startup and backup messagesComplete history and debugging
errors.logWARN and ERR entries onlyFirst file to check when something seems wrong
trades.csvEvery confirmed buy and sell as a spreadsheet row: timestamp, type, level, price, tokens, PLS, PnL, gas, TX hashTax records, Excel analysis
daily-summary.logWritten at midnight: total buys, sells, PnL, gas, best/worst trade, regime breakdownDaily performance check
weekly-summary.logSame as daily but for the full week, written every MondayWeekly performance review
cycle-history.logOne entry per completed grid cycle: cycle number, start/end date, PnL, duration, trade countLong-term performance trends
auto-tune.csvOne row per calibration run: all parameters chosen and the ATR/liquidity values that drove themUnderstanding bot calibration decisions

Log files grow continuously. The bot rotates them automatically — old files are renamed with a date suffix and a maximum of 7 days of history is kept per pair.

💡
If something disappears from the dashboard terminal panel (which only shows the last 200 lines), open the current session-*.log file in your bot folder — it has the complete untruncated output for that session with timestamps on every line.

Security Checklist

🚨
Your .env file contains your private key. Anyone with this key has full control of your wallet. Protect it like a password.

Tips — Capital Sizing

Per-pair TOTAL_PLS is the budget the bot can spend on that pair. Wallet must hold:

min wallet = SUM(TOTAL_PLS for each pair) + SUM(RESERVE_PLS for each pair) + ~5,000 PLS gas

With auto-tune defaults at the BALANCED profile, RESERVE is 10% of TOTAL. So 5 pairs × 10M PLS = 50M for grids, plus 5M reserve = 55M minimum. Under-funding doesn't break anything but means deep-DCA may not fully deploy in extreme conditions.

Tips — Choosing Pairs

Grid bots make money on volatility within a range. Best pairs:

Tips — Running on VPS

For 24/7 operation, run the bot on a low-cost VPS rather than your home computer:

🚨
Do NOT expose port 5555 directly to the public internet. The dashboard has no authentication and includes Sell-All, Pause, and Reseed buttons. Use SSH tunneling.

Recovery from State Mismatch

If the dashboard shows a pair as PAUSED with a STATE MISMATCH alert, follow these steps:

  1. 1
    Stop the bot

    Close the bot window or Ctrl+C in the terminal. Wait for the graceful shutdown.

  2. 2
    Inspect the state file

    Open {pair}-grid-state.json in any text editor. Compare tokenBalance (wallet) against totalTokens (state's view) to understand the gap.

  3. 3
    Check the backup folder

    Look in state-backups/ for the best snapshot. Start with {pair}-grid-state.startup.json (taken right before the last restart). If that is the bad one, try the hourly or daily slots.

  4. 4
    Restore the backup

    Copy the chosen file over the live state file — rename it to {pair}-grid-state.json (remove the suffix). Keep a copy of the corrupt file for review before overwriting.

  5. 5
    Restart and resume

    Start the bot. The self-check should pass with the restored state. If the pair is still paused, click Resume on the dashboard.

Tips — Running on Linux 24/7

For unattended operation on a Linux VPS or server, keep the bot running after you close your SSH session using screen or nohup:

Using screen (recommended)

screen -S pulsexbot          # create a named session
./Start-PulseXBot.sh         # start the bot inside the session
# Press Ctrl+A then D        # detach — bot keeps running
screen -r pulsexbot          # reattach later to check on it

Using nohup

nohup ./Start-PulseXBot.sh > /dev/null 2>&1 &
# Check it's running:
ps aux | grep PulseXBot
💡
Access the dashboard from your home machine via SSH tunnel: ssh -L 5555:localhost:5555 user@your-vps-ip — then open http://localhost:5555 in your local browser. This keeps the dashboard private without exposing it to the internet.

Telegram Alerts

PulseXBot sends real-time alerts to your Telegram when key trading events happen — buys, sells, trail activations, low balance warnings, daily summaries, and more. No extra packages required — uses Node's built-in https module.

Setup

  1. Open Telegram → search @BotFather → send /newbot → follow prompts → copy the BOT_TOKEN
  2. Search @userinfobot → send any message → copy your CHAT_ID
  3. Open corebot-config.js and fill in the TELEGRAM section
  4. Restart the bot — you'll receive a startup message instantly
TELEGRAM: {
  BOT_TOKEN: "7123456789:AAHxxxxxxxxxxxxxxxxxxxxxxxx",
  CHAT_ID:   "123456789",
  BOT_NAME:  "PulseXBot",  // shown at top of every message
  ALERTS: {
    buys:         true,
    sells:        true,
    trailActive:  true,
    lowBalance:   true,
    rpcFailover:  true,
    stuckLevels:  false,
    botLifecycle: true,
    dailySummary: true,
  },
}
💡
Running multiple bots? Set a different BOT_NAME for each instance — e.g. "Bot DAI", "Bot HEX". Every message shows this name at the top so you always know which bot sent it.

Alert Types

AlertToggleWhat it shows
🟢 BUY FILLEDbuysPair, level, PLS spent, tokens received, fill price, sell target, TX link
🔴 30% FIXED SELLsellsReceived PLS, net P&L, %, USD value, gas, hold time, all-time P&L, TX link
🎯 70% TRAIL SELLsellsSame as fixed sell
🎯 TRAIL STOP FIREDtrailActiveExit price, peak price, drop % from peak, gain vs entry, hold time
🟡 TRAIL ACTIVEtrailActiveTrail just activated — unrealised P&L, current price, trail stop level
🎉 CYCLE COMPLETEsellsCycle P&L + USD, duration, all-time P&L, today P&L
🚧 SELL BLOCKEDsellsLoss guard blocked a sell — estimated loss amount. Max once/hour per level.
⏳ LEVEL STUCKstuckLevelsStuck reduction started — buy price, hold time, target ramp. Fires once per event.
⚠️ LOW BALANCElowBalanceWallet too low to open a new level — detail of what's needed
🔄 RPC SWITCHEDrpcFailoverBot switched to backup RPC endpoint
🔼 GRID AUTO-SHIFTEDbotLifecycleGrid recentred at new price — shows new seed price
✅ BOT STARTEDbotLifecycleAll active pairs with PLS allocation, risk profiles, license/trial status
🛑 BOT STOPPEDbotLifecycleBot received shutdown signal
📊 DAILY SUMMARYdailySummaryToday P&L, sells/buys/cycles, best sell, all-time P&L, win rate. Fires once per pair at midnight.
⛽ DAILY GAS REPORTdailySummaryCombined cross-pair message after all individual summaries: per-pair gas used + net P&L, total gas in PLS + USD across all pairs.
🗓 TRIAL REMINDERdailySummarySent daily if on free trial — days remaining, urgency increases near expiry
Set stuckLevels: false (default) unless you want to be notified every time a level's target starts reducing. Set BOT_TOKEN: "" to disable all Telegram alerts completely without removing the config block.

Updating the Bot

New versions are released as updated zip files on pulsexbot.com. Updating is safe — your positions, trade history, and config are preserved.

  1. 1
    Back up your state files

    Copy the *-grid-state.json files and the state-backups/ folder to a safe location. The bot backs these up daily but a manual backup before a major update is good practice.

  2. 2
    Stop the bot

    Close the bot window or press Ctrl+C in the terminal. Wait for the graceful shutdown message.

  3. 3
    Download the new version

    Download the latest zip for your platform from pulsexbot.com and extract it.

  4. 4
    Replace the bot binary only

    Copy PulseXBot.exe (Windows) or PulseXBot (Mac/Linux) from the new zip into your existing bot folder. Do not replace your .env, corebot-config.js, state files, or log folders — these stay exactly as they are.

  5. 5
    Restart the bot

    Start normally. State files are forward-compatible — existing positions and trade history survive the update. You will see the new version number in the terminal header.

💡
Check the pulsexbot.com changelog or Telegram community for release notes before updating — some updates include new config fields you may want to set.

Troubleshooting

"FATAL: PRIVATE_KEY not found in .env file"

Your .env file is missing, misnamed, or the PRIVATE_KEY= line is empty. Check: the file is named exactly .env (with dot, no other extension), it is in the same folder as the bot binary, and the value is exactly 64 hex characters with no spaces or 0x prefix.

Dashboard shows "connecting" / no data

Make sure the bot terminal window is still open and running. Try Ctrl+Shift+R in the browser to force a hard refresh. Try http://127.0.0.1:5555 instead of localhost. Check that the PORT in corebot-config.js matches the URL you are opening.

"execution reverted" errors in the log

Slippage is too tight. Increase SLIPPAGE_PERCENT by 0.5 in the config for that pair and restart. Also check pool liquidity on dexscreener.com/pulsechain.

Bot shows "SOFT STOP" badge

The 60-day trial has expired and no PXB is detected in the wallet. Click Buy PXB in the dashboard, or buy PXB manually on app.pulsex.com. After buying, click Recheck in the dashboard.

"LICENSE FILE TAMPERED" in the terminal

The .lic file was edited — its cryptographic signature no longer matches your wallet address. The bot signs the trial start date against your wallet on first run. Editing trialStart, graceSince, or any field breaks this signature and triggers an immediate soft stop.

Fix: Delete the .lic file. Your 60-day trial restarts from today. If your trial was already expired: buy 10,000 PXB — holding PXB bypasses the trial entirely and the bot detects it on the next PXB balance check.

SELL_LOSS_GUARD_PCT is blocking the sell because the estimated net result after gas and slippage would be a loss. This is intentional — the bot waits for price to recover. If you want to sell anyway regardless of P&L, click the SELL button on the level card — manual sells bypass the loss guard.

"pre-buy quote shows X% slippage — skipping"

The DEX quote before the buy was 3%+ worse than the last price. Usually means the market moved fast or liquidity is thin. The bot skips this tick and retries next tick. If it repeats, check pool liquidity or increase SLIPPAGE_PERCENT.

🔒 Slot Required on a pair

That pair needs a PXB slot. Buy PXB via the Buy PXB button in the dashboard (10,000 PXB per pair beyond the first). After buying, click Recheck.

"Insufficient wallet balance — skipping buy"

Your wallet balance is at or below RESERVE_PLS. Top up your wallet with more PLS, or reduce RESERVE_PLS. The dashboard shows a wallet warning banner when balance is critically low.

RPC errors / timeouts

The primary RPC is degraded. The bot auto-switches to the backup RPC. If errors persist, try changing RPC_URL in .env to a different endpoint from the list in .env Setup.

macOS: "cannot be opened — unidentified developer"

Run ./Start-PulseXBot.sh — it removes the quarantine flag automatically. Or: right-click PulseXBot → Open → click Open in the dialog that appears. One-time only.

Linux: "Permission denied"

Run chmod +x PulseXBot then try again. Or use Start-PulseXBot.sh which sets permissions automatically.


FAQ

Will the bot ever sell at a loss?

No, by default. The strict-zero loss guard blocks any sell whose net result (after gas and slippage) is below cost. Stuck-reduction will lower the target down to +1.5%, but the loss guard provides the absolute floor.

What happens if PulseChain RPC goes down?

The bot automatically switches to the backup RPC from your .env and continues. It also polls the primary every 5 minutes and switches back when it's healthy.

What if the bot crashes mid-trade?

State is persisted to disk on every state change. On restart, the bot loads the last known state and resumes. The startup self-check verifies wallet balances match state — if there's a mismatch (e.g. a swap completed but state didn't save), the bot pauses the pair for manual review rather than acting on stale data.

Can I run multiple instances on the same wallet?

No. Two instances would race on swap transactions and corrupt nonces. Run one bot per wallet. If you want to trade more pairs than your slot allows, use a separate wallet.

How do I know my data is safe?

Daily backups go to state-backups/ with 7-day retention. Plus log files (trades.log, errors.log, trades.csv) accumulate per pair so you can audit every action by hand.

Can the bot lose tokens?

Tokens never leave the wallet except via legitimate swaps the bot initiates. Even if the state file gets corrupted, your tokens stay on-chain. The seedGrid preservation system ensures positions are tracked through every reseed and recalibration.

What happens during the 24h auto-tune?

The bot pauses trading on that pair for ~3 minutes while it samples price and recomputes parameters. Existing filled levels are preserved across the recalibration — they'll be reattached to the new grid by closest-trigger-price match. You'll see ↪ Reattached preserved fill: L1 @ ... in the log when this happens.

How do I update the bot to a new version?

Stop the bot, replace the bot binary and supporting files with the new version (your .env, corebot-config.js, and state files stay untouched), restart. State files are forward-compatible — your positions and trade history survive. Always back up state files before a major version update.

What does the "stuck X.Xh — target reduced to +1.50%" log mean?

That level has been filled and waiting to sell for X hours. The stuck-reduction system has lowered its sell target. The level will sell when price reaches the reduced target, OR when the trail (if armed) triggers.

Why does my BUY card show "spent: 3,000,000 PLS"?

That's the actual amount of PLS sent to the swap, captured directly from the transaction. Older versions estimated this from price × tokens which was off by slippage; the current version reads the real value.

Why does a SELL card show "gas: 312 PLS (sell 200 + buy 112)"?

The total cost-of-trade includes both the sell transaction's gas AND the original buy's gas. Tier 1 sells charge the full buy gas; tier 2 (trail) sells show "buy 0" because tier 1 already covered it. This avoids double-counting.

What is the difference between Pause and Sell All?

Pause stops new buys but keeps managing existing filled positions — the bot will still sell them at their targets. Sell All immediately sells every filled position at market price and then reseeds the grid. Use Pause when you want to stop accumulating. Use Sell All when you want to fully exit.

What does CALIBRATE do vs AUTO-TUNE?

CALIBRATE forces an immediate recalibration run (~3 minutes) that re-measures ATR volatility and liquidity and recomputes all AUTO parameters. Use this after a major market move. AUTO-TUNE opens a panel where you can view and override individual parameters without triggering a full recalibration.

Why does my Deep-DCA reserve never activate?

All three conditions must be true simultaneously: (1) all main grid levels must be filled, (2) regime must be TREND_DOWN or DCA, and (3) RSI must be below DEEP_DCA_RSI_MAX. This triple gate is intentional — reserves are designed for genuine crashes, not normal dips. If you want them to fire more easily, increase DEEP_DCA_RSI_MAX or set RISK_PROFILE: "AGGRESSIVE".

Can I trade the same token on two different pairs?

No — each SYMBOL must be unique in the config. Running two pairs with the same token would cause state and accounting conflicts. Use one pair per token.

What does "1 buy · 1 sell" in the trade log header mean?

Today's count of confirmed trade fills — buy transactions with a ✓ checkmark and sell transactions with a ✓ checkmark since midnight. It counts completed transactions, not individual tier sells.

My trail fired and sold but the level card still shows "FILL"?

If you are using partial tiers (30%/70%), the card shows FILL until ALL tiers have sold. After Tier 1 (30%) sells, the card updates to show ✓30% ●70% — still FILLED because 70% is still open. It shows WAIT/recycles only after the final tier completes.

What does "⚠ L3 stuck CLOSED with no tokens on startup — recycling to WAITING" mean?

The bot found a level marked CLOSED (fully sold) that hadn't finished recycling — usually because the bot was restarted mid-process. The startup repair loop caught it and fixed it automatically. No action needed.

Why does the low balance alert disappear even though the wallet is low?

If all main grid levels are already filled, the wallet being low is expected — all capital is deployed and working. The bot suppresses the alert so you don't see a false alarm. The alert only appears when a main level is genuinely waiting to buy but can't afford to.

Is there a maximum number of pairs I can run?

No hard cap. Slots are calculated as floor(PXB balance / 10,000) with no upper limit. Hold more PXB, unlock more pairs. Each pair also uses ~150 MB RAM, so your machine's resources are the practical limit.

What is the 60-second TX deadline?

Every swap includes a 60-second on-chain expiry. If the transaction isn't included in a block within 60 seconds it auto-reverts — it will never execute at a stale price. The bot retries on the next tick. This protects against sandwich attacks and mempool congestion.