Cryptocurrency K-Line Quantitative Analysis Platform
Real-time · Plugin-driven · Cross-platform
English · 简体中文
Features · Quick Start · Architecture · Plugins · Contributors
AetherQuant is a desktop-grade cryptocurrency technical analysis workstation. It renders interactive candlestick charts, runs five independent quantitative strategies in parallel, and aggregates their output into a unified consensus rating — all fed by live market data from Hyperliquid DEX over a persistent WebSocket connection.
The entire system is plugin-driven: swap exchanges to pull data from a different venue, or plug in your own strategy module without touching the core.
|
Each strategy emits a 0–100 score mapped to a 5-tier rating. |
|
|
| Score | Rating | Interpretation |
|---|---|---|
| 70 – 100 | Bullish | Strong Buy |
| 55 – 70 | Slightly Bullish | Buy |
| 45 – 55 | Neutral | Hold |
| 30 – 45 | Slightly Bearish | Sell |
| 0 – 30 | Bearish | Strong Sell |
The consensus rating is the arithmetic mean of all active strategy scores.
| Layer | Stack |
|---|---|
| UI Framework | Vue 3 (Composition API, <script setup>) |
| Language | TypeScript (strict) |
| Charting | lightweight-charts v5 (TradingView) |
| i18n | vue-i18n v10 |
| Styling | CSS Custom Properties (light / dark) |
| Bundler | Vite 8 |
| Desktop Shell | Tauri 2 (Rust backend) |
| Market Data | Hyperliquid DEX (HTTP + WebSocket) |
# Prerequisites: Node.js ≥ 18, Rust toolchain
# Browser development
npm install
npm run dev # http://localhost:5173
# Desktop development
npm run tauri:dev
# Production distribution
npm run tauri:build # → src-tauri/target/release/bundle/Windows: requires MSVC build tools + Windows SDK for the Rust backend.
src/
├── components/ Vue 3 SFCs
│ ├── TitleBar.vue Custom frameless title bar + window controls
│ ├── Toolbar.vue Symbol / interval / limit selectors + WS indicator
│ ├── CoinSelector.vue Searchable dropdown (100+ pairs, real-time filter)
│ ├── KlineChart.vue Candlestick + volume + MA overlay + legend
│ ├── AnalysisPanel.vue Strategy cards with scores, signals, indicators
│ └── RatingBadge.vue Colored rating pill
├── composables/ Logic hooks
│ ├── useChart.ts lightweight-charts lifecycle & indicator API
│ ├── useRealtime.ts Hyperliquid persistent WebSocket manager
│ ├── useAnalysis.ts Strategy execution pipeline
│ ├── useTheme.ts Dark/light toggle + persistence
│ ├── useTauri.ts Native window API abstraction
│ └── usePlugins.ts Reactive plugin state
├── plugin-system/
│ └── PluginManager.ts Registry, activation, pub/sub
├── plugins/
│ ├── exchanges/
│ │ └── hyperliquid.ts
│ └── strategies/
│ ├── ma-strategy.ts
│ ├── macd-strategy.ts
│ ├── rsi-strategy.ts
│ ├── bollinger-strategy.ts
│ └── ema-strategy.ts
├── locales/ zh.ts / en.ts
├── types/ Shared TypeScript interfaces
├── themes.css CSS variable definitions (dark + light)
├── App.vue Root — wiring, WS lifecycle, indicator dispatch
├── i18n.ts i18n instance + locale persistence
└── main.ts Entry point
src-tauri/ Tauri (Rust) backend
├── src/ lib.rs, main.rs
├── icons/ App icons (ico, icns, png)
├── Cargo.toml
└── tauri.conf.json Window config (frameless, 1400×900)
HTTP fetchData ──→ data[] ──→ KlineChart.setData()
│
WS onCandle ──→ merge ──→ data[] ──→ KlineChart.setData()
│
├── plotIndicators() (MA lines)
└── run(slice) (quant analysis)
connect(BTC, 1h)
├── unsubscribe old (if any)
├── subscribe { candle, BTC, 1h }
│
├── onmessage → Number() coerce → filter by coin/interval → onCandle()
│
├── switch to (ETH, 15m)
│ ├── unsubscribe { candle, BTC, 1h }
│ └── subscribe { candle, ETH, 15m }
│ (same WebSocket, no reconnect)
│
└── onclose → 3s delay → reconnect → onopen → re-subscribe current
Plugins implement a typed interface and register with the PluginManager. The host application never imports plugin internals directly — it only talks to the manager.
import type { StrategyPlugin } from '@/types'
export const myStrategy: StrategyPlugin = {
id: 'my-strategy',
name: 'My Strategy',
version: '1.0.0',
type: 'strategy',
description: 'Description',
analyze(data) {
return {
strategyId: 'my-strategy',
strategyName: 'My Strategy',
rating: 'bullish', // 'bearish' | 'slightly_bearish' | 'neutral' | ...
score: 75, // 0 – 100
signals: [{ type: 'buy', message: 'Signal text', timestamp: Date.now() }],
indicators: [{ name: 'Value', value: 1.23, displayValue: '1.23' }],
summary: 'Analysis result',
timestamp: Date.now(),
}
},
}
// Activate
pluginManager.registerStrategy(myStrategy)import type { ExchangePlugin } from '@/types'
export const myExchange: ExchangePlugin = {
id: 'my-exchange',
name: 'My Exchange',
version: '1.0.0',
type: 'exchange',
description: 'Custom exchange adapter',
async fetchData(symbol, interval, limit) { /* → OHLCV[] */ },
async fetchRange?(symbol, interval, start, end) { /* → OHLCV[] */ },
subscribe?(symbol, interval, onCandle) { /* → unsubscribe fn */ },
getSupportedSymbols() { return ['BTC/USDT', 'ETH/USDT'] },
getSupportedIntervals() { return ['1m', '5m', '15m', '1h', '4h', '1d'] },
}
pluginManager.registerExchange(myExchange)
pluginManager.setActiveExchange('my-exchange')|
oxroot Project Author Architecture · Strategy Algorithms · Direction |
Claude Code Engineering Full-stack Implementation · UI/UX · Tooling |
MIT © 2025 oxroot. See LICENSE for full text.