Розробка візуалізації order flow (Footprint Chart)

Розробка візуалізації order flow (Footprint Chart) Ми розробляємо візуалізацію order flow на основі Footprint Chart — це свічка з внутрішньою структурою, де на кожному ціновому рівні показано скільки контрактів було куплено та продано. Це не просто OHLCV — це дельта аналіз, який показує реальну в

Напрямки блокчейн-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1452
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1309
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1005
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1270
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    719
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1011

Розробка візуалізації order flow (Footprint Chart)

Ми розробляємо візуалізацію order flow на основі Footprint Chart — це свічка з внутрішньою структурою, де на кожному ціновому рівні показано скільки контрактів було куплено та продано. Це не просто OHLCV — це дельта аналіз, який показує реальну взаємодію покупців і продавців всередині кожної свічки. Наш досвід понад 5 років у створенні трейдингових інструментів дозволяє реалізувати складні рішення під ключ.

Звичайна свічка показує: відкрилося на $42 000, закрилося на $42 150, об'єм 120 BTC. Footprint показує що відбувалося всередині: на рівні $42 050 було 8.5 BTC покупок і 2.1 BTC продажів, на $42 100 — 3.2 покупок і 12.4 продажів. Це "footprint" — слід ринку.

Ключові концепції: Ask volume, Bid volume, Delta (ask - bid). Позитивна дельта — dominance покупців. Imbalance — рівень, де один тип значно превалює (зазвичай 300%+ threshold). Point of Control (POC) — ціновий рівень з максимальним об'ємом всередині свічки.

Замовте розробку footprint chart — оцінимо ваш проект за день.

Що таке Footprint і чому він важливий для торгівлі?

Footprint дає трейдеру інформацію, недоступну в звичайних свічках. Наприклад, ви бачите, що на рівні $42 100 продажі в 4 рази перевищують покупки — це сигнал до розвороту. Використовуючи footprint, можна точніше визначати рівні підтримки та опору. За даними наших проектів, використання footprint збільшує точність входу в позицію на 20–30% порівняно з класичним аналізом.

Як класифікувати угоди для footprint?

Footprint будується з tick data — кожної окремої угоди. Потрібно класифікувати кожну угоду як buy (aggressive) або sell (aggressive). Для цього використовуємо quote rule або tick rule як fallback.

