Skip to content

ibrahim-deriv/deriv-pulse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

29 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Deriv Pulse

"TradingView is built for people who already speak the language of markets. Deriv Pulse is built for the moment before that."

Built for the Deriv API Grand Prix 2026 · April 6–17


Team

Name Role
Ibrahim Abdulla Product · Designer · Developer

Submission date: April 6, 2026 Competition: Deriv API Grand Prix 2026 Category: Consumer · Open category


What is this?

Deriv Pulse is a single-page, deployable web app that answers one question a non-trader actually asks:

Is right now a calm or crazy moment in global markets?

It is not a trading dashboard. It is not a chart tool. It is the emotional front door to understanding markets — designed for someone who has never traded before. The entire experience lives on one screen. No backend. No database. Just a live URL anyone can open.


Why it exists

The problem with every existing market tool — Bloomberg, TradingView, even Deriv's own platform — is that they assume the user already speaks the language of markets. Candlesticks, order books, bid/ask spreads: these are fluent-trader concepts. They exclude the 99% of people who haven't started yet.

Deriv Pulse is designed for the moment before someone becomes a trader. It takes real, live, institutional-grade market data from Deriv's public WebSocket API and translates it into a single human feeling: calm, steady, active, or wild.

The strategic argument:

  • Every person who opens this screen and understands "markets are calm right now" is one step closer to becoming a Deriv client
  • This is a user acquisition funnel disguised as a visualisation
  • The flow is: Awareness → Curiosity → First experience → Signup — all on one screen

The complete user journey

1. First-time user sees a 3-step walkthrough:
   - Step 1: bottom sheet ("Markets, made human.") — explains the app in one sentence
   - Step 2: spotlight on the orb ("This colour is the market's mood. Right now.")
   - Step 3: spotlight on the first asset row ("Tap any asset to predict where it's heading.")
   - "?" button in header replays the walkthrough at any time

2. Home screen: tagline "Feel the market. Before you trade it." above the breathing orb
3. Orb colour and speed reflect the current market mood in real time
4. Featured asset card shows the most-moving asset (driven by live tick delta)

5. User taps the orb (or featured card) — Pulse Read sheet slides up:
   - Which asset is moving most / most stable right now
   - AI-narrative momentum insight ("Bitcoin trending upward across last 4 ticks")
   - Opinionated CTA: "Predict [Asset] now →"

6. User taps an asset row directly — prediction sheet slides up with:
   - Last 80 ticks as a historical chart (from ticks_history API)
   - Live price as entry point
   - Real Deriv payout quotes on each direction button ("~87% if right")
   - Momentum signal ("Bitcoin trending upward across last 4 ticks")
   - Direction buttons labelled "With the flow ↑" / "Against it ↓"

7. User picks a duration (30s / 60s / 5 min) and direction (UP / DOWN)
8. Countdown begins — live mini chart, entry vs current price, progress bar; sheet stays open so the user can watch the countdown unfold; drag down or tap outside to minimise to the mini bar

   SIMULATION MODE (default — no account needed):
   - At zero: result compared against live price
   - WIN  → "You called it. Bitcoin moved your way."
   - LOSE → "Markets had other plans. Bitcoin went the other way."

   DEMO ACCOUNT MODE (optional — connect via + Demo button):
   - On direction pick: real Deriv buy call fires with proposal ID
   - Deriv contract executes on your demo balance ($1 stake)
   - When Deriv settles the contract, result shows official P&L
   - "Deriv settled this contract. +$0.87 · Demo account · Won"

9.  Result screen shows: plain-English explanation, price moved %, win/loss record
10. "Predict [Asset] on Deriv →" deep-links to that asset on app.deriv.com
11. "Read the next pulse ↑" resets — loops back to the Pulse Read sheet

AI Insight Engine

Below the headline area, a live panel explains why the market feels the way it does right now. It reads from the same real-time WebSocket data as the rest of the app and surfaces up to three plain-English signal bullets on every tick cycle.

Signals generated

