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
- 1Download for your platform
Click the download card above for your operating system.
- 2Extract the zip to a folder
Right-click → Extract All. Example:
C:\PulseXBot\on Windows,~/PulseXBot/on Mac/Linux. - 3Create your .env file
Copy
.env.examplein the bot folder, rename the copy to.env, open in any text editor, fill in your values. See .env Setup. - 4Configure your pairs
Open
corebot-config.jsin 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. - 5Start the bot
Windows: double-click
Start-PulseXBot.bat
macOS / Linux: open a terminal in the bot folder and run./Start-PulseXBot.sh - 6Open the dashboard
Navigate to
http://localhost:5555in your browser to see live prices, positions and P&L.
Requirements
- Windows 10 or 11 (64-bit)
- No other software needed
- macOS 12 or later
- Intel or Apple Silicon
- No other software needed
- Any modern x64 distro
- Ubuntu, Debian, Fedora
- No other software needed
Resources
| Resource | Detail |
|---|---|
| RAM | ~150 MB per running pair |
| Disk | ~100 MB for the bot, ~50 MB for logs (rotates automatically) |
| Network | Always-on internet, low-latency to PulseChain RPC |
| Wallet | Hot wallet funded with PLS (and optionally PXB tokens for licensing) |
| Browser | Any modern browser for the dashboard (Chrome, Firefox, Safari, Edge) |
Installation
🪟 Windows
- 1Download
PulseXBot-Setup.zip from pulsexbot.com
- 2Extract to a folder
Right-click the zip → Extract All. Example:
C:\PulseXBot\ - 3Create your .env file
Copy
.env.example→ rename to.env→ open in Notepad → fill in your private key. See .env Setup below. - 4Edit corebot-config.js
Open in Notepad or VSCode. Set your trading pairs and PLS budget.
- 5Start the bot
Double-click
Start-PulseXBot.bat— it launches the trading bot. - 6Open dashboard
Go to
http://localhost:5555in 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)
http://localhost:5555 in your browser to access the live dashboard.🍎 macOS (Intel + Apple Silicon)
- 1Download
PulseXBot-Setup-Mac.zip — works on all Macs (Intel and M1/M2/M3/M4)
- 2Unzip
Double-click the zip in Finder — it extracts automatically. Move the folder to your preferred location.
- 3Open Terminal in the folder
Right-click the folder → "New Terminal at Folder", or in Terminal:
cd ~/PulseXBot - 4Create your .env file
cp .env.example .env
Then edit.envin any text editor (Notes, TextEdit, VSCode). - 5Edit corebot-config.js
Open in any text editor and set your trading pairs.
- 6Start the bot
./Start-PulseXBot.sh
This makes the binary executable, removes the macOS quarantine flag automatically, and launches the bot. - 7Open dashboard
Go to
http://localhost:5555in your browser.
🐧 Linux
- 1Download
- 2Extract
unzip PulseXBot-Setup-Linux.zip -d ~/PulseXBot && cd ~/PulseXBot - 3Create .env
cp .env.example .env && nano .env - 4Edit corebot-config.js
nano corebot-config.js - 5Start the bot
./Start-PulseXBot.sh - 6Keep running 24/7
For VPS or unattended operation, use
screenortmuxto 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.
.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
.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
- Click the account icon in MetaMask
- Go to Settings → Security & Privacy
- Click Export Private Key
- Enter your MetaMask password
- Copy the key exactly — 64 characters (or 66 with the leading
0x)
Available RPC Endpoints
| URL | Notes |
|---|---|
| https://rpc.pulsechain.com | Official — use as primary |
| https://rpc-pulsechain.g4mm4.io | Community — good backup |
| https://pulsechain.publicnode.com | PublicNode alternative |
| https://rpc.pulsechain.g4mm4.io | Alternative |
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.
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
| Setting | What to put | Example |
|---|---|---|
TOKEN_ADDRESS | The contract address of the token you want to trade (from PulseX or PulseScan) | 0xefD766cCb38EaF1dfd701853BFCe31359239F305 |
SYMBOL | Short name of the token — used in logs and dashboard only | DAI |
TOTAL_PLS | How much PLS to allocate to this trading pair. Must be in your wallet before starting. | 4600000 |
TOKEN_DECIMALS | The 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"
}
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.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:
- 1Wallet check
The bot reads your PLS and token balances and logs them.
- 2Router 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.
- 3Auto-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.
- 4Grid seed
Buy levels are placed at calculated offsets below the current price. The grid is now live.
- 5Dashboard online
Open
http://localhost:5555in 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
| Status | Meaning |
|---|---|
| WAITING | Trigger price not yet reached. Bot is monitoring. |
| FILLED | Buy executed. Tokens are held; sell tiers are armed. |
| CLOSED | All sell tiers complete. Level recycles to WAITING immediately after the final sell confirms. |
| RESERVE | Deep-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 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:
- All main grid levels are already filled (regular budget exhausted)
- Market regime is DCA or TREND_DOWN (sustained downtrend)
- RSI is below the oversold threshold (default 25)
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.
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 stuck | Effect on sell target |
|---|---|
| 0–6 h | No reduction. Original target. |
| 6–30 h | Linear interpolation from original target down to STUCK_REDUCE_MIN_PCT. |
| 30+ h | Held 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:
- All MAIN grid levels have sold at least once this cycle
- All deep-DCA reserves that activated this cycle have also sold
- No levels are currently FILLED
- Total token balance is below dust threshold
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:
- On first run — fresh state, no prior calibration data
- Every 24 hours while the bot runs continuously (configurable via AUTOTUNE_RECAL_MS)
- On restart, only if the saved calibration is older than 24 hours
- On ATR regime shift — when volatility changes significantly from the calibrated baseline
- On RSI regime shift — when the market transitions between primary regimes (e.g. GRID → DCA)
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 group | Parameters set | Driven by |
|---|---|---|
| Grid | BUY_OFFSETS, level count, RESERVE_PLS | ATR volatility + risk profile |
| Sell & Trail | SELL_LEVELS (pct + portions), TRAIL_TRIGGER_PCT, TRAIL_DISTANCE_PCT, TRAIL_SELL_NOTIFY_PCT | ATR volatility |
| Risk | SELL_LOSS_GUARD_PCT, STOP_LOSS_PCT | Risk profile |
| Slippage | SLIPPAGE_PERCENT, SLIPPAGE_ALERT_PCT, MIN_LIQUIDITY_USD | Pool liquidity |
| Deep-DCA | DEEP_DCA_BUDGET_PCT, DEEP_DCA_OFFSETS, DEEP_DCA_RSI_MAX | ATR volatility + risk profile |
| Timing | BUY_COOLDOWN_MS, AUTO_SHIFT_PCT, AUTO_SHIFT_COOLDOWN_MS, RESEED_OFFSET_PCT, STAGGER_DELAY_MS | ATR volatility |
| Regime indicators | DCA_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_LEVELS | Risk profile |
| Stuck recovery | STUCK_REDUCE_START_HOURS, STUCK_REDUCE_MIN_PCT, STUCK_TRAIL_TIGHTEN | Risk profile |
| Freefall protection | FREEFALL_DROP_PCT, FREEFALL_CANDLES, FREEFALL_RECOVERY_PCT | ATR volatility |
| Capital stages | CAPITAL_STAGE_THRESHOLDS, CAPITAL_STAGE_MULTIPLIERS | Risk profile |
| Climb protection | CLIMB_SENSITIVITY_PCT, CLIMB_EXTRA_GAIN_PCT | ATR volatility |
| RSI sizing | RSI_OVERSOLD_LVL, RSI_OVERBOUGHT_LVL, RSI_OVERSOLD_MULT, RSI_OVERBOUGHT_MULT | Risk profile |
| Pyramid + compound | LEVEL_WEIGHTS, COMPOUND_PCT | Risk profile |
| Smart partial sells | MIN_VIABLE_PARTIAL_MULT | Fixed default (3×) |
| ATR-adaptive sells | ATR_ADAPTIVE_SELLS, sell target scaling, trail distance scaling | ATR volatility (same thresholds as spacing) |
| Stuck deploy | STUCK_DEPLOY_HOURS | Risk 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:
- Permanent override — replaces "AUTO" in the config permanently. Survives restarts.
- Temporary override — applies until the next auto-tune run or restart. Good for testing.
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:
| Regime | Conditions | Bot behavior |
|---|---|---|
| GRID | Price near MA20, normal volatility | Standard grid trading. All levels active. |
| TREND_UP | Price significantly above MA20, rising | Buys active but bot is cautious on deep levels. Grid may auto-shift upward. |
| TREND_DOWN | Price below MA20 by >0.5%, RSI < 50 | Buys still active. Deep-DCA reserves can activate if RSI also below threshold. |
| DCA | RSI below DEEP_DCA_RSI_MAX, sustained drop | Buy size boosted by DCA_BIAS_EXTRA_PCT. Deep-DCA reserve levels activate if all main levels filled. |
| HIGH_VOL | ATR above ATR_HIGH_VOL_PCT threshold | Skips the deepest HIGH_VOL_SKIP_DEEP_LEVELS levels to preserve capital. |
| PAUSED | Manual 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:
- If ATR is low (e.g. 0.1%), the bot tightens the grid (multiplier ~0.73x): a base offset of -2.1% becomes -1.53%
- If ATR is high (e.g. 0.5%), the bot widens the grid (multiplier ~1.2x): same -2.1% becomes -2.5%
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:
| Profile | Reserve | Deep-DCA % | Buy spacing |
|---|---|---|---|
| CONSERVATIVE | 200K PLS (min) | ~23% | 0.85x — tighter |
| BALANCED (default) | 200K PLS (min) | ~18% | 1.0x — neutral |
| AGGRESSIVE | 200K 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:
- Price hits 102.18 → sell 300,000 tokens immediately. Profit locked.
- Price continues to 103.35 → trail arms on remaining 700,000 tokens
- Price peaks at 106.00, then drops 1.2% → trail stop fires at 104.73
- Sell 700,000 tokens at 104.73. Total result: both tiers profitable.
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: 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:
- ALL main grid levels are filled (main budget fully deployed)
- Market regime is TREND_DOWN or DCA (sustained downtrend)
- 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)
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:
| Timeframe | Used for | Responds to |
|---|---|---|
| 5-minute RSI | Regime detection (GRID / DCA / HIGH_VOL / TREND_UP / TREND_DOWN) | Short-term momentum. Fast. |
| 1-hour RSI | Buy 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
- ATR regime shift — volatility moves significantly from the calibrated baseline (e.g. calm token suddenly becomes extremely volatile)
- RSI regime shift — market transitions between primary regimes (e.g. GRID → DCA, HIGH_VOL → GRID)
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-DCA | Stuck Deploy | |
|---|---|---|
| Trigger | All levels filled + RSI below DEEP_DCA_RSI_MAX | All levels filled for STUCK_DEPLOY_HOURS regardless of RSI |
| Purpose | Oversold market averaging | Extended 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:
- Pre-swap estimate — uses the DEX router's
getAmountsOutto predict the sell outcome including pool slippage - Full-cost accounting — includes the original buy gas (not just sell gas) and any unpaid buy gas from earlier tier sells
- 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:
- Sandwich-attack manipulation
- Stale liquidity (large LPs withdrawn between tick and tx)
- Flash crashes / pumps that move price meaningfully between tick and tx
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:
- Main WAITING level can't buy → real alert. A level needs funding and the wallet is short. Top up or wait for a sell.
- Only deep-DCA levels WAITING → uses the smaller deep-DCA allocation for the threshold, not the full main level alloc. Avoids false alarms on tiny reserve levels.
- All main levels FILLED → no alert. Capital is fully deployed and working. The wallet being low is expected — it recovers when any level sells.
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:
- 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.
- 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:
- Retries the balance check up to 3 times (3 seconds apart)
- Sends a Telegram alert: "SELL NOT CONFIRMED ON-CHAIN — retrying automatically"
- Throws an error, which restores the level to FILLED so the next tick retries the sell
- Keeps retrying indefinitely until the tokens are confirmed gone
- 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:
- CLOSED + no tokens — if a level is marked CLOSED but holds no tokens (sell completed but recycle didn't finish), it is recycled to WAITING automatically. A
WARNline appears in the log:⚠ L3 stuck CLOSED with no tokens on startup — recycling to WAITING - FILLED + all tiers sold — if a level is FILLED but all its sell tiers are marked sold (state inconsistency), the tiers are reset so the level can sell normally.
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:
- Network & dashboard — chain ID, router address, dashboard port. Rarely change.
- Global tuning — tick interval, CSV logging.
- 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: 369ROUTER_ADDRESS: "0x165C3410fC91EF562C50559f7d2289fEbed552d9"WPLS: "0xA1077a294dDE1B09bB078844df40758a5D0f9a27"USDC: "0x15D38573d2feeb82e7ad5187aB8c1D52810B1f07""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.HOST: "localhost"Example B (LAN-accessible):
HOST: "0.0.0.0"PORT: 5555Example B (alternative):
PORT: 8080TX_EXPLORER: "https://apphex.win/@/#/tx/"Global Settings
CHECK_INTERVAL_MS: 5000Example B (faster, 3 sec — for fewer pairs only):
CHECK_INTERVAL_MS: 3000Example C (slower, easier on RPC):
CHECK_INTERVAL_MS: 10000{pair}-grid-logs/trades.csv. Useful for spreadsheet analysis. Set to false if you don't need it.CSV_LOGGING: trueExample B (off):
CSV_LOGGING: falsePRICE_DECIMALS: 7Example B (more decimals for low-priced tokens):
PRICE_DECIMALS: 10CALIBRATION_MIN_MS: 120000Example B (default, 3 min):
CALIBRATION_MIN_MS: 180000Example C (5 min, more accurate):
CALIBRATION_MIN_MS: 300000CALIBRATION_MAX_MS: 360000Example B (10 min max):
CALIBRATION_MAX_MS: 600000CALIBRATION_MIN_SAMP: 10Example B (more samples for illiquid tokens):
CALIBRATION_MIN_SAMP: 20AUTOTUNE_RECAL_MS: 86400000Example B (12h, more adaptive):
AUTOTUNE_RECAL_MS: 43200000Example C (7 days, set-and-forget):
AUTOTUNE_RECAL_MS: 604800000STATE_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: "PRVX"Example B:
SYMBOL: "EHEX"Example C:
SYMBOL: "PLSX"TOKEN_ADDRESS: "0xf6f8db0aba00007681f8faf16a0fda1c9b030b11"Example B (EHEX):
TOKEN_ADDRESS: "0x57fde0a71132198BBeC939B98976993d8D89D225"TOKEN_DECIMALS: 18Example B (HEX-style):
TOKEN_DECIMALS: 8Example C (USDC/USDT):
TOKEN_DECIMALS: 6TOTAL_PLS: 1000000Example B (medium, 10M PLS):
TOTAL_PLS: 10000000Example C (large, 50M PLS):
TOTAL_PLS: 50000000RISK_PROFILE: "CONSERVATIVE"Example B (default, balanced):
RISK_PROFILE: "BALANCED"Example C (high risk, more capital deployed):
RISK_PROFILE: "AGGRESSIVE"Pair Settings — Grid
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: "AUTO"Example B (manual override, 500K PLS held):
RESERVE_PLS: 500000Example C (no reserve, deploy everything):
RESERVE_PLS: 0DEEP_DCA_BUDGET_PCT: "AUTO"Example B (15% reserved for crashes):
DEEP_DCA_BUDGET_PCT: 15Example C (disabled — all capital on main grid):
DEEP_DCA_BUDGET_PCT: 0DEEP_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: 25Example B (very oversold only):
DEEP_DCA_RSI_MAX: 20Example C (less strict):
DEEP_DCA_RSI_MAX: 30TOTAL_PLS even if every level fills simultaneously in DCA mode.DCA_BIAS_EXTRA_PCT: 10Example B (no boost, equal allocation):
DCA_BIAS_EXTRA_PCT: 0Example C (strong dip-buy, +25%):
DCA_BIAS_EXTRA_PCT: 25Pair Settings — Sells
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: "AUTO"Example B (early trail arming):
TRAIL_TRIGGER_PCT: 2.0Example C (late trail arming):
TRAIL_TRIGGER_PCT: 5.0TRAIL_DISTANCE_PCT: "AUTO"Example B (tight trail, exit on small reversal):
TRAIL_DISTANCE_PCT: 0.5Example C (wide trail, ride bigger moves):
TRAIL_DISTANCE_PCT: 1.5TRAIL_SELL_NOTIFY_PCT: 1.0Example B (notify earlier):
TRAIL_SELL_NOTIFY_PCT: 0.5Example C (notifications off — set to large number):
TRAIL_SELL_NOTIFY_PCT: 100Pair Settings — Safety
SELL_LOSS_GUARD_PCT: 0Example B (allow up to 0.5% loss):
SELL_LOSS_GUARD_PCT: -0.5Example C (allow up to 1% loss):
SELL_LOSS_GUARD_PCT: -1.0STOP_LOSS_PCT: 0Example B (pause if 20% underwater):
STOP_LOSS_PCT: 20Example C (pause if 35% underwater):
STOP_LOSS_PCT: 35SLIPPAGE_PERCENT: "AUTO"Example B (tight, deep liquidity):
SLIPPAGE_PERCENT: 0.3Example C (looser, low liquidity):
SLIPPAGE_PERCENT: 1.0SLIPPAGE_ALERT_PCT: 2.0Example B (warn earlier):
SLIPPAGE_ALERT_PCT: 1.0Example C (warn only on bad fills):
SLIPPAGE_ALERT_PCT: 5.0MIN_LIQUIDITY_USD: "AUTO"Example B (require strong liquidity):
MIN_LIQUIDITY_USD: 100000Example C (small caps OK):
MIN_LIQUIDITY_USD: 20000BUY_COOLDOWN_MS: "AUTO"Example B (1-minute lockout):
BUY_COOLDOWN_MS: 60000Example C (no cooldown — risky):
BUY_COOLDOWN_MS: 0AUTO_SHIFT_PCT: "AUTO"Example B (shift early):
AUTO_SHIFT_PCT: 1.5Example C (shift only on big breakouts):
AUTO_SHIFT_PCT: 5.0AUTO_SHIFT_COOLDOWN_MS: 300000Example B (10 min):
AUTO_SHIFT_COOLDOWN_MS: 600000Example C (1 hour):
AUTO_SHIFT_COOLDOWN_MS: 3600000RESEED_OFFSET_PCT: "AUTO"Example B (seed slightly above current):
RESEED_OFFSET_PCT: 0.5Example C (seed at current price):
RESEED_OFFSET_PCT: 0STAGGER_DELAY_MS: "AUTO"Example B (faster ticks, more RPC load):
STAGGER_DELAY_MS: 100Example C (slower, kinder to RPC):
STAGGER_DELAY_MS: 500Pair Settings — Indicators
MA_PERIOD: 20Example B (faster):
MA_PERIOD: 10Example C (slower):
MA_PERIOD: 50RSI_PERIOD: 14Example B (more reactive):
RSI_PERIOD: 9Example C (smoother):
RSI_PERIOD: 21ATR_PERIOD: 14Example B (faster):
ATR_PERIOD: 7Example C (smoother):
ATR_PERIOD: 28ATR_ADAPTIVE_SPACING: trueExample B (off, fixed offsets):
ATR_ADAPTIVE_SPACING: falseATR_LOW_VOL_PCT: "AUTO"Example B (manual, very calm):
ATR_LOW_VOL_PCT: 0.1Example C (manual, looser):
ATR_LOW_VOL_PCT: 0.3ATR_HIGH_VOL_PCT: "AUTO"Example B (manual):
ATR_HIGH_VOL_PCT: 1.0Example C (only extreme moves):
ATR_HIGH_VOL_PCT: 2.0ATR_MIN_SPACING_MULT: 0.7Example B (allow tighter):
ATR_MIN_SPACING_MULT: 0.5Example C (no tightening):
ATR_MIN_SPACING_MULT: 1.0ATR_MAX_SPACING_MULT: 1.3Example B (allow wider):
ATR_MAX_SPACING_MULT: 1.7Example C (no widening):
ATR_MAX_SPACING_MULT: 1.0HIGH_VOL_SKIP_DEEP_LEVELS: 2Example B (skip none, fill aggressively):
HIGH_VOL_SKIP_DEEP_LEVELS: 0Example C (skip 3 deepest, very cautious):
HIGH_VOL_SKIP_DEEP_LEVELS: 3false, 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.AUTO_TUNE: trueExample B (fully manual, advanced):
AUTO_TUNE: falsePair 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.
[0.222, 0.333, 0.444] — L3 gets 2× L1Equal (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× L1Math (BALANCED, 3,936,000 PLS main grid): L1=874K · L2=1,312K · L3=1,749K PLS
Override:
FREEFALL_DROP_PCT: 3.0FREEFALL_CANDLES: 12 ← 60-minute lookbackFREEFALL_RECOVERY_PCT: 0.8[0.30, 0.60, 0.85]Override:
CAPITAL_STAGE_THRESHOLDS: [0.35, 0.65, 0.90][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: 35RSI_OVERBOUGHT_LVL: 65Override:
RSI_OVERSOLD_MULT: 1.2Override:
RSI_OVERBOUGHT_MULT: 0.6Override:
CLIMB_SENSITIVITY_PCT: 1.5Override:
CLIMB_EXTRA_GAIN_PCT: 0.5STUCK_DEPLOY_HOURS: 72Override:
ATR_ADAPTIVE_SELLS: falsePosition 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)Override:
COMPOUND_PCT: 15 or COMPOUND_PCT: 0 to disablePair Settings — Stuck Reduction
STUCK_REDUCE_START_HOURS: 6Example B (start sooner, 3 hours):
STUCK_REDUCE_START_HOURS: 3Example C (start later, 12 hours):
STUCK_REDUCE_START_HOURS: 12STUCK_REDUCE_MIN_PCT: 1.5Example B (more aggressive exit, +1.0%):
STUCK_REDUCE_MIN_PCT: 1.0Example C (preserve more profit, +2%):
STUCK_REDUCE_MIN_PCT: 2.0STUCK_TRAIL_TIGHTEN: trueExample B (keep wide trail even when stuck):
STUCK_TRAIL_TIGHTEN: falseAdding 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:
| Token | Address | Decimals |
|---|---|---|
| HEX | 0x2b591e99afE9f32eAA6214f7B7629768c40Eeb39 | 8 |
| PLSX | 0x95B303987A60C71504D99Aa1b13B4DA07b0790ab | 18 |
| INC | 0x2fa878Ab3F87CC1C9737Fc071108F904c0B0C95d | 18 |
| EHEX | 0x57fde0a71132198BBeC939B98976993d8D89D225 | 8 |
| USDC | 0x15D38573d2feeb82e7ad5187aB8c1D52810B1f07 | 6 |
| WETH | 0x02DcdD04e3F455D838cd1249292C58f3B79e3C3C | 18 |
| PRVX | 0xF6f8Db0aBa00007681F8fAF16A0FDa1c9B030b11 | 18 |
| USDT | 0x0Cb6F5a34ad42ec934882A05265A7d5F59b51A2f | 6 |
Save and restart the bot. The new pair runs a fresh 3-minute calibration on first start.
Web Dashboard
Open the dashboard at http://localhost:5555 (or your configured PORT). It refreshes automatically every 2–5 seconds via WebSocket.
Header bar
| Element | Meaning |
|---|---|
| TOTAL P&L | Combined realised profit/loss across all pairs in PLS and USD. Green = profit, red = loss. |
| PLS PRICE | Current PLS price in USD with 1h, 24h, 7d % change |
| SERVER pill | Green ● = bot running and connected. Red ○ = bot offline. Hover to see the active RPC endpoint URL. Orange when backup RPC is in use. |
| ≡ menu | Hamburger 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
| Tab | What it shows |
|---|---|
| ⊞ ALL PAIRS | Overview 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-Tune | Opens the auto-tune calibration and override panel |
All Pairs overview page
- Combined P&L card — animated water-level visualisation of total portfolio P&L. Water rises as positions go underwater, falls as profit grows.
- Per-pair status cards — price, regime, P&L, level status, and quick-access Pause / Sell All / Reseed / Calibrate / Auto-Tune buttons
- Regime breakdown — how many pairs are in each market regime right now
- Portfolio P&L chart — combined 7-day realised P&L trend
- Recent trade history — unified buy/sell feed across all pairs. Click ⊞ FULL TRADE LOG to open a full-screen modal with every trade, filters (ALL / BUYS / SELLS / T1 ONLY / TRAIL ONLY / 🔄 CYCLES), sortable columns, per-pair P&L breakdown, and summary stats.
- 📊 SUMMARY button (header) — full portfolio modal: total value, session P&L, ROI, win rate, avg profit/sell, best/worst trade, avg hold time, weekly trade chart, and per-pair breakdown.
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:
| Element | Meaning |
|---|---|
| L3 −1.96% | Level number and % offset below seed price |
| ● 80.20 / $0.000059 | Buy 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.000060 | Sell target price in PLS and USD |
| ▲ 1.08% | Distance from current price to sell target |
| FILL / WAIT badge | Green 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.7h | Stuck recovery active. Shows hours stuck and current reduced sell target. |
| Progress bar | How far price is below the sell target. Fills as price approaches. |
| 13% allocation | This level's share of the total pair budget |
| 💰 SELL L3 | Manual 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:
- ALL — every log event (INFO, BUY, SELL, WARN, ERR)
- BUYS & SELLS — confirmed trade cards only
- BUYS — buy confirmations only (green)
- SELLS — sell confirmations only (red)
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
| Button | What it does |
|---|---|
| Pause | Pauses new buys. Existing positions still managed. Click again to resume. PAUSED badge appears on pair tab. |
| Sell All | Sells ALL filled positions immediately at market price. Bot reseeds automatically after. Use to fully exit all positions. |
| Reseed | Reseeds grid at current price without selling. Use when price has moved far from the current seed. |
Right column — Position & Stats
| Stat | Meaning |
|---|---|
| Token Held | Total tokens currently held across all filled levels |
| Allocated PLS | Total PLS budget for this pair with % spent bar |
| Realised PnL | Total confirmed profit from all completed sells |
| Budget Left | Unspent PLS remaining for future buys |
| Total Buys / Sells | Lifetime buy and sell transaction counts |
| Gas / Month | Estimated gas cost per month based on recent activity |
| Trades Today | Buys + sells executed since midnight |
| Cycles | Full grid cycles completed |
| Auto Shifts | Times 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:
- Low water (8% of card height) — when in profit (≥ +5% above avg entry). Position is well above water.
- Rising water — as profit shrinks toward zero, water rises smoothly.
- High water (~95%) — deeply underwater (below -15% from avg entry). Card is almost fully submerged.
- Wave animation speeds up when more underwater — choppier waters for stormier markets.
The water color is always blue. A stationary big +/- percent number appears in the bottom-right area:
- Green "ABOVE WATER" + percent — currently in profit on average
- Red "UNDER WATER" + percent — currently underwater on average
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
| State | Display |
|---|---|
| Free trial | LICENSE ✓ FREE TRIAL 47 days remaining · 1 slot active |
| Trial < 1 day | LICENSE ✓ FREE TRIAL 18h remaining · 1 slot active |
| Licensed | LICENSE ✓ LICENSED 3 slots active · 30,000 PXB held |
| Grace period | LICENSE ⚠ GRACE PERIOD 19h remaining |
| Soft stop | LICENSE ✗ SOFT STOP — BUYS PAUSED no PXB held |
| RPC error | LICENSE ⚠ PXB CHECK PENDING (RPC error — retrying) |
Per-pair summary table
| Column | Meaning |
|---|---|
| ● PAIR | Status dot (green = healthy) and pair symbol |
| MODE | Current mode: GRID, DCA, PAUSED, RESEED, IDLE, CALIBRATING |
| PRICE ▲/▼ | Current price + 1h direction arrow |
| $0.0… | USD price |
| seed | The price the grid is anchored to |
| avg | Volume-weighted average entry across filled levels |
| (±X%) | Current price vs avg entry (red = underwater, green = profit) |
| ✓ LIQ $X | Liquidity check + USD pool size |
| PnL ±X PLS | Lifetime realized PnL for this pair |
| B/S | Total buys/sells |
| cyc | Cycles completed |
Per-level table (focused pair)
| Column | Meaning |
|---|---|
| L# | Level number (L1 = shallowest) |
| OFF | Offset percent below seed (e.g. -2.1%) |
| BUY TRIGGER | Trigger price (token / PLS) |
| USD | Trigger price in USD |
| SELL TARGET | Tier 2's sell target (or for filled levels, the active target) |
| USD | Sell target in USD |
| DIST ▲/▼ | Distance from current price to trigger (▲ above, ▼ below) |
| P&L | Net unrealized PnL on this level (only shown for FILLED levels) |
| ALLOC | PLS 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).
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..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 held | Slots | Active pairs |
|---|---|---|
| 0 (trial) | 1 | 1 pair free for 60 days |
| 10,000 PXB | 1 | 1 pair — forever while holding |
| 20,000 PXB | 2 | 2 pairs |
| 30,000 PXB | 3 | 3 pairs |
| 60,000 PXB | 6 | 6 pairs |
| N × 10,000 PXB | N | N 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:
| File | Contents | Best for |
|---|---|---|
| trades.log | Full timestamped log of every event — buys, sells, regime changes, auto-tune, warnings, errors, startup and backup messages | Complete history and debugging |
| errors.log | WARN and ERR entries only | First file to check when something seems wrong |
| trades.csv | Every confirmed buy and sell as a spreadsheet row: timestamp, type, level, price, tokens, PLS, PnL, gas, TX hash | Tax records, Excel analysis |
| daily-summary.log | Written at midnight: total buys, sells, PnL, gas, best/worst trade, regime breakdown | Daily performance check |
| weekly-summary.log | Same as daily but for the full week, written every Monday | Weekly performance review |
| cycle-history.log | One entry per completed grid cycle: cycle number, start/end date, PnL, duration, trade count | Long-term performance trends |
| auto-tune.csv | One row per calibration run: all parameters chosen and the ATR/liquidity values that drove them | Understanding 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.
session-*.log file in your bot folder — it has the complete untruncated output for that session with timestamps on every line.Security Checklist
.env file contains your private key. Anyone with this key has full control of your wallet. Protect it like a password.- ☐ Using a dedicated trading wallet — not your main or hardware wallet
- ☐ Trading wallet holds only the PLS you intend to trade plus a gas buffer
- ☐
.envfile is NOT shared with anyone - ☐
.envfile is NOT uploaded to GitHub, Google Drive, Dropbox, or any cloud - ☐
.envfile is NOT in a folder that auto-syncs (OneDrive, iCloud, Dropbox) - ☐ Private key is NOT typed into
corebot-config.jsor any other file - ☐
RESERVE_PLSis set to at least 10% ofTOTAL_PLS - ☐ Dashboard is NOT exposed to the public internet (use SSH tunnel or
localhost) - ☐ Only trading with funds you can afford to lose
- ☐ Bot is running on a machine you control, not shared or public
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:
- Liquid — at least $50K USD pool, ideally $200K+
- Volatile — daily ranges of 2–10% are ideal
- Mean-reverting — rangy tokens (most established PulseChain assets) work better than parabolic memecoins
- Not bleeding — avoid tokens in sustained downtrends; the bot will keep buying as price drops and you'll be holding bags
Tips — Running on VPS
For 24/7 operation, run the bot on a low-cost VPS rather than your home computer:
- $5/month VPS is plenty (1 vCPU, 1 GB RAM)
- Use
screenortmuxto keep the bot running across SSH disconnects (see Linux 24/7 tips) - Bind dashboard to
HOST: "0.0.0.0"and access via SSH tunnel:ssh -L 5555:localhost:5555 user@vps - Or stick with
HOST: "localhost"and use a port-forwarding SSH tunnel — keeps dashboard private - Pick a VPS region geographically close to where PulseChain RPC endpoints are hosted (typically US East / EU)
Recovery from State Mismatch
If the dashboard shows a pair as PAUSED with a STATE MISMATCH alert, follow these steps:
- 1Stop the bot
Close the bot window or Ctrl+C in the terminal. Wait for the graceful shutdown.
- 2Inspect the state file
Open
{pair}-grid-state.jsonin any text editor. ComparetokenBalance(wallet) againsttotalTokens(state's view) to understand the gap. - 3Check 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. - 4Restore 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. - 5Restart 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
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
- Open Telegram → search @BotFather → send
/newbot→ follow prompts → copy the BOT_TOKEN - Search @userinfobot → send any message → copy your CHAT_ID
- Open
corebot-config.jsand fill in theTELEGRAMsection - 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,
},
}
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
| Alert | Toggle | What it shows |
|---|---|---|
| 🟢 BUY FILLED | buys | Pair, level, PLS spent, tokens received, fill price, sell target, TX link |
| 🔴 30% FIXED SELL | sells | Received PLS, net P&L, %, USD value, gas, hold time, all-time P&L, TX link |
| 🎯 70% TRAIL SELL | sells | Same as fixed sell |
| 🎯 TRAIL STOP FIRED | trailActive | Exit price, peak price, drop % from peak, gain vs entry, hold time |
| 🟡 TRAIL ACTIVE | trailActive | Trail just activated — unrealised P&L, current price, trail stop level |
| 🎉 CYCLE COMPLETE | sells | Cycle P&L + USD, duration, all-time P&L, today P&L |
| 🚧 SELL BLOCKED | sells | Loss guard blocked a sell — estimated loss amount. Max once/hour per level. |
| ⏳ LEVEL STUCK | stuckLevels | Stuck reduction started — buy price, hold time, target ramp. Fires once per event. |
| ⚠️ LOW BALANCE | lowBalance | Wallet too low to open a new level — detail of what's needed |
| 🔄 RPC SWITCHED | rpcFailover | Bot switched to backup RPC endpoint |
| 🔼 GRID AUTO-SHIFTED | botLifecycle | Grid recentred at new price — shows new seed price |
| ✅ BOT STARTED | botLifecycle | All active pairs with PLS allocation, risk profiles, license/trial status |
| 🛑 BOT STOPPED | botLifecycle | Bot received shutdown signal |
| 📊 DAILY SUMMARY | dailySummary | Today P&L, sells/buys/cycles, best sell, all-time P&L, win rate. Fires once per pair at midnight. |
| ⛽ DAILY GAS REPORT | dailySummary | Combined cross-pair message after all individual summaries: per-pair gas used + net P&L, total gas in PLS + USD across all pairs. |
| 🗓 TRIAL REMINDER | dailySummary | Sent daily if on free trial — days remaining, urgency increases near expiry |
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.
- 1Back up your state files
Copy the
*-grid-state.jsonfiles and thestate-backups/folder to a safe location. The bot backs these up daily but a manual backup before a major update is good practice. - 2Stop the bot
Close the bot window or press
Ctrl+Cin the terminal. Wait for the graceful shutdown message. - 3Download the new version
Download the latest zip for your platform from pulsexbot.com and extract it.
- 4Replace the bot binary only
Copy
PulseXBot.exe(Windows) orPulseXBot(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. - 5Restart 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.
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.