Бот для торговли на бирже на Python: от простых до сложных решений
Основы создания торгового бота на Python
Эффективное решение: бот на библиотеке ccxt с использованием скользящих средних
Этот подход позволяет подключиться к любой криптовалютной бирже через единый API и реализовать простую стратегию пересечения скользящих средних (SMA). Бот работает в реальном времени, получая цены через REST API.
import ccxt
import time
import pandas as pd
exchange = ccxt.binance({
'apiKey': 'ВАШ_API_KEY',
'secret': 'ВАШ_SECRET',
'enableRateLimit': True,
})
def get_sma(symbol, period, timeframe='1h'):
ohlcv = exchange.fetch_ohlcv(symbol, timeframe, limit=period+1)
df = pd.DataFrame(ohlcv, columns=['timestamp','open','high','low','close','volume'])
sma = df['close'].rolling(window=period).mean().iloc[-1]
return sma
def trade_loop():
symbol = 'BTC/USDT'
short_sma = 10
long_sma = 30
position = None
while True:
try:
s = get_sma(symbol, short_sma)
l = get_sma(symbol, long_sma)
print(f"SMA{short_sma}={s:.2f}, SMA{long_sma}={l:.2f}")
if s > l and position != 'long':
exchange.create_market_buy_order(symbol, 0.001)
position = 'long'
print('Открыта длинная позиция')
elif s < l and position == 'long':
exchange.create_market_sell_order(symbol, 0.001)
position = None
print('Закрыта длинная позиция')
time.sleep(3600)
except Exception as e:
print(f"Ошибка: {e}")
time.sleep(60)
trade_loop()
торговый бот python (торговый бот на python)
Пояснение шагов:
- Импорт ccxt – универсальная библиотека для работы с биржами.
- Создание объекта exchange с ключами – авторизация.
- Функция get_sma загружает свечи и вычисляет скользящее среднее.
- В бесконечном цикле проверяется пересечение SMA. При сигнале создаётся рыночный ордер.
- Переменная position предотвращает повторные входы.
Типичные проблемы и решения:
- Ошибка rate limit: слишком частые запросы. Решение – установить enableRateLimit=True и добавить задержку.
- Недостаточно средств: проверять баланс перед ордером, использовать manage_position с расчётом размера.
- Сбой сети: обернуть цикл в try-except и переподключаться.
Варианты реализации торгового бота
Как реализовать бота на основе индикатора RSI?
Используется библиотека ta (technical analysis). Сигнал – пересечение уровня oversold/overbought.
import ccxt
import ta
import pandas as pd
def get_rsi(symbol, period=14):
ohlcv = exchange.fetch_ohlcv(symbol, '1h', limit=period+1)
df = pd.DataFrame(ohlcv, columns=['t','o','h','l','c','v'])
rsi = ta.momentum.RSIIndicator(df['c'], window=period).rsi().iloc[-1]
return rsi
Цель: ловить развороты на перекупленности/перепроданности. Использовать как дополнение к трендовой стратегии.
Проблема: RSI даёт ложные сигналы на сильном тренде. Решение – комбинировать с трендовым фильтром (например, SMA).
Как создать арбитражного бота между биржами?
Ищется разница цен одного актива на разных площадках и выполняется одновременная покупка/продажа.
exchange1 = ccxt.binance()
exchange2 = ccxt.kraken()
symbol = 'ETH/USDT'
ticker1 = exchange1.fetch_ticker(symbol)
ticker2 = exchange2.fetch_ticker(symbol)
spread = ticker2['ask'] - ticker1['bid']
if spread > threshold:
# покупка на binance, продажа на kraken
pass
Цель: получение безрисковой прибыли. Требуются низкие комиссии и быстрые API.
Проблема: задержки исполнения и комиссии съедают прибыль. Решение – использовать кросс-биржевые спреды только >0.5% и тестировать latency.
Как настроить Freqtrade для автоматической торговли?
Freqtrade – готовый фреймворк с поддержкой стратегий, backtesting и live trading.
# Установка
pip install freqtrade
# Создание конфигурации
freqtrade new-config --config config.json
# Запуск backtest
freqtrade backtesting --config config.json --strategy SampleStrategy
Цель: быстрое развёртывание без написания кода с нуля. Подходит для новичков.
Проблема: сложность настройки стратегии под свои нужды. Решение – изучить встроенные стратегии и модифицировать.
Как протестировать стратегию на исторических данных с backtrader?
Backtrader позволяет симулировать торговлю и оценить доходность.
import backtrader as bt
class SmaCross(bt.Strategy):
def __init__(self):
self.sma1 = bt.indicators.SMA(self.data.close, period=10)
self.sma2 = bt.indicators.SMA(self.data.close, period=30)
def next(self):
if self.sma1 > self.sma2 and not self.position:
self.buy()
elif self.sma1 < self.sma2 and self.position:
self.sell()
cerebro = bt.Cerebro()
data = bt.feeds.YahooFinanceData(dataname='BTC-USD', fromdate=..., todate=...)
cerebro.adddata(data)
cerebro.addstrategy(SmaCross)
cerebro.run()
cerebro.plot()
Цель: оценить эффективность до реальной торговли. Позволяет подобрать параметры.
Проблема: переобучение на исторических данных. Решение – использовать out-of-sample тестирование и валидацию.
Расширенные примеры кода торгового бота
Полный бот с websocket и управлением капиталом
Пример использует Websocket для получения цен в реальном времени, логирование и динамический размер позиции.
import ccxt.pro as ccxtpro
import asyncio
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
exchange = ccxtpro.binance()
symbol = 'BTC/USDT'
position = None
capital = 1000.0
fee = 0.001
async def trade():
global position
async for ticker in exchange.watch_ticker(symbol):
price = ticker['last']
# Простая стратегия: если цена выше SMA50 -> long
# Здесь для примера используем фиктивные условия
if price > 50000 and position != 'long':
size = capital * 0.01 / price
order = await exchange.create_market_buy_order(symbol, size)
position = 'long'
logging.info(f"Buy {size} BTC at {price}")
elif price < 45000 and position == 'long':
order = await exchange.create_market_sell_order(symbol, None)
position = None
logging.info(f"Sell at {price}")
asyncio.run(trade())
2025-04-01 12:00:05 - Buy 0.0002 BTC at 50123.4 2025-04-01 14:32:11 - Sell at 44890.1
Пояснение: используется ccxt.pro для асинхронного WebSocket, что снижает задержки. Размер позиции рассчитывается как 1% от капитала. Логирование помогает отслеживать действия.
Бот с машинным обучением (LSTM) для прогноза
Пример обучения простой LSTM на исторических ценах и генерации сигналов.
import numpy as np
import pandas as pd
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense
from sklearn.preprocessing import MinMaxScaler
data = pd.read_csv('btc_usd_1h.csv')['close'].values
scaler = MinMaxScaler()
data_scaled = scaler.fit_transform(data.reshape(-1,1))
# Создание последовательностей
def create_sequences(d, seq_len=60):
X, y = [], []
for i in range(len(d)-seq_len-1):
X.append(d[i:i+seq_len])
y.append(d[i+seq_len])
return np.array(X), np.array(y)
X, y = create_sequences(data_scaled)
model = Sequential([
LSTM(50, return_sequences=True, input_shape=(60,1)),
LSTM(50),
Dense(1)
])
model.compile(optimizer='adam', loss='mse')
model.fit(X, y, epochs=10, batch_size=32)
# Предсказание
last_60 = data_scaled[-60:].reshape(1,60,1)
pred = model.predict(last_60)
price_pred = scaler.inverse_transform(pred)
print(f"Предсказание следующей цены: {price_pred[0][0]:.2f}")
Предсказание следующей цены: 54321.67
Цель: генерация торговых сигналов на основе прогноза. Проблема: качество прогноза зависит от данных и архитектуры сети.
Backtesting с оптимизацией параметров
Используется backtrader с поиском лучших периодов SMA.
import backtrader as bt
import itertools
class SmaOpt(bt.Strategy):
params = (('pfast', 10), ('pslow', 30))
def __init__(self):
self.sma_fast = bt.indicators.SMA(self.data.close, period=self.params.pfast)
self.sma_slow = bt.indicators.SMA(self.data.close, period=self.params.pslow)
def next(self):
if self.sma_fast > self.sma_slow and not self.position:
self.buy()
elif self.sma_fast < self.sma_slow and self.position:
self.sell()
cerebro = bt.Cerebro()
data = bt.feeds.YahooFinanceData(dataname='BTC-USD', fromdate='2023-01-01', todate='2024-01-01')
cerebro.adddata(data)
# Оптимизация
fast_range = range(5, 20, 5)
slow_range = range(20, 60, 10)
opt_results = []
for fast, slow in itertools.product(fast_range, slow_range):
cerebro.addstrategy(SmaOpt, pfast=fast, pslow=slow)
result = cerebro.run()
opt_results.append((fast, slow, result[0].analyzers.getbyname(???).get_analysis()['total']['pnl']))
Результат: таблица с доходностью для каждой комбинации. Помогает выбрать лучшие параметры.