Signal Source Example
Vol 75 spike Rolling 14-sample baseline vs current getVolatility('1HZ75V') "Volatility 75 is spiking faster than its recent average"
Multi-asset mover count % change from tick −5 to tick 0 across all 10 symbols "3 assets moved >0.07% in the last 5 ticks"
Vol 75 momentum 4-of-4 consecutive same-direction tick changes on 1HZ75V "Momentum increasing over last 5 ticks"
Cross-asset alignment All primary assets moving the same direction simultaneously "All tracked assets rising together — broad upward pressure"
Vol index agreement Both 1HZ75V and 1HZ100V above the active threshold "Vol 75 & 100 both elevated — synthetic indices heating up"

The AI badge and top accent line recolour with --mood-color in real time. The panel throttles its DOM redraws to every 4 ticks and samples its baseline every 5 ticks to prevent flicker on fast synthetic index streams.


The Market Pulse — four mood states

The central visual is a breathing orb that shifts colour, glow intensity, and animation speed based on live volatility data from Deriv's synthetic indices.

State Volatility Score Colour Animation Headline
Calm < 0.05% Deep teal #0f9b8e Slow, 4s cycle "Markets are breathing easy right now."
Steady 0.05–0.15% Warm amber #d4924a Rhythmic, 2.5s "Markets are moving with purpose."
Active 0.15–0.35% Electric blue #4a8fd4 Quick, 1.5s "Something is stirring out there."
Wild > 0.35% Coral red #d45a4a Rapid, 0.8s "It's chaotic out there right now."

Mood is calculated from Deriv's Volatility 75 and Volatility 100 synthetic indices — instruments specifically designed to simulate real market volatility conditions.


Technical architecture

Stack

  • One .html file — embedded CSS and JS, zero build step
  • Zero dependencies — no npm, no framework, no bundler
  • Google Fonts — Inter (300/400/500/600/700/800), loaded via <link>
  • Deriv WebSocket API V3 — 9 live tick subscriptions + up to 5 API calls per prediction

Deployment

Live at https://deriv-pulse.vercel.app

WebSocket connection

wss://ws.derivws.com/websockets/v3?app_id=1089

API calls on connection open

Call Purpose
ticks × 9 symbols Live price stream
asset_index Tradeable dot per asset row
authorize Demo account auth (if token stored)

API calls per prediction

Call When Purpose
ticks_history Asset tapped 80-tick history chart on choose sheet
proposal × 2 Asset tapped Payout % for CALL and PUT
proposal × 2 Duration changed Refresh payout quotes
buy Direction chosen (demo mode) Execute real Deriv contract
proposal_open_contract After buy Stream settlement in real time

Symbols subscribed

Symbol Name Role
cryBTCUSD Bitcoin Asset display
frxEURUSD Euro Asset display
frxXAUUSD Gold Asset display
cryETHUSD Ethereum Asset display
frxGBPUSD British Pound Asset display
1HZ10V Volatility 10 Index Mood signal
1HZ25V Volatility 25 Index Mood signal
1HZ75V Volatility 75 Index Primary mood driver
1HZ100V Volatility 100 Index Primary mood driver

Mood calculation

function getVolatility(sym) {
  const h = priceHistory[sym]; // last 20 ticks
  return Math.abs((h[h.length - 1] - h[0]) / h[0] * 100);
}

function recalculateMood() {
  const score = (getVolatility('1HZ75V') + getVolatility('1HZ100V')) / 2;
  if (score < 0.05)  return setMood('calm');
  if (score < 0.15)  return setMood('steady');
  if (score < 0.35)  return setMood('active');
  return setMood('wild');
}

Payout % from proposal API

When a user taps an asset, two proposal calls fire for CALL and PUT with a $1 stake. The response payout is used to show real Deriv contract rates on the direction buttons:

const pct = Math.round((proposal.payout / proposal.ask_price - 1) * 100);
// e.g. "~87% if right" on the Going UP button

Demo account flow (optional)

  1. User taps + Demo in the header → pastes an API token (Trading scope) — token created at developers.deriv.com/dashboard/tokens
  2. Token stored in localStorage, sent only to Deriv's WebSocket
  3. { authorize: token } fires → balance and loginid confirmed
  4. On direction choice → { buy: proposalId, price: askPrice } executes a $1 Deriv contract
  5. proposal_open_contract subscription streams settlement
  6. When is_sold: 1: result screen shows Deriv's official P&L
  7. Fallback: if Deriv hasn't settled within 8s, resolves from live price comparison

asset_index — tradeable dots

