ccxt для получения текущих открытых позиций на бирже Bybit (или любой другой CEX) и отправляет структурированный PnL-отчет в Telegram-канал или чат через Telegram Bot API.Исходный код
Для любого системного трейдера или квант-разработчика критически важно иметь оперативный доступ к метрикам риска своего портфеля. Если вы строите полноценного торгового робота, например, реализуя Пинг-понг стратегию на Bybit V5: Post-Only ордера на Python, регулярный мониторинг PnL становится ключевым элементом контроля просадок.
Для более сложных систем мониторинга, требующих мгновенной реакции на изменение рыночной микроструктуры, часто применяется Парсинг стакана ордеров Binance через WebSockets на Python asyncio. Однако для периодического контроля текущего состояния портфеля (например, раз в час) отлично подходит классический опрос REST API биржи с последующей отправкой отчета в Telegram.
В то время как на CEX мы полагаемся на API биржи, для DEX-сегмента мониторинг требует других подходов, таких как Декодирование транзакций Uniswap V3 Mint/Burn из мемпула на Python. В этой инструкции мы сфокусируемся на централизованных площадках и библиотеке ccxt.
import asyncio
import ccxt.async_support as ccxt
import aiohttp
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
API_KEY = 'YOUR_BYBIT_API_KEY'
API_SECRET = 'YOUR_BYBIT_API_SECRET'
TELEGRAM_TOKEN = 'YOUR_TELEGRAM_BOT_TOKEN'
TELEGRAM_CHAT_ID = 'YOUR_TELEGRAM_CHAT_ID'
async def send_telegram_message(session: aiohttp.ClientSession, text: str):
url = f'https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage'
payload = {
'chat_id': TELEGRAM_CHAT_ID,
'text': text,
'parse_mode': 'HTML'
}
try:
async with session.post(url, json=payload) as response:
if response.status != 200:
logger.error(f'Ошибка отправки TG: {await response.text()}')
except Exception as e:
logger.error(f'Ошибка сети при отправке в TG: {e}')
async def fetch_and_report():
exchange = ccxt.bybit({
'apiKey': API_KEY,
'secret': API_SECRET,
'options': {
'defaultType': 'swap',
}
})
async with aiohttp.ClientSession() as session:
try:
positions = await exchange.fetch_positions()
active_positions = [p for p in positions if float(p.get('contracts', 0)) > 0]
if not active_positions:
await send_telegram_message(session, '📊 Отчет по позициям:\nНет открытых позиций.')
return
report = '📊 Отчет по открытым позициям:\n\n'
total_unrealized_pnl = 0.0
for pos in active_positions:
symbol = pos.get('symbol')
side = pos.get('side')
size = float(pos.get('contracts', 0))
entry_price = float(pos.get('entryPrice', 0))
mark_price = float(pos.get('markPrice', 0))
unrealized_pnl = float(pos.get('unrealizedPnl', 0))
leverage = pos.get('leverage', 'N/A')
total_unrealized_pnl += unrealized_pnl
side_emoji = '🟢 LONG' if side.lower() == 'long' else '🔴 SHORT'
pnl_emoji = '📈' if unrealized_pnl >= 0 else '📉'
report += (
f'{symbol} ({side_emoji} x{leverage})\n'
f'• Размер: {size}\n'
f'• Вход: {entry_price:.4f} | Марк: {mark_price:.4f}\n'
f'• PnL: {pnl_emoji} {unrealized_pnl:+.2f} USDT\n\n'
)
pnl_total_emoji = '🟢' if total_unrealized_pnl >= 0 else '🔴'
report += f'Итоговый нереализованный PnL: {pnl_total_emoji} {total_unrealized_pnl:+.2f} USDT'
await send_telegram_message(session, report)
except Exception as e:
logger.error(f'Ошибка при получении данных: {e}')
await send_telegram_message(session, f'❌ Ошибка выполнения скрипта: {str(e)}')
finally:
await exchange.close()
if __name__ == "__main__":
asyncio.run(fetch_and_report()) Разбор параметров
API_KEYиAPI_SECRET: Ключи доступа к API биржи (в примере используется Bybit). Для безопасности рекомендуется использовать ключи с правами только на чтение (Read-Only).TELEGRAM_TOKEN: Уникальный токен вашего Telegram-бота, полученный у официального бота@BotFather.TELEGRAM_CHAT_ID: Идентификатор чата или канала, куда бот будет отправлять отчеты. Получить его можно через специализированных ботов, например,@userinfobot.ccxt.bybit: Класс инициализации биржи. Благодаря унификацииccxt, вы можете легко заменить его наccxt.binanceили любой другой поддерживаемый коннектор.fetch_positions(): Унифицированный методccxtдля получения информации обо всех открытых позициях на фьючерсном аккаунте.
Как запустить
Для запуска скрипта вам понадобятся установленные библиотеки ccxt и aiohttp. Установите их с помощью пакетного менеджера: pip install ccxt aiohttp.
Сохраните код в файл pnl_reporter.py, укажите ваши API-ключи и Telegram-данные, после чего запустите скрипт командой: python pnl_reporter.py.
Для автоматизации регулярной отправки отчетов (например, каждые 30 минут) настройте планировщик задач cron в Linux или Task Scheduler в Windows.