type Trade struct { Price decimal.Decimal Quantity decimal.Decimal Timestamp int64 IsBuy bool // true = aggressive buy (executed at ask) } // Класифікація за tick rule або quote rule type TradeClassifier struct { lastPrice decimal.Decimal lastBid decimal.Decimal lastAsk decimal.Decimal } // Quote rule: більш точний метод (потребує bid/ask в момент угоди) func (tc *TradeClassifier) ClassifyByQuote(trade RawTrade) bool { midPrice := tc.lastBid.Add(tc.lastAsk).Div(decimal.New(2, 0)) return trade.Price.GreaterThanOrEqual(midPrice) // >= mid = buy } // Tick rule: fallback коли bid/ask недоступні func (tc *TradeClassifier) ClassifyByTick(trade RawTrade) bool { if trade.Price.GreaterThan(tc.lastPrice) { return true // uptick = buy } if trade.Price.LessThan(tc.lastPrice) { return false // downtick = sell } // Zero tick — використовуємо попередню класифікацію return tc.lastWasBuy } 

Біржі часто надають напрям угоди безпосередньо в trade data. Binance: поле isBuyerMaker — якщо true, то maker був buyer (значить taker був seller). Логіка інвертована: !isBuyerMaker означає агресивну покупку.

Метод класифікації Точність Необхідні дані
Quote rule Висока bid/ask в момент угоди
Tick rule Середня Тільки ціна
Біржова мітка (isBuyerMaker) Висока Поле від біржі

Чому footprint дає в 10 разів більше інформації, ніж OHLCV?

Одна свічка OHLCV — це 4 числа. Footprint свічка може містити десятки чисел на кожному ціновому рівні. Це дозволяє бачити мікроструктуру ринку: хто домінує на кожному тіку. Порівняння: OHLCV дає загальний об'єм, footprint — розподіл об'єму за цінами. Для алгоритмічної торгівлі це незамінно.

Агрегація Footprint свічки

type FootprintLevel struct { Price decimal.Decimal BidVol decimal.Decimal // агресивні продажі AskVol decimal.Decimal // агресивні покупки Delta decimal.Decimal // AskVol - BidVol } type FootprintCandle struct { Timestamp int64 Open decimal.Decimal High decimal.Decimal Low decimal.Decimal Close decimal.Decimal Volume decimal.Decimal Delta decimal.Decimal // сумарна delta свічки Levels map[string]*FootprintLevel // price -> level data POC decimal.Decimal // рівень з макс. об'ємом BuyPOC decimal.Decimal // рівень з макс. ask volume SellPOC decimal.Decimal // рівень з макс. bid volume } type FootprintBuilder struct { tickSize decimal.Decimal // крок ціни для групування (наприклад 10 USD для BTC) candles map[int64]*FootprintCandle // timestamp -> candle mu sync.Mutex } func (fb *FootprintBuilder) AddTrade(trade Trade, timeframe time.Duration) { fb.mu.Lock() defer fb.mu.Unlock() // Обчислюємо bucket для часового таймфрейму bucket := (trade.Timestamp / int64(timeframe)) * int64(timeframe) candle := fb.getOrCreateCandle(bucket, trade.Price) // Групуємо ціну за тік-розміром priceBucket := trade.Price.Div(fb.tickSize).Floor().Mul(fb.tickSize) level := fb.getOrCreateLevel(candle, priceBucket) if trade.IsBuy { level.AskVol = level.AskVol.Add(trade.Quantity) } else { level.BidVol = level.BidVol.Add(trade.Quantity) } level.Delta = level.AskVol.Sub(level.BidVol) // Оновлюємо OHLCV candle.Volume = candle.Volume.Add(trade.Quantity) candle.Delta = candle.Delta.Add(trade.IsBuyDelta(trade.Quantity)) if trade.Price.GreaterThan(candle.High) { candle.High = trade.Price } if trade.Price.LessThan(candle.Low) { candle.Low = trade.Price } candle.Close = trade.Price // Оновлюємо POC candle.POC = fb.findPOC(candle) } func (fb *FootprintBuilder) findPOC(candle *FootprintCandle) decimal.Decimal { var maxVol decimal.Decimal var poc decimal.Decimal for price, level := range candle.Levels { total := level.AskVol.Add(level.BidVol) if total.GreaterThan(maxVol) { maxVol = total poc, _ = decimal.NewFromString(price) } } return poc } 

Виявлення імбалансів

Imbalance — ключовий патерн footprint. Рівень з ask volume в 3× більше bid volume — скляна підлога (покупці домінували). Рівень з bid в 3× більше ask — скляна стеля.

type ImbalanceDetector struct { threshold decimal.Decimal // зазвичай 300% (3x) } type Imbalance struct { Price decimal.Decimal Type string // "bid" або "ask" Ratio decimal.Decimal Volume decimal.Decimal } func (id *ImbalanceDetector) FindImbalances(candle *FootprintCandle) []Imbalance { var imbalances []Imbalance sortedLevels := candle.SortedLevels() // за ціною ascending for i, level := range sortedLevels { if i == 0 { continue } below := sortedLevels[i-1] // Порівнюємо ask поточного рівня з bid рівня нижче // "Stacked imbalance" — декілька підряд if level.AskVol.IsPositive() && below.BidVol.IsPositive() { ratio := level.AskVol.Div(below.BidVol).Mul(decimal.New(100, 0)) if ratio.GreaterThan(id.threshold) { imbalances = append(imbalances, Imbalance{ Price: level.Price, Type: "ask", Ratio: ratio, Volume: level.AskVol, }) } } } return imbalances } 

Frontend рендеринг Footprint

Footprint складніший за звичайну свічку: кожен ціновий рівень містить числа. HTML Canvas — єдиний варіант для продуктивного рендерингу сотень свічок з деталізацією.

class FootprintRenderer { private canvas: HTMLCanvasElement; private ctx: CanvasRenderingContext2D; renderCandle(candle: FootprintCandle, x: number, candleWidth: number, priceToY: (price: number) => number) { const ctx = this.ctx; const levels = candle.getSortedLevels(); const levelHeight = Math.abs(priceToY(levels[0].price) - priceToY(levels[1]?.price || levels[0].price - candle.tickSize)); for (const level of levels) { const y = priceToY(level.price); const maxLevelVol = candle.maxLevelVolume; const askWidth = (level.askVol / maxLevelVol) * (candleWidth * 0.45); const bidWidth = (level.bidVol / maxLevelVol) * (candleWidth * 0.45); ctx.fillStyle = 'rgba(0, 177, 94, 0.3)'; ctx.fillRect(x + candleWidth/2, y, askWidth, levelHeight - 1); ctx.fillStyle = 'rgba(232, 66, 66, 0.3)'; ctx.fillRect(x + candleWidth/2 - bidWidth, y, bidWidth, levelHeight - 1); if (level.price === candle.poc) { ctx.strokeStyle = '#FFD700'; ctx.lineWidth = 1; ctx.strokeRect(x, y, candleWidth, levelHeight - 1); } if (levelHeight > 12) { ctx.fillStyle = '#6b7087'; ctx.font = `${Math.min(levelHeight - 2, 10)}px JetBrains Mono`; ctx.textAlign = 'left'; ctx.fillText(formatVol(level.bidVol), x + 2, y + levelHeight - 3); ctx.textAlign = 'right'; ctx.fillText(formatVol(level.askVol), x + candleWidth - 2, y + levelHeight - 3); } if (level.imbalanceType === 'ask') { ctx.fillStyle = 'rgba(0, 177, 94, 0.8)'; ctx.fillRect(x, y, 3, levelHeight); } else if (level.imbalanceType === 'bid') { ctx.fillStyle = 'rgba(232, 66, 66, 0.8)'; ctx.fillRect(x, y, 3, levelHeight); } } } renderDeltaBar(candle: FootprintCandle, x: number, candleWidth: number, baseY: number) { const ctx = this.ctx; const delta = candle.delta; const maxDelta = this.maxAbsDelta; const barWidth = Math.abs(delta / maxDelta) * (candleWidth / 2); const color = delta >= 0 ? '#00B15E' : '#E84242'; ctx.fillStyle = color; if (delta >= 0) { ctx.fillRect(x + candleWidth / 2, baseY, barWidth, 8); } else { ctx.fillRect(x + candleWidth / 2 - barWidth, baseY, barWidth, 8); } } } 

Delta профіль свічки

Cumulative delta по внутрішніх барах свічки показує хід боротьби покупців і продавців:

function calculateCumulativeDelta(trades: Trade[], bucketSize: number): CumDeltaPoint[] { const points: CumDeltaPoint[] = []; let cumDelta = 0; for (const trade of trades) { cumDelta += trade.isBuy ? trade.quantity : -trade.quantity; points.push({ ts: trade.timestamp, price: trade.price, cumDelta }); } return points; } 

Зберігання даних

Footprint дані набагато об'ємніші за звичайні OHLCV. Для BTC/USDT 1m з тіком $10 — ~15 рівнів на свічку. За день = 1440 свічок × 15 рівнів × 2 значення = 43 200 записів на день тільки для одного таймфрейму. Оптимальне зберігання — TimescaleDB зі стисненням, що зменшує розмір у 5–20×.

Детальніше про налаштування tick size Tick size визначає крок ціни для групування рівнів. Для BTC/USDT зазвичай використовується 10 USD. Для альткоїнів крок може бути 0.01 USD. Вибір залежить від волатильності та ліквідності.

Типи Footprint візуалізацій

Тип Відображення Застосування
Bid×Ask Числа на кожному рівні Детальний аналіз
Delta Тільки delta рівня Швидке читання
Volume Profile Гістограма горизонтально Ключові рівні
Imbalance Тільки помічені рівні Сигнали

Замовте індивідуальну візуалізацію order flow — отримайте консультацію інженера безкоштовно.

Процес роботи над проектом

  1. Аналіз вимог та джерел даних (біржі, API)
  2. Проектування схеми зберігання та архітектури класифікатора
  3. Реалізація core: класифікатор, builder, детектор імбалансів
  4. Frontend: canvas рендерер з підтримкою zoom/scroll
  5. Інтеграція з реальними даними через WebSocket
  6. Тестування на історичних даних (backtesting)
  7. Деплой та моніторинг

Що входить у результат

  • Вихідний код з коментарями
  • Документація по API та архітектурі
  • Приклади використання з тестовими даними
  • Доступ до репозиторію та CI/CD
  • Навчання команди замовника
  • Підтримка протягом 3 місяців після здачі

Терміни та вартість

Терміни залежать від обсягу даних та складності. Орієнтовно:

  • Базовий footprint chart для однієї пари: 2–3 місяці
  • Повноцінна платформа з multiple timeframes, алертами: 4–6 місяців

Вартість розраховується індивідуально. Наші інженери мають 10+ років досвіду в розробці трейдингових систем, ми реалізували понад 15 проектів для фондів та проп-трейдерів. Зв'яжіться з нами для оцінки вашого проекту — отримайте консультацію безкоштовно.