On connect, { asset_index: 1, landing_company: 'svg' } is sent. The response is parsed to check which of the 5 displayed assets have CALL/PUT contracts available. Each asset row shows a 5px dot:

  • Green — confirmed available for trading
  • Dim grey — view only

CSS custom property system

All mood-driven visuals flow through CSS variables on :root:

--mood-color      /* primary accent colour */
--mood-glow       /* same colour at ~20% opacity */
--anim-duration   /* orb breathe cycle speed */

When mood changes, colour, glow, orb speed, spark lines, predict pills, and time selector all update simultaneously via transition: 2s ease.

Connection resilience

All WebSocket lifecycle logic lives in a single DerivWSManager class:

Behaviour Detail
Keep-alive ping Every 25 s while connected
Exponential backoff 1 s → 2 s → 4 s → 8 s → 16 s → 30 s (cap), resets on success
Heartbeat watchdog Force-reconnects if no data arrives for 60 s while nominally connected
Tab visibility visibilitychange listener reconnects immediately when the user returns to the tab
Reconnecting banner Amber top banner slides in on disconnect, disappears on recovery
Live dot states Amber pulse = reconnecting · Green flash = recovered
Row dimming Asset rows dim to 45% opacity during disconnect; prices preserved in state — no blank rows
Recovery toast "Reconnected ✓" shown after any reconnect
Re-subscription All tick subscriptions re-sent on every onopen; old server-side subs die with the socket

The prediction engine

Simulation mode (default)

1. startPrediction(sym)
   → records entry price, fetches ticks_history + proposal quotes

2. chooseDirection('up' | 'down')
   → starts 250ms interval countdown

3. Every 250ms:
   → remaining time, live price vs entry, mini chart, progress bar

4. At t=0: resolvePrediction(exitPrice)
   → won = price moved in predicted direction
   → orb flashes green (win) or amber (loss) for 1.5s
   → streak updated in localStorage

Demo account mode (when authorized)

1. chooseDirection fires → buy call with proposal ID
2. Deriv returns contract_id → subscribe to proposal_open_contract
3. Countdown runs in parallel
4. If Deriv settles first → countdown stops, result from Deriv data
5. If countdown ends first → "Settling..." spinner, 8s Deriv fallback
6. Result shows official P&L from Deriv

Time selector

  • 30 seconds — fast, for crypto
  • 60 seconds — default
  • 5 minutes — slower assets like Gold

Changing duration re-fires proposal calls to refresh payout quotes.

Mini charts

Choose sheet — 80-tick history from ticks_history API, rendered as SVG polyline. Shows price context before picking direction.

Countdown sheet — builds live from WebSocket ticks since prediction started. Entry price shown as dashed reference line. Only redraws on new ticks (throttled).

Orb flash on result

  • Win#1D9E75 (green) for 1.5s
  • Loss#BA7517 (amber) for 1.5s

Achieved by scoped --mood-color inline style on #orb-wrapper, removed after 1.5s.

Pulse tracker (session progress)

A compact dot strip in the header, next to the Day streak counter. Replaces the old scoreboard fraction.

  • Dots — last 8 predictions; green filled = correct, outlined red = wrong
  • Win animation — newest dot scales to 1.7× with a green glow ring on a correct prediction
  • Early state label — under 5 predictions: "first call" / "N calls", no percentage; accuracy % only appears at 5+ predictions when there is enough signal to be meaningful
  • Result screen — shows streak first ("3 correct in a row"), then accuracy if enough data, then a gentle nudge ("N predictions — keep going"); raw fraction removed

Win/loss streak

Tracked in localStorage as { wins, total }. Persists across sessions. Shown on result screen.


Visual design

Aesthetic

Calm luxury meets live data. Think Bloomberg meets the Calm app. Every pixel is intentional. Built for a C-suite presentation at a fintech company.

Background

#0a0d12 — near-black with a subtle SVG noise texture overlay (4% opacity fractalNoise) and a directional gradient.

Typography

  • Inter — entire app, single typeface with 6 weights:
    • 800 — tagline, headlines, result screen, onboarding, auth titles
    • 600 — sheet asset name, spotlight text, pulse narrative
    • 400 — body text, asset names, supporting copy
    • 300 — countdown number, subline, onboarding body (light, airy)
  • Tagline: clamp(1.2rem, 4.5vw, 1.7rem), letter-spacing: -0.03em — tight and confident
  • Countdown number: 72px Inter 300 — large light numerals feel more modern than serif

