npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rki-js/sdk

v1.0.0

Published

RKI - RSI & KD Phase Identification System SDK

Readme

@rki-js/sdk

RSI & KD 阶段识别系统 — 市场阶段分析 TypeScript SDK。


目录


安装

npm install @rki-js/sdk
# 或
pnpm add @rki-js/sdk

运行环境: Node.js >= 22.0.0,支持 ESM 和 CJS 双格式。


快速上手

批量处理历史数据

import { processBars, createBinanceAdapter } from '@rki-js/sdk'

// 获取历史 K 线数据
const adapter = createBinanceAdapter()
const bars = await adapter.fetchOHLCV('BTCUSDT', '4h', { limit: 300 })

// 批量计算所有 bar 的指标
const { snapshots } = processBars(bars)

// 获取最新结果
const latest = snapshots[snapshots.length - 1]
console.log(`综合市场阶段: ${latest.marketStage}`) // -8 到 +8
console.log(`RSI: ${latest.rsiVal.toFixed(1)}, K: ${latest.kVal.toFixed(1)}`)
console.log(`回调轮数: ${latest.pullbackRounds}`)
console.log(`预测价格: ${latest.predPrice.toFixed(2)}`)

逐 bar 实时处理

import { createInitialState, processBar } from '@rki-js/sdk'
import type { OHLCVBar } from '@rki-js/sdk'

const { state: initialState, config } = createInitialState()
let state = initialState

function onNewBar(bar: OHLCVBar) {
  const result = processBar(state, bar, config)
  state = result.state // 更新状态以处理下一根 bar
  console.log(result.snapshot.marketStage) // 综合阶段
}

自定义配置

import { processBars } from '@rki-js/sdk'

const { snapshots } = processBars(bars, {
  kd: { kd_k_len: 9, kd_ob: 75 },   // 覆盖 KD 参数
  rsi: { rsi_len: 21, rsi_ob: 65 },  // 覆盖 RSI 参数
})

API 概览

核心引擎

import { createInitialState, processBar, processBars } from '@rki-js/sdk'

createInitialState(config?)

创建初始 RKI 状态和已合并的配置对象。

createInitialState(config?: Partial<RKIConfig>): { state: RKIState, config: RKIConfig }

processBar(state, bar, config)

处理单根 K 线,返回新的不可变状态和当前快照。

processBar(state: RKIState, bar: OHLCVBar, config: RKIConfig): { state: RKIState, snapshot: RKISnapshot }

每 bar 执行顺序(与 Pine Script 完全一致):

  1. 价格变动 → RSI gains/losses RMA → RSI 值 → RSI MA(SMA)
  2. 高低价窗口 → Stochastic %K → %D(K 的 SMA)
  3. KD 阶段状态机更新
  4. RSI 阶段状态机更新
  5. 综合市场阶段合并(calcStage → synthesize)
  6. 回调轮数计数器更新
  7. 价格预测(二分法,50 次迭代)
  8. 构建快照并更新 prev 值

processBars(bars, config?)

批量处理所有 K 线,返回每 bar 的快照数组和最终状态。

processBars(bars: OHLCVBar[], config?: Partial<RKIConfig>): { state: RKIState, snapshots: RKISnapshot[] }

数据适配器

import { createBinanceAdapter, createOKXAdapter } from '@rki-js/sdk'

Binance 适配器

const binance = createBinanceAdapter()

// 基础用法
const bars = await binance.fetchOHLCV('BTCUSDT', '4h', { limit: 500 })

// 时间范围
const bars2 = await binance.fetchOHLCV('BTCUSDT', '1h', {
  limit: 200,
  startTime: Date.now() - 7 * 24 * 60 * 60 * 1000, // 7天前
  endTime: Date.now(),
})

支持的 interval: 1s 1m 3m 5m 15m 30m 1h 2h 4h 6h 8h 12h 1d 3d 1w 1M

OKX 适配器

const okx = createOKXAdapter()
const bars = await okx.fetchOHLCV('BTC/USDT', '4h', { limit: 100 })

