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

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1Все 1305 услуг
Разработка визуализации order flow (Footprint Chart)
Сложный
~5 дней
Часто задаваемые вопросы

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

Этапы блокчейн-разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1360
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    957
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1188
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    646
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    929

Разработка визуализации 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 проектов для фондов и проп-трейдеров. Свяжитесь с нами для оценки вашего проекта — получите консультацию бесплатно.

Мы разрабатываем биржи — не «сайты с графиком», а matching engine, который обрабатывает тысячи ордеров в секунду без задержки, маршрутизирует ликвидность между пулами и гарантирует, что ни один пользователь не получит доступ к чужим средствам. Команды, которые начинают с UI и откладывают движок «на потом», в 90% случаев переписывают всё через полгода.

Какие проблемы решает правильная архитектура?

Order Book vs AMM: где ломается большинство проектов

Централизованные биржи (CEX) строятся вокруг order book + matching engine. Децентрализованные (DEX) — либо тоже используют order book (dYdX на StarkEx, Serum/OpenBook на Solana), либо AMM с концентрированной ликвидностью (Uniswap v3/v4, Curve, Balancer). Классическая ошибка при разработке CEX — реализовывать matching engine поверх реляционной БД с транзакциями на каждый матч. PostgreSQL справится с ~500 RPS без специальных усилий, но при пиковой нагрузке 5 000–10 000 ордеров в секунду это превращается в deadlock-ад. Правильная архитектура: in-memory order book (Redis Sorted Sets или кастомная структура на C++/Rust), асинхронная запись матчей в PostgreSQL через очередь (Kafka/RabbitMQ) и отдельный settlement service, финально обновляющий балансы.

Для DEX самая болезненная проблема — sandwich атаки и MEV. Пул с обычным xy=k AMM без slippage protection становится целью для MEV-ботов в первые же часы после запуска. Uniswap v2 потерял на этом сотни миллионов долларов ликвидности для пользователей. Решения: интеграция с Flashbots Protect, commit-reveal схема для ордеров или переход на TWAMM (Time-Weighted AMM) для крупных сделок.

Концентрированная ликвидность и impermanent loss

Uniswap v3 ввёл концентрированную ликвидность — LP выбирают ценовой диапазон, в котором предоставляют ликвидность. Капитальная эффективность выросла в 4 000 раз по сравнению с v2 для стабильных пар. Но реализовать этот механизм правильно — нетривиальная задача. Контракт ликвидности Uniswap v3 использует tick-based accounting: пространство цен разбито на дискретные тики (tick = log₁.0001(price)), каждый тик хранит накопленные fee growth и liquidity delta. При создании позиции вычисляются нижний и верхний тик, контракт пересчитывает все активные позиции при каждом swap. Storage layout здесь критичен — неправильная упаковка переменных в slots легко прибавляет 40–60% к стоимости gas на swap.

Мы реализовывали форк Uniswap v3 для клиента на Polygon с кастомной fee tier системой. Первоначальная версия тратила 180k gas на swap через 2 тика. После slot packing переменных в Tick.Info и инлайнинга нескольких internal вызовов — 112k gas. Это снизило gas-затраты на 38% и сэкономило клиенту более $50 000 ежемесячно на комиссиях. Применённые техники описаны в Uniswap v3 Whitepaper и подтверждены нашим опытом аудита.

Что такое matching engine и почему он критичен?

Production-ready matching engine строится по следующей схеме:

  • Order ingestion layer — WebSocket gateway (Go или Rust), принимает ордера, валидирует подпись, проверяет баланс через Redis, ставит в очередь. Latency на этом уровне должна быть <1ms.
  • Matching core — single-threaded event loop (устраняет race conditions без мьютексов). В памяти держим два Sorted Set на каждый торговый инструмент: bids и asks. FIFO matching для limit ордеров, immediate-or-cancel для маркет. Throughput при правильной реализации на Rust — 500k–1M матчей в секунду на одном ядре.
  • Settlement service — читает матчи из Kafka, атомарно обновляет балансы в PostgreSQL (UPDATE accounts SET balance = balance - $1 WHERE id = $2 AND balance >= $1). Optimistic locking через версионирование строк.
  • Withdrawal pipeline — отдельный сервис с cold/hot wallet архитектурой. Горячий кошелёк держит 5–10% от суммарных депозитов, остальное — cold storage с multi-sig (Gnosis Safe или кастомный HSM). Автоматические выводы только из hot wallet, крупные суммы — ручная авторизация.
Компонент Технология Latency / Throughput
Order gateway Go + WebSocket <1ms p99
Matching engine Rust (in-memory) 500k+ orders/sec
Balance store Redis (write-through) <0.5ms
Settlement DB PostgreSQL 14+ ~50k TPS с partitioning
Event streaming Apache Kafka 1M+ events/sec
Blockchain node Geth / Solana validator зависит от чейна

Как мы строим on-chain DEX: смарт-контракты и gas-оптимизация

Для DEX на EVM (Ethereum, Arbitrum, Optimism, Polygon) весь критический путь живёт в Solidity. Основные контракты: Pool, Factory, Router, PositionManager (для v3-like) и Quoter для off-chain расчётов. Типичные ошибки, которые мы видим в аудитах:

