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