支持的 interval: 1m 3m 5m 15m 30m 1H 2H 4H 6H 12H 1D 3D 1W 1M(传入小写 4h 会自动转为 4H

自定义适配器

import type { DataAdapter, OHLCVBar } from '@rki-js/sdk'

const myAdapter: DataAdapter = {
  async fetchOHLCV(symbol, interval, options): Promise<OHLCVBar[]> {
    const raw = await fetchFromMyAPI(symbol, interval)
    return raw.map(r => ({
      time:   r.ts,
      open:   r.o,
      high:   r.h,
      low:    r.l,
      close:  r.c,
      volume: r.v,
    }))
  },
}

可视化工具

import { getStageText, getStageColor, getBarHeight, getPullbackColor } from '@rki-js/sdk'

| 函数 | 入参 | 返回值示例 | |---|---|---| | getStageText(stage) | marketStage (-8 到 +8) | 'R:TD''K:BA''—' | | getStageColor(stage) | marketStage (-8 到 +8) | '#2265D4''#FFFFFF' | | getBarHeight(stage) | marketStage (-8 到 +8) | 6(最大)、0(中性) | | getPullbackColor(rounds) | pullbackRounds (0+) | '#37F053''#EF4444' |

// 阶段标签
getStageText(8)     // 'R:TD'
getStageText(-3)    // 'K:BA'
getStageText(0)     // '—'

// 颜色(HEX)— RSI 阶段(偶数)为蓝紫色,KD 阶段(奇数)为黄色,顶部和底部使用相同配色
getStageColor(8)    // '#2265D4'  RSI 出货(深蓝)
getStageColor(-8)   // '#2265D4'  RSI 启动(深蓝)
getStageColor(7)    // '#E8B61A'  KD 出货(黄色)
getStageColor(0)    // '#FFFFFF'  中性(白色)

// 信号条高度 (1-6)
getBarHeight(8)     // 6
getBarHeight(4)     // 4
getBarHeight(1)     // 3
getBarHeight(0)     // 0

// 回调轮数颜色
getPullbackColor(0) // '#37F053'  绿
getPullbackColor(1) // '#F59E0B'  橙
getPullbackColor(2) // '#EF4444'  红
getPullbackColor(3) // '#DC2626'  深红

颜色对照表:

| 阶段值 | 颜色 | | ---------------- | ---------------- | | ±8 (R:TD / R:BB) | #2265D4 深蓝 | | ±6 (R:TE / R:BR) | #9022D4 紫 | | ±4 (R:TB / R:BA) | #73A0E8 浅蓝 | | ±2 (R:TI / R:BP) | #C2D5F5 最浅蓝 | | ±7 (K:TD / K:BB) | #E8B61A 黄 | | ±5 (K:TE / K:BR) | #B5E81A 黄绿 | | ±3 (K:TB / K:BA) | #F0CF6A 浅黄 | | ±1 (K:TI / K:BP) | #F9EABE 最浅黄 |


价格预测

import { predictRSIAtPrice, findRSIMACrossPrice } from '@rki-js/sdk'

predictRSIAtPrice(targetPrice, currentClose, gains, losses, rsiLen)

给定目标收盘价,预测下一根 bar 结束后的 RSI 值。

使用 RMA 更新公式:

  • newGain = alpha * max(Δp, 0) + (1 - alpha) * currentGains
  • newLoss = alpha * max(-Δp, 0) + (1 - alpha) * currentLosses
  • predictedRSI = 100 - 100 / (1 + newGain / newLoss)
predictRSIAtPrice(
  targetPrice:  number,  // 假设的下一 bar 收盘价
  currentClose: number,  // 当前收盘价
  rsiGains:     number,  // 当前 RMA gains
  rsiLosses:    number,  // 当前 RMA losses
  rsiLen:       number,  // RSI 周期
): number

findRSIMACrossPrice(rsiVal, rsiMaVal, close, gains, losses, rsiLen)

二分法求解 RSI 等于 RSI MA 时所对应的未来价格(最多 50 次迭代,精度 0.5)。

  • 当 RSI > MA:在 [close * 0.3, close] 区间搜索(价格需下跌)
  • 当 RSI < MA:在 [close, close * 2.0] 区间搜索(价格需上涨)
  • 当 RSI == MA:返回 NaN
findRSIMACrossPrice(
  rsiVal:    number,  // 当前 RSI
  rsiMaVal:  number,  // 当前 RSI MA
  close:     number,  // 当前收盘价
  gains:     number,  // 当前 RMA gains
  losses:    number,  // 当前 RMA losses
  rsiLen:    number,  // RSI 周期
): number             // 预测价格,RSI==MA 时为 NaN

RKISnapshot.predPriceRKISnapshot.predPct 由此函数自动填充:

const latest = snapshots[snapshots.length - 1]
const changePct = latest.predPct    // 预测涨跌幅 %
const crossPrice = latest.predPrice // RSI/MA 交叉价格

配置参数

所有参数均与 TradingView Pine Script v6 默认值一致。

KD 配置(config.kd

| 参数 | 默认值 | 描述 | |---|---|---| | kd_k_len | 14 | Stochastic K 周期 | | kd_d_smooth | 3 | Stochastic D 平滑周期 | | kd_ob | 80 | 超买判定线 | | kd_os | 20 | 超卖判定线 | | kd_top_exhaust_lvl | 70 | 顶部衰竭触发线(K 跌破此线进入 P3) | | kd_bot_recovery_lvl | 40 | 底部修复触发线(K 升破此线进入 P3) | | kd_retrace_lvl | 50 | 顶部重置回调线(K、D 均跌破则清除阶段) | | kd_bounce_lvl | 50 | 底部重置反弹线(K、D 均升破则清除阶段) |

RSI 配置(config.rsi

| 参数 | 默认值 | 描述 | |---|---|---| | rsi_len | 14 | RSI 计算周期 | | rsi_ma_len | 14 | RSI MA 平滑周期 | | rsi_ob | 70 | RSI 超买判定线 | | rsi_os | 30 | RSI 超卖判定线 | | rsi_top_exhaust_lvl | 70 | 顶部衰竭线(MA 跌破此线进入 P3) | | rsi_bot_recovery_lvl | 35 | 底部修复触发线(RSI 升破此线进入 P3) | | rsi_retrace_lvl | 55 | 顶部重置回调线(RSI 跌破则清除阶段) | | rsi_bounce_lvl | 45 | 底部重置反弹线(RSI 升破则清除阶段) | | rsi_extreme_lvl | 20 | 极度超卖线(直接进入 ACCUM) | | rsi_bot_gap_thr | 10 | RSI/MA 间距阈值(触发 ACCUM 的最大差值) |


市场阶段值

综合市场阶段(marketStage)范围为 -8 至 +8,正值为顶部周期,负值为底部周期,0 为中性。

顶部阶段

| 阶段值 | 短码 | 描述 | | ------ | ---- | ---------------------------------------------------- | | +1 | K:TI | KD 顶部启动 — K、D 同时进入超买区且 K > D | | +2 | R:TI | RSI 顶部启动 — RSI 进入超买区 | | +3 | K:TB | KD 顶部构建 — K 在超买区且 K < D | | +4 | R:TB | RSI 顶部构建 — RSI 在超买区且 RSI < MA | | +5 | K:TE | KD 动能衰竭 — K 跌破 kd_top_exhaust_lvl(瞬态) | | +6 | R:TE | RSI 动能衰竭 — MA 跌破 rsi_top_exhaust_lvl(瞬态) | | +7 | K:TD | KD 出货阶段 — 衰竭后 K 仍在超买区 | | +8 | R:TD | RSI 出货阶段 — 衰竭后 RSI 仍在超买区 |

底部阶段

| 阶段值 | 短码 | 描述 | | ------ | ---- | ----------------------------------------------------------------------------------- | | -1 | K:BP | KD 恐慌杀跌 — K、D 同时进入超卖区且 K < D | | -2 | R:BP | RSI 恐慌杀跌 — RSI 进入超卖区 | | -3 | K:BA | KD 吸筹筑底 — K 在超卖区且 K > D | | -4 | R:BA | RSI 吸筹筑底 — RSI < OS 且 (MA−RSI) < rsi_bot_gap_thr,或 RSI < rsi_extreme_lvl | | -5 | K:BR | KD 修复阶段 — K 升破 kd_bot_recovery_lvl(瞬态) | | -6 | R:BR | RSI 修复阶段 — RSI 升破 rsi_bot_recovery_lvl(瞬态) | | -7 | K:BB | KD 启动上涨 — 修复后 K 仍在超卖区 | | -8 | R:BB | RSI 启动上涨 — 修复触发后 RSI 回落至 rsi_bot_recovery_lvl 以下 |

阶段合并规则

同一 bar 上 KD 和 RSI 可能处于不同阶段,合并逻辑如下:

  1. 冲突屏蔽 — RSI 与 KD 方向相反时,KD 阶段被屏蔽为 0
  2. 取大原则 — 取绝对值较大者作为综合阶段值
  3. RSI 优先 — 绝对值相同时 RSI 优先

类型定义

/** 单根 K 线数据 */
interface OHLCVBar {
  time:   number  // Unix 毫秒时间戳
  open:   number
  high:   number
  low:    number
  close:  number
  volume: number
}

/** 每根 bar 的计算结果快照 */
interface RKISnapshot {
  // 指标值
  rsiVal:    number  // RSI (0–100)
  rsiMaVal:  number  // RSI MA (0–100)
  kVal:      number  // Stochastic %K (0–100)
  dVal:      number  // Stochastic %D (0–100)

  // 子系统阶段(0=无,1=P1,2=P2,3=P3 瞬态,4=P4)
  kdTopPhase:  number  // KD 顶部阶段
  kdBotPhase:  number  // KD 底部阶段
  rsiTopPhase: number  // RSI 顶部阶段
  rsiBotPhase: number  // RSI 底部阶段

  // 子系统有符号阶段
  kdStage:  number  // KD 有符号综合阶段 (-7 到 +7)
  rsiStage: number  // RSI 有符号综合阶段 (-8 到 +8)

  // 综合市场阶段
  marketStage: number  // 综合阶段 (-8 到 +8)

  // 回调统计
  pullbackRounds: number  // 已记录的回调轮数(从 0 起)

  // 价格预测
  predPrice: number  // RSI/MA 交叉所需价格(RSI==MA 时为 NaN)
  predPct:   number  // 预测涨跌幅 %(RSI==MA 时为 NaN)
}

/** 数据适配器接口 */
interface DataAdapter {
  fetchOHLCV(
    symbol:   string,
    interval: string,
    options?: { limit?: number; startTime?: number; endTime?: number }
  ): Promise<OHLCVBar[]>
}

执行原理

状态机结构

RKI 的核心是两套独立的阶段状态机(KD 和 RSI),每套各有顶部和底部两条路径,共 4 个阶段:

顶部周期:
  TOP_INIT (P1) → TOP_BUILD (P2) → TOP_EXHAUST (P3, 瞬态) → TOP_DIST (P4)
         ↑                                    ↓ (自动清除)
         └──────────── 阶段清除 ←──────────────────────────┘

底部周期:
  BOT_PANIC (P1) → BOT_ACCUM (P2) → BOT_RECOVERY (P3, 瞬态) → BOT_BREAKOUT (P4)

P3(衰竭/修复)是瞬态阶段,在同一 bar 内完成转换后自动清除。

KD 与 RSI 状态机的差异

| 条件 | KD | RSI | |---|---|---| | TOP_INIT 触发 | K > OB 且 D > OB 且 K > D | RSI > OB | | TOP_BUILD 进入 | K > OB 且 K < D | RSI > OB 且 RSI < MA | | TOP_EXHAUST 触发 | K 跌破 kd_top_exhaust_lvl | MA 跌破 rsi_top_exhaust_lvl | | TOP_DIST 进入 | 衰竭后 K 仍在超买区 | 衰竭后 RSI 仍在超买区 | | 顶部清除 | K 且 D 均跌破 kd_retrace_lvl | RSI 跌破 rsi_retrace_lvl | | BOT_PANIC 触发 | K < OS 且 D < OS 且 K < D | RSI < OS | | BOT_ACCUM 触发 | K > D 且 K < OS | RSI < OS 且 (MA−RSI) < rsi_bot_gap_thr,或 RSI < rsi_extreme_lvl | | BOT_RECOVERY 触发 | K 升破 kd_bot_recovery_lvl | RSI 升破 rsi_bot_recovery_lvl | | BOT_BREAKOUT 进入 | 修复后 K 仍在超卖区 | 修复触发后 RSI 回落至 rsi_bot_recovery_lvl 以下 | | BOT_BREAKOUT 清除 | K 且 D 均升破 kd_bounce_lvl | RSI >= rsi_bot_recovery_lvl | | 底部重置 | K 且 D 均升破 kd_bounce_lvl | RSI 升破 rsi_bounce_lvl |

回调轮数计数

每个 bar 按以下固定顺序执行(与 Pine Script 行为一致):

  1. 重置(最高优先级) — RSI < OS 时,轮数清零,hadTopBuild 重置为 false
  2. 建顶标记marketStage >= 3 时,设置 hadTopBuild = true
  3. 计数hadTopBuild 为 true 且 marketStage <= -1 时,pullbackRounds += 1,并清除 hadTopBuild

License

MIT