Розробка бота на базі ковзних середніх (MA/EMA)

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Розробка бота на базі ковзних середніх (MA/EMA)
Простий
~3-5 днів
Часті запитання

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

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

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1285
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1198
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    902
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1121
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    589
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    857

Розробка бота на базі скользящих середніх (MA/EMA)

Скользящі середні (Moving Average) — базовий і один з найбільш надійних інструментів технічного аналізу. Бот на MA/EMA генерує сигнали на основі пересічень та положення ціни відносно середньої. Простий у реалізації, зрозумілий у логіці, та при правильній параметризації дає стабільні результати на трендових ринках.

MA vs EMA: в чому різниця

SMA (Simple MA) — просте середнє за N періодів. Усі свічки мають однаковий вага.

EMA (Exponential MA) — зважене середнє, останні свічки мають більший вага. Швидше реагує на зміни ціни.

import pandas as pd

def sma(close: pd.Series, period: int) -> pd.Series:
    return close.rolling(period).mean()

def ema(close: pd.Series, period: int) -> pd.Series:
    return close.ewm(span=period, adjust=False).mean()

Для трейдингу EMA переважніша: швидше сигналізує про розвороти тренду.

Класичні стратегії

Golden Cross / Death Cross

Пересічення EMA 50 та EMA 200:

  • Golden Cross: EMA50 пересікає EMA200 знизу вгору → бичий сигнал
  • Death Cross: EMA50 пересікає EMA200 зверху вниз → ведмежий сигнал
class GoldenCrossStrategy:
    def generate_signal(self, df: pd.DataFrame) -> str:
        ema_fast = ema(df['close'], 50).shift(1)
        ema_slow = ema(df['close'], 200).shift(1)

        # Пересічення: на попередній свічці було одне співвідношення, на поточній — інше
        prev_fast = ema_fast.iloc[-2]
        prev_slow = ema_slow.iloc[-2]
        curr_fast = ema_fast.iloc[-1]
        curr_slow = ema_slow.iloc[-1]

        if prev_fast <= prev_slow and curr_fast > curr_slow:
            return 'BUY'   # Golden Cross
        if prev_fast >= prev_slow and curr_fast < curr_slow:
            return 'SELL'  # Death Cross

        return 'HOLD'

Triple EMA стратегія (9/21/55)

Три середні дають більше підтверджень:

class TripleEMAStrategy:
    def generate_signal(self, df: pd.DataFrame) -> str:
        e9 = ema(df['close'], 9).shift(1)
        e21 = ema(df['close'], 21).shift(1)
        e55 = ema(df['close'], 55).shift(1)

        last_9 = e9.iloc[-1]
        last_21 = e21.iloc[-1]
        last_55 = e55.iloc[-1]
        price = df['close'].iloc[-1]

        # Бичий сигнал: усі EMA вишикувані по порядку
        if last_9 > last_21 > last_55 and price > last_9:
            return 'BUY'

        # Ведмежий сигнал: зворотний порядок
        if last_9 < last_21 < last_55 and price < last_9:
            return 'SELL'

        return 'HOLD'

Реалізація бота

class MABot:
    def __init__(self, strategy, exchange_client, config):
        self.strategy = strategy
        self.exchange = exchange_client
        self.config = config
        self.position = None
        self.candles = []

    async def on_candle(self, candle: dict):
        self.candles.append(candle)
        if len(self.candles) > 300:
            self.candles = self.candles[-300:]  # тримаємо історію

        if len(self.candles) < 210:  # потрібен прогрів для EMA 200
            return

        df = pd.DataFrame(self.candles)
        signal = self.strategy.generate_signal(df)

        if signal == 'BUY' and not self.position:
            order = await self.exchange.place_market_order(
                self.config.symbol, 'buy', self.config.position_size
            )
            self.position = {'entry': order.fill_price, 'side': 'long'}

        elif signal == 'SELL' and self.position and self.position['side'] == 'long':
            await self.exchange.place_market_order(
                self.config.symbol, 'sell', self.config.position_size
            )
            pnl = (order.fill_price - self.position['entry']) / self.position['entry'] * 100
            logger.info(f"Закрили long, PnL: {pnl:.2f}%")
            self.position = None

Параметризація та оптимізація

Оптимальні періоди EMA залежать від таймфрейму:

Таймфрейм Fast EMA Slow EMA Застосування
1h 9 21 Інтрадей
4h 21 55 Свинг
Daily 50 200 Golden/Death Cross
Weekly 20 50 Довгострок

EMA-стратегії працюють погано на боковому ринку — дають багато хибних сигналів. Додайте фільтр ADX (Average Directional Index): торгуйте тільки коли ADX > 25 (ринок у тренді). Це зменшує кількість сделок, але покращує якість.