输入/搜索内容
内置函数
结构体
内置变量与常量
通用约定
交易所
能力矩阵
中心化交易所
去中心化交易所
Hyperliquid
Lighter
edgeX
Aster
Aevo
Pendle
WOOFi Pro
Uniswap / PancakeSwap
Aerodrome / Velodrome
KyberSwap
1inch
EVM DEX通用指令
Jupiter
OKX DEX
DEX策略示例
LP自动调仓
Gauge质押复投
DEX与CEX搬砖
Jupiter限价单网格
DEX定投
pump.fun打新策略
预测市场
证券与期货
链上与自定义接入

极高风险,仅供学习与改写:发现pump.fun上刚创建的币,按条件过滤后以固定金额在联合曲线上买入,触发止盈、止损或达到最长持有时间时全部卖出。

做法

使用exchange.IO("pump.*", ...)指令:

  1. 每POLL_SEC秒调用pump.new,发现策略启动后新创建的币。
  2. 过滤:只买以SOL计价、且不属于mayhem或cashback类型的币;创建时间不超过MAX_AGE_SEC秒;创建者在创建交易中的首笔买入不超过MAX_DEV_BUY_SOL;pump.info返回的曲线进度不超过MAX_PROGRESS%,且曲线尚未完成。
  3. 买入:pump.buy(mint, BUY_SOL, {slippage, priorityFee})。资金护栏:同时最多持有MAX_POSITIONS个仓位,累计买入不超过MAX_TOTAL_SOL。
  4. 持仓:用pump.quote按曲线估算全部卖出可得的SOL(已毕业的币改用Jupiter报价);盈利达到TAKE_PROFIT_PCT%、亏损达到STOP_LOSS_PCT%或持有超过MAX_HOLD_MIN分钟时,用pump.sell(mint, "all")全部卖出。
  5. 状态栏:显示发现与跳过的数量、累计买入、已平仓数与已实现盈亏,以及各持仓的成本、现值、盈亏与持有时间。

交易所对象

一个Jupiter交易所对象(使用专用钱包),钱包中只放少量SOL。公共节点限流且延迟高,抢新时请配置自己的付费节点。

参数
参数默认值说明
BUY_SOL0.01每个币的买入金额(SOL,含协议费与创作者费)
MAX_POSITIONS3同时持有的最大币数
MAX_TOTAL_SOL0.1累计买入上限(SOL)
MAX_AGE_SEC30只买创建时间不超过该秒数的币
MAX_DEV_BUY_SOL1创建者首买超过该数量SOL时跳过
MAX_PROGRESS20曲线进度超过该百分比时跳过
TAKE_PROFIT_PCT50止盈(%)
STOP_LOSS_PCT30止损(%)
MAX_HOLD_MIN30最长持有时间(分钟)
SLIPPAGE0.2买卖滑点
PRIORITY_FEE0.0005每笔交易的优先费(SOL)
POLL_SEC5轮询间隔(秒)
DRY_RUNtrue为true时只模拟,不发送交易

风险
  • 绝大多数新币会很快归零,创作者或捆绑钱包随时可能砸盘(rug pull);名称和符号可以冒充知名项目,请以mint地址为准。
  • 抢新机器人与MEV竞争激烈,滑点设置过大容易遭到三明治攻击(被夹),以最差价格成交;流动性枯竭时,止损可能无法按预期价格卖出。
  • 每次买卖都需支付协议费、创作者费、网络费与优先费。
  • 只投入可以承受全部亏损的小额资金。请先阅读Jupiter交易所页面的「Pump.fun打新」一节。

DRY_RUN与实盘

DRY_RUN为true(默认)时不发送交易:买入使用pump.buy的dryRun选项模拟(钱包中没有SOL时模拟会报错,属正常现象),并按报价记录纸面持仓。由于模拟买入并未真实发生,曲线中并没有这些币,因此纸面持仓的现值按pump.info的现价 × 数量估算,并扣除协议费与创作者费(已毕业的币仍用pump.quote);止盈止损照常计算,卖出只记录日志。将DRY_RUN改为false即为实盘,建议先使用最小的BUY_SOL和MAX_TOTAL_SOL。

示例

完整策略代码(DRY_RUN = true 时仅模拟运行,不发送交易)。