The orb

A layered SVG with:

  • Ambient glow div — radial gradient, scales 1→1.3 on the breathe cycle
  • Main orb body — radial gradient ellipse with depth falloff
  • Inner highlight ellipse — offset from centre, creates a 3D light-source feel
  • Specular highlight — small blurred white ellipse at top-left
  • Ring — fades opacity only (no scale), stays perfectly geometric

The orb and ring animate independently:

  • Ring: opacity fade only (0.08 → 0.22)
  • Inner orb: pure scale breathe (1.0 → 1.08)
  • Whole SVG: glow filter pulse only — no transform, no layout shift

Asset rows

Each row: name + mood dot | spark line | live price | status | Predict › pill

  • Per-market mood dot — 7px circle, colour reflects the individual asset's volatility mood (teal=calm, amber=steady, blue=active, red=wild); seeded from ticks_history on boot; neutral var(--border) before data arrives
  • Left border flashes to --mood-color on hover
  • Loading skeleton pulse on prices while waiting for first tick
  • Status column (rising/falling/steady) shown at ≥460px viewport width

Splash loader

  • Full-screen #splash covers the page immediately on load with a pulsing mini-orb and "DERIV PULSE" wordmark
  • Dismissed on the first WebSocket tick — fades out over 0.5s then removes itself from the DOM
  • No blank white flash or layout shift while the WebSocket connects

PWA theming

  • <meta name="theme-color" content="#11141b"> — Chrome/Android status bar matches the app background
  • apple-mobile-web-app-capable + black-translucent status bar — correct behaviour when added to iOS Home Screen

Bottom sheet

  • Slides up from bottom with cubic-bezier(0.16, 1, 0.3, 1) — the iOS spring curve
  • Wide drag zone: top 60px — covers the handle pill and first content line; any swipe near the top initiates the drag. Handle bar opacity bumped to 32% for better visibility as an affordance.
  • Drag handle: pull down 80px+ to minimise
  • During active countdown: minimises to a 56px bar showing asset, direction, timer, progress bar
  • Tap the bar to re-expand
  • Backdrop tap: minimises if prediction active, dismisses otherwise

Compliance bar

Fixed to the bottom of the viewport at all times (z-index below bottom sheet). Glassmorphic background. Always visible regardless of scroll position.


File structure

3apr/
├── index.html    ← the entire application (~2,500 lines, HTML + CSS + JS)
├── README.md     ← this file
├── CHANGELOG.md  ← version history
├── PROMPTS.md    ← full development session log
└── LICENSE       ← MIT

Data sources

Asset Symbol API call
Bitcoin cryBTCUSD ticks (live) + ticks_history
Ethereum cryETHUSD ticks (live) + ticks_history
Euro frxEURUSD ticks (live) + ticks_history
British Pound frxGBPUSD ticks (live) + ticks_history
Gold frxXAUUSD ticks (live) + ticks_history
Market Mood 1HZ75V · 1HZ100V ticks (live)
Payout quotes all 5 assets proposal (CALL + PUT)
Contract execution all 5 assets buy + proposal_open_contract
Tradeability all 5 assets asset_index

Updates: real-time, every tick (~1s per symbol).


Compliance

Three disclaimer placements:

  1. Fixed compliance bar — always visible at the bottom of the viewport:

    "Not financial advice · No real money involved · For informational purposes only"

  2. Inside the prediction sheet (before direction choice):

    "This is not financial advice. No real money is involved. Past market movements do not predict future results."

  3. Result screen (after every prediction):

    Same disclaimer as above.

Demo account mode is clearly labelled throughout as using virtual funds only.


Deployment

Live URL: https://deriv-pulse.vercel.app

# Local dev
python3 -m http.server 3000
# then open http://localhost:3000

# Deploy
vercel --prod

No build step. No environment variables. No server. No database.


The pitch

One liner:

"Deriv Pulse is the emotional entry point that sits before your existing product."

On the demo account feature:

"It's not a simulation pretending to be real. When you connect a demo account, the buy call actually fires on Deriv's infrastructure. You get a real contract ID, real settlement data, real P&L — on virtual money. That's a fundamentally different thing."


Built for the Deriv API Grand Prix 2026 · Powered by Deriv API V3 · Optional demo account · No backend · No database

deriv-pulse

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages