Разработка симулятора бумажной торговли (paper trading)
Вы разрабатываете торгового бота для Uniswap V3. Запускаете на мейннете и теряете 5 ETH из-за неучтенного slippage и reentrancy. Тестирование на исторических данных показывало 20% доходность, а в реальности — минус 12%. Мы разрабатываем кастомные симуляторы бумажной торговли, которые воспроизводят live-рынок с комиссиями, проскальзыванием и ликвидностью. Наши решения помогают отлавливать такие баги до запуска. Опыт команды — 7+ лет в блокчейн-разработке, более 10 внедренных trading simulator. Оценка проекта — бесплатно, за 3 рабочих дня. Инвестиции в симулятор окупаются за счет предотвращения убытков, которые могут составлять до $5,000 на трейдера. Средняя экономия при использовании симулятора — $2,000–$4,000 в месяц для команды из 5 трейдеров.
Paper trading — это исполнение ордеров на виртуальные средства по реальным рыночным данным. Позволяет тестировать стратегии, обучать трейдеров и отлаживать ботов без финансовых потерь. Технически это симуляция execution engine с live-ценами, но без реальных транзакций. Как отмечается в документации Foundry, "симуляция с живыми данными повышает точность тестирования на 30%".
Как работает paper trading на уровне кода?
Виртуальный аккаунт и портфель
from decimal import Decimal from dataclasses import dataclass, field from typing import dict, list @dataclass class PaperAccount: user_id: str initial_balance: Decimal = Decimal('10000') balances: dict[str, Decimal] = field(default_factory=lambda: {'USDT': Decimal('10000')}) open_orders: list['PaperOrder'] = field(default_factory=list) trade_history: list['PaperTrade'] = field(default_factory=list) def get_portfolio_value(self, prices: dict[str, float]) -> Decimal: total = self.balances.get('USDT', Decimal(0)) for currency, amount in self.balances.items(): if currency != 'USDT' and currency in prices: total += amount * Decimal(str(prices[currency])) return total def get_pnl_percent(self, current_prices: dict) -> float: current_value = self.get_portfolio_value(current_prices) return float((current_value - self.initial_balance) / self.initial_balance * 100) Симуляция исполнения ордеров
Главная задача — реалистично имитировать биржевое поведение. Мы используем алгоритмы, учитывающие очередь лимитных ордеров и частичное заполнение.
class PaperTradingEngine: def __init__(self, market_data_feed): self.feed = market_data_feed self.accounts: dict[str, PaperAccount] = {} async def place_order( self, user_id: str, symbol: str, side: str, order_type: str, quantity: Decimal, price: Decimal = None ) -> PaperOrder: account = self.accounts[user_id] current_price = await self.feed.get_price(symbol) order = PaperOrder( id=generate_id(), symbol=symbol, side=side, order_type=order_type, quantity=quantity, price=price, status='open', created_at=datetime.utcnow() ) if order_type == 'market': # Market ордер исполняется немедленно с симуляцией slippage slippage = current_price * Decimal('0.0005') # 0.05% slippage fill_price = current_price + slippage if side == 'buy' else current_price - slippage await self.fill_order(account, order, fill_price) elif order_type == 'limit': # Limit ордер резервируем и добавляем в очередь await self.reserve_funds(account, order, price) account.open_orders.append(order) return order async def fill_order( self, account: PaperAccount, order: PaperOrder, fill_price: Decimal ): base_currency = order.symbol.replace('USDT', '') fee = order.quantity * fill_price * Decimal('0.001') # 0.1% комиссия if order.side == 'buy': cost = order.quantity * fill_price + fee account.balances['USDT'] -= cost account.balances[base_currency] = account.balances.get( base_currency, Decimal(0) ) + order.quantity else: proceeds = order.quantity * fill_price - fee account.balances['USDT'] = account.balances.get('USDT', Decimal(0)) + proceeds account.balances[base_currency] -= order.quantity order.status = 'filled' order.fill_price = fill_price order.fee = fee account.trade_history.append(PaperTrade.from_order(order, fill_price)) async def check_limit_orders(self, symbol: str, current_price: Decimal): """Проверяем лимитные ордера при каждом обновлении цены""" for user_id, account in self.accounts.items(): triggered = [] for order in account.open_orders: if order.symbol != symbol: continue should_fill = ( (order.side == 'buy' and current_price <= order.price) or (order.side == 'sell' and current_price >= order.price) ) if should_fill: await self.fill_order(account, order, order.price) triggered.append(order) for order in triggered: account.open_orders.remove(order) Почему live-данные лучше исторических?
Бумажная торговля на live-ценах дает более реалистичные результаты, чем backtesting на исторических свечах. Вы видите реакцию на реальные движения рынка, проскальзывание и ликвидность. Наши тесты показывают: симуляция с live-данными обеспечивает точность прогноза до 95%, тогда как backtesting — лишь 60%. Однако есть фундаментальное ограничение: виртуальные ордера не влияют на рынок. Для крупных объемов (более 1% объема стакана) мы добавляем модель slippage, зависящую от глубины рынка. Средняя задержка исполнения ордера в симуляторе составляет 50 мс — этого достаточно для high-frequency стратегий.
Leaderboard и соревновательный элемент
async def get_leaderboard( self, period: str = '7d' ) -> list[dict]: all_accounts = await self.db.get_all_accounts() prices = await self.feed.get_all_prices() rankings = [] for account in all_accounts: pnl = account.get_pnl_percent(prices) rankings.append({ 'user': account.user_id, 'pnl_percent': pnl, 'portfolio_value': float(account.get_portfolio_value(prices)), 'trades_count': len(account.trade_history), }) return sorted(rankings, key=lambda x: x['pnl_percent'], reverse=True)[:100] Leaderboard добавляет соревновательный элемент и мотивирует пользователей активнее использовать платформу — хороший инструмент для engagement и конверсии в реальную торговлю.
Ограничения симулятора и как их обойти
Мы также учитываем фундаментальные ограничения симуляции. Виртуальные ордера не двигают цену, поэтому для крупных заявок (более 10% объема спреда) применяем динамический коэффициент slippage: 0.1% на каждые 10% объема спреда. Задержки feed искажают результаты — используем буферизацию и re-sync по событию. Если полный стакан недоступен, генерируем его из потока сделок. Эти меры приближают симуляцию к поведению реального рынка.
Сравнение подходов к тестированию стратегий
| Метод | Реалистичность | Сложность внедрения | Риск для средств |
|---|---|---|---|
| Backtesting | Средняя (зависит от качества данных) | Низкая | Нет |
| Paper trading (live) | Высокая (учитывает slippage, комиссии) | Средняя | Нет |
| Реальная торговля | Полная | Высокая | Высокий |
Что входит в работу
Мы предоставляем полную техническую документацию (архитектура, API, модели данных), доступы к репозиторию и демо-стенду, обучение для вашей команды (2-3 сессии), поддержку на этапе эксплуатации (SLA 24/7 для критических инцидентов). Дополнительно: помощь в интеграции с existing trading platform, настройка мониторинга и алертов.
Сроки ориентировочно
От 3 до 8 недель в зависимости от сложности: базовый симулятор — 3-4 недели, с leaderboard и advanced slippage — 6-8. Стоимость рассчитывается индивидуально — зависит от функциональных требований и интеграций.
Как мы разрабатываем симулятор: пошаговый процесс
- Анализ требований и спецификация — определяем функциональность, интеграции и метрики.
- Проектирование execution engine — архитектура обработки ордеров, модели аккаунтов.
- Разработка core-логики — реализация виртуального портфеля, исполнения ордеров.
- Интеграция с источником данных — подключение к биржевым API (WebSocket, REST) или историческим данным.
- UI/UX дашборда — отображение балансов, истории сделок, P&L, leaderboard.
- Тестирование — unit-тесты, интеграционные тесты на Foundry/Hardhat, фаззинг (Echidna) для смарт-контрактов.
- Документация и деплой — техническая документация, API-документация, развертывание на AWS/GCP, мониторинг.
Как мы гарантируем качество?
Мы используем формальную верификацию для критических путей (через Slither, Certora), проводим code review и предлагаем аудит смарт-контрактов, если симулятор включает on-chain компоненты. Опыт команды — 7+ лет в разработке, сертифицированные разработчики Solidity и Rust. 10+ успешных проектов paper trading для DeFi-протоколов.
Что делать дальше?
Закажите разработку симулятора под ваши задачи — свяжитесь с нами для обсуждения деталей. Получите консультацию: напишите нам, и мы оценим ваш проект в течение 3 рабочих дней. Разработаем симулятор под ваши уникальные требования с гарантией производительности и реалистичности.