Reentrancy через callback. Uniswap v3 использует flash swap с callback (uniswapV3SwapCallback). Если в вашем роутере нет nonReentrant guard и вы не проверяете msg.sender == pool, контракт дренируется через вложенный вызов. Это не гипотетика — несколько форков v3 теряли средства именно так.

Oracle manipulation в AMM. Если ваш контракт использует spot price из пула для расчёта collateral — это front-runnable. Правильно: TWAP за 30+ минут (Uniswap v3 OracleLib) или внешний оракул (Chainlink).

Unbounded loops в liquidity range. Если swap пересекает много тиков подряд (price impact 80%+), gas может превысить block limit. Нужен MAX_TICKS_CROSSED с partial fill и возвратом остатка.

Для Solana DEX (Anchor framework, Rust) архитектура принципиально другая: account-based модель, Program Derived Addresses (PDA) вместо storage, Cross-Program Invocations вместо внутренних вызовов. Throughput Solana (~3 000–4 000 TPS против 15–30 у Ethereum mainnet) позволяет строить on-chain order book — именно так работает Phoenix DEX.

Liquidity bootstrapping и интеграция с агрегаторами

Запустить пул мало — нужно обеспечить ликвидность на старте. Практические механизмы:

  • Liquidity Bootstrapping Pool (LBP) — начальная цена высокая, весовые коэффициенты активов динамически смещаются, создавая давление продаж и равномерное распределение токена. Реализован в Balancer v2.
  • Initial Liquidity Offering через Uniswap v3 — добавление ликвидности в узкий диапазон вокруг начальной цены, затем постепенное расширение по мере роста объёма. Требует active liquidity management или интеграции с Arrakis/Gamma.
  • Интеграция с 1inch, Paraswap, Li.Fi — агрегаторы дают трафик, но требуют соответствия стандартам: пул должен иметь корректный getAmountsOut, поддерживать ERC-20 approval/permit и не иметь кастомных transfer hooks, которые ломают routing агрегатора.

Процесс разработки

Аналитика и проектирование начинаются с выбора архитектурной модели: CEX с кастодиальным хранением, non-custodial DEX или гибрид (off-chain order book + on-chain settlement, как dYdX v3). Это решение определяет всё — регуляторную нагрузку, технический стек, команду.

Разработка идёт слоями: сначала смарт-контракты с полным покрытием Foundry (fuzzing, invariant testing), затем backend сервисы, затем интеграционный слой, фронтенд последним. Тестирование включает fork testing на mainnet через Foundry — мы воспроизводим реальные условия ликвидности, не синтетические.

Аудит обязателен перед деплоем на mainnet. Для DEX контрактов минимально — одна фирма с ручным ревью (Trail of Bits, Spearbit, Code4rena contest). Для CEX custody — аудит процессов хранения ключей. Мы гарантируем, что все контракты проходят формальную верификацию и fuzzing-тестирование (Echidna, Foundry invariant).

Что входит в работу (deliverables)

По завершении проекта вы получаете:

  • Исходный код смарт-контрактов и backend-сервисов под вашу лицензию
  • Полную техническую документацию (архитектурные схемы, API-спецификации, инструкции по деплою)
  • Доступы к репозиторию и CI/CD pipeline
  • Обучение вашей команды работе с кодом (2–3 сессии)
  • Гарантию на найденные в процессе эксплуатации баги до 6 месяцев
  • Сертификат прохождения стороннего аудита безопасности

Ориентиры по срокам

  • DEX (AMM, xy=k) — от 3 до 5 месяцев: контракты + backend + UI
  • DEX с концентрированной ликвидностью (v3-like) — от 6 до 10 месяцев
  • CEX (matching engine + custody + торговый UI) — от 8 до 14 месяцев
  • Интеграция с существующим протоколом — от 4 до 8 недель

Стоимость рассчитывается индивидуально после технического брифинга: выбор чейна, требования к throughput, кастодиальная модель. Наши сертифицированные инженеры с опытом более 10 лет помогут подобрать оптимальную архитектуру и не допустить типичных ошибок.

Типичные грабли при запуске

  • Забывают про price oracle в AMM. Spot price манипулируется flash loan’ом за одну транзакцию. Если ваш lending protocol использует spot price из своего же пула — это баг, а не фича.
  • Горячий кошелёк без лимитов. CEX без суточных лимитов на автоматические выводы — приглашение для атакующего. Компрометация одного ключа должна потерять максимум 10% от суммарных средств.
  • Отсутствие circuit breaker. Резкое падение цены на 40% за 5 минут должно останавливать автоматические ликвидации или выводы до ручного ревью. Без этого cascading liquidation spiral уничтожает весь TVL.
  • Неправильный decimal handling. USDC использует 6 decimals, WBTC — 8, большинство токенов — 18. Смешивание без нормализации даёт либо потерю точности, либо overflow. В Solidity нет float — работаем с fixed-point через FullMath (mulDiv с overflow protection).

Хотите избежать этих проблем? Свяжитесь с нами для консультации — мы подберём архитектуру под ваш проект и назовём точные сроки. Закажите разработку биржи с гарантией качества и последующей поддержкой.