javascript
/* * pump.fun 打新(Solana,范例策略)—— 极高风险,仅供学习改写 * * 用 Jupiter 交易所对象的 pump.* 指令:轮询 pump.new 发现刚在 pump.fun 上创建的币,按条件过滤后用固定 * 金额在联合曲线上买入(pump.buy),持仓期间用 pump.quote 按曲线估算全部卖出可得的 SOL,达到止盈、止损或 * 最长持有时间就全部卖出(pump.sell(mint, "all"))。 * * 过滤条件:只买以 SOL 计价、不是 mayhem / cashback 的币;创建时间在 MAX_AGE_SEC 秒以内;创建者在创建交易里 * 的首买不超过 MAX_DEV_BUY_SOL;曲线进度不超过 MAX_PROGRESS%。资金护栏:同时最多 MAX_POSITIONS 个持仓, * 累计买入不超过 MAX_TOTAL_SOL。 * * DRY_RUN = true(默认)不发交易:买入用 pump.buy 的 dryRun 选项模拟(钱包没有 SOL 时模拟报错,属正常), * 按 pump.quote 的报价记纸面持仓,止盈止损照常计算,卖出只记日志。 * * 风险(请先读交易所文档「Pump.fun打新」): * - 绝大多数新币很快归零,创作者或捆绑钱包随时砸盘(rug pull);名称、符号可以冒充知名项目,以 mint 为准; * - 抢新机器人与 MEV 竞争激烈,滑点设得大会被夹,按最差价成交;止损在流动性枯竭时可能卖不出预期价格; * - 协议费、创作者费、网络费与优先费每次买卖都要付;公共节点限流、延迟高,抢新请配置自己的付费节点。 * 只用可以全部亏掉的小钱。 * * 用法:添加 Jupiter 交易所对象(专用钱包),钱包里放少量 SOL。 */ // ---------------- 参数 ---------------- var BUY_SOL = 0.01 // 每个币买入的 SOL(含协议费与创作者费) var MAX_POSITIONS = 3 // 同时最多持有几个币 var MAX_TOTAL_SOL = 0.1 // 累计买入上限(SOL) var MAX_AGE_SEC = 30 // 只买创建不超过这么多秒的币 var MAX_DEV_BUY_SOL = 1 // 创建者首买超过这么多 SOL 的跳过 var MAX_PROGRESS = 20 // 曲线进度超过这么多 % 的跳过 var TAKE_PROFIT_PCT = 50 // 止盈(%) var STOP_LOSS_PCT = 30 // 止损(%) var MAX_HOLD_MIN = 30 // 最长持有(分钟) var SLIPPAGE = 0.2 // 买卖滑点 var PRIORITY_FEE = 0.0005 // 每笔交易的优先费(SOL) var POLL_SEC = 5 // 轮询间隔(秒) var DRY_RUN = true // true 只模拟,不发交易 var KEY = DRY_RUN ? "pump_sniper_paper" : "pump_sniper" var S = null // {positions: {mint: {symbol, tokens, cost, time}}, spent, closed, realized} var seen = {} var skipped = 0 function fmt(x, d) { return x === null || x === undefined || isNaN(x) ? "-" : Number(x).toFixed(d === undefined ? 2 : d) } // 过滤;通过返回 null,否则返回原因 function reject(c) { if (c.quote !== "SOL" || c.mayhem || c.cashback) return "非 SOL 计价 / mayhem / cashback" if (Date.now() - c.time > MAX_AGE_SEC * 1000) return "太旧" if (c.devBuy && (c.devBuy.quoteAmount === null || c.devBuy.quoteAmount > MAX_DEV_BUY_SOL)) return "创建者首买过大" var info = exchange.IO("pump.info", c.mint) if (!info) return "pump.info 失败:" + GetLastError() if (info.complete || info.progress > MAX_PROGRESS) return "曲线进度 " + fmt(info.progress, 1) + "%" return null } function buy(c) { var opts = { slippage: SLIPPAGE, priorityFee: PRIORITY_FEE } if (DRY_RUN) { opts.dryRun = true var sim = exchange.IO("pump.buy", c.mint, BUY_SOL, opts) if (!sim) { Log("模拟买入出错", c.symbol, GetLastError()); return } Log("DRY_RUN 买入", c.symbol, c.mint, BUY_SOL, "SOL → 约", fmt(sim.expected.tokenAmount, 0), sim.ok ? "(模拟通过)" : "(模拟未通过:" + sim.simulationError + ")") S.positions[c.mint] = { symbol: c.symbol, tokens: sim.expected.tokenAmount, cost: BUY_SOL, time: Date.now() } } else { var r = exchange.IO("pump.buy", c.mint, BUY_SOL, opts) if (!r) { Log("买入失败", c.symbol, GetLastError(), "#FF0000"); return } Log("买入", c.symbol, c.mint, r.solAmount, "SOL →", r.tokenAmount, r.txHash, "#00AA00") S.positions[c.mint] = { symbol: c.symbol, tokens: r.tokenAmount, cost: r.solAmount, time: Date.now() } } S.spent += BUY_SOL } // 全部卖出可得的 SOL。实盘用 pump.quote 按曲线精确报价;DRY_RUN 的买入没有真的发生,曲线里没有这些币, // 按曲线报价卖不出去,所以按现价 × 数量 − 费率估算(已毕业的币仍用 pump.quote,它改走 Jupiter) function sellValue(mint, p) { if (DRY_RUN) { var info = exchange.IO("pump.info", mint) if (info && info.price !== null) return info.price * p.tokens * (1 - (info.fees.protocolBps + info.fees.creatorBps) / 10000) } var q = exchange.IO("pump.quote", mint, "sell", p.tokens) return q ? q.amountOut : null } // 检查一个持仓:返回状态栏的一行 function manage(mint) { var p = S.positions[mint] var value = sellValue(mint, p) if (value === null) return [p.symbol, mint, fmt(p.cost, 4), "-", "-", fmt((Date.now() - p.time) / 60000, 1), "报价失败:" + GetLastError()] var pct = (value / p.cost - 1) * 100 var age = (Date.now() - p.time) / 60000 var why = pct >= TAKE_PROFIT_PCT ? "止盈" : pct <= -STOP_LOSS_PCT ? "止损" : age >= MAX_HOLD_MIN ? "到时" : "" if (why) { Log(why, p.symbol, mint, "卖出约", fmt(value, 4), "SOL", fmt(pct, 1) + "%", "#FF9900") var out = value if (!DRY_RUN) { var r = exchange.IO("pump.sell", mint, "all", { slippage: SLIPPAGE, priorityFee: PRIORITY_FEE }) if (!r) { Log("卖出失败", p.symbol, GetLastError(), "#FF0000"); return [p.symbol, mint, fmt(p.cost, 4), fmt(value, 4), fmt(pct, 1) + "%", fmt(age, 1), "卖出失败,下轮重试"] } out = r.solAmount } S.realized += out - p.cost S.closed++ delete S.positions[mint] } return [p.symbol, mint, fmt(p.cost, 4), fmt(value, 4), fmt(pct, 1) + "%", fmt(age, 1), why || "持有"] } function main() { if (exchange.GetName() !== "Jupiter") throw new Error("请添加 Jupiter 交易所对象,当前是 " + exchange.GetName()) S = _G(KEY) || { positions: {}, spent: 0, closed: 0, realized: 0 } var start = Date.now() while (true) { try { var coins = exchange.IO("pump.new", { limit: 10, since: start }) if (!coins) throw new Error("pump.new failed: " + GetLastError()) coins.forEach(function (c) { if (seen[c.mint]) return seen[c.mint] = true if (Object.keys(S.positions).length >= MAX_POSITIONS || S.spent + BUY_SOL > MAX_TOTAL_SOL) { skipped++; return } var why = reject(c) if (why) { skipped++; return } buy(c) }) var rows = Object.keys(S.positions).map(manage) _G(KEY, S) LogStatus(_D(), "已发现", Object.keys(seen).length, "个新币,跳过", skipped, ",累计买入", fmt(S.spent, 4), "/", MAX_TOTAL_SOL, "SOL,已平仓", S.closed, "个,已实现盈亏", fmt(S.realized, 4), "SOL", DRY_RUN ? "(DRY_RUN 纸面)" : "", "\n`" + JSON.stringify({ type: "table", title: "持仓", cols: ["币", "mint", "成本 SOL", "现值 SOL", "盈亏", "持有分钟", "状态"], rows: rows }) + "`") } catch (e) { Log("本轮出错:", e.message || e, "#FF0000") } Sleep(POLL_SEC * 1000) } }

参考