About the project

GhostMarket was inspired by a simple observation: social sentiment often moves faster than price. In crypto communities, hype or panic can explode in minutes, while price sometimes lags behind. We wanted to build a leading indicator that detects those “rubber band” moments when vibe surges but the market has not reacted yet and surface them as a clear, real-time alert.

What we built

GhostMarket is a real-time vibe and price decoupling engine with three core layers:

  1. Ingestion
  • A Telegram listener streams messages from crypto groups.
  • A price producer polls CoinGecko for live prices.
  1. Streaming intelligence
  • Each Telegram message is scored with FinBERT to produce a sentiment (“vibe”) value in ([-1, 1]).
  • A stream processor maintains rolling time windows and computes decoupling metrics.
  1. Storage and visualization
  • Raw events and computed signals are stored in MotherDuck for fast querying.
  • A React and Tailwind dashboard shows the vibe feed, live price trend, and the current alert state.

The key idea (decoupling math)

We do not just plot sentiment and price. We compute changes relative to a rolling baseline.

Price move

$$ \Delta P = \frac{P_{\text{current}} - P_{\text{avg}}}{P_{\text{avg}}} $$

Vibe move

$$ \Delta V = V_{\text{current}} - V_{\text{avg}} $$

Hype momentum

$$ M_{\text{hype}} = \Delta V \times N $$

where (N) is the number of messages in the rolling window (a simple proxy for attention and velocity).

Trigger (MVP rule)

We fire an alert when hype momentum is strong but price is still flat.

$$ M_{\text{hype}} > T \quad \text{and} \quad \Delta P < 0.02 $$

In plain English, people are getting loud and positive, but the chart has not moved yet, so we flag IMMINENT HYPE PUMP.

What we learned

  • Real-time systems are about tradeoffs. We balanced latency vs reliability, and signal vs noise, especially under free-tier API limits.
  • Streaming windowing is everything. Rolling baselines make the signal far more meaningful than raw sentiment or raw price.
  • End-to-end matters. The project was not just ML. It was ingestion, Kafka, windowed computation, database, and UI, all running live.

Challenges we faced

  • Rate limits and demo realism: CoinGecko polling cadence had to be tuned so the app stayed stable while still feeling live.
  • Noisy social data: Telegram messages are messy, repetitive, and off-topic, so keyword and alias filtering was necessary to keep the stream relevant.
  • Time alignment: Price and sentiment arrive asynchronously, so we had to be careful with window boundaries to avoid drift.
  • UI clarity: We had to present a complex signal in a way judges can understand quickly, so the alert state and its supporting metrics are front and center.

Built With

  • coingecko-api
  • dotenv
  • duckdb
  • huggingface-transformers-(finbert)
  • javascript
  • kafka-(aiven)
  • motherduck-(duckdb-cloud)
  • react
  • request
  • tailwind-css
  • telethon-(telegram-api)
  • vite
Share this project:

Updates