Розробка бота для ребалансування портфеля

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Розробка бота для ребалансування портфеля
Середній
~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

Розробка бота для ребалансування портфеля

Ребалансуючий бот підтримує задану аллокацію активів у портфелі. Якщо BTC виросла з 50% до 65% через ріст ціни, бот продає частину BTC та докупує інші активи до цільових ваг. Це дисциплінований підхід до управління портфелем: автоматично фіксує прибуток у виросших активах та купує недооцінені.

Стратегії ребалансування

Calendar rebalancing (за часом)

Ребалансування за розкладом незалежно від відхилень:

# Тижнева ребалансування кожний понеділок о 12:00 UTC
schedule = {
    'type': 'calendar',
    'interval': 'weekly',
    'day': 'monday',
    'time': '12:00'
}

Просто та передбачуваного, але може совпасти з неблагоприятним рыночним моментом.

Threshold rebalancing (за відхиленням)

Ребалансування тільки коли вага активу відхилиться від ціль на N%:

def needs_rebalancing(
    current_weights: dict,
    target_weights: dict,
    threshold_percent: float = 5.0
) -> bool:
    for asset, target_weight in target_weights.items():
        current = current_weights.get(asset, 0)
        deviation = abs(current - target_weight)
        if deviation >= threshold_percent:
            return True
    return False

Більш ефективно: ребалансуємо тільки коли дійсно потрібно.

Hybrid approach

Перевіряємо щодня, але ребалансуємо тільки при відхиленні >5%:

class HybridRebalancer:
    def should_rebalance(self, portfolio: Portfolio) -> bool:
        current_weights = portfolio.get_weights()
        max_deviation = max(
            abs(current_weights[a] - self.target_weights[a])
            for a in self.target_weights
        )
        return max_deviation >= self.threshold

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

Розрахунок ребалансуючих ордерів

from decimal import Decimal
from typing import dict

class RebalancingCalculator:
    def calculate_trades(
        self,
        current_balances: dict[str, Decimal],
        current_prices: dict[str, Decimal],
        target_weights: dict[str, float]  # сума = 100
    ) -> list[RebalanceTrade]:
        # Рахуємо поточну вартість портфеля
        total_value = sum(
            current_balances[asset] * current_prices[asset]
            for asset in current_balances
        )

        trades = []

        for asset, target_weight in target_weights.items():
            target_value = total_value * Decimal(str(target_weight / 100))
            current_value = current_balances.get(asset, Decimal(0)) * current_prices[asset]

            diff_value = target_value - current_value

            if abs(diff_value) < Decimal('10'):  # Мінімум $10 для торговлі
                continue

            diff_quantity = diff_value / current_prices[asset]

            trades.append(RebalanceTrade(
                asset=asset,
                side='buy' if diff_value > 0 else 'sell',
                quantity=abs(diff_quantity),
                value_usd=abs(diff_value),
                current_weight=float(current_value / total_value * 100),
                target_weight=target_weight
            ))

        return trades

    def optimize_trade_order(self, trades: list[RebalanceTrade]) -> list[RebalanceTrade]:
        """Спочатку продаємо, потім купуємо — не потрібен додатковий USDT"""
        sells = [t for t in trades if t.side == 'sell']
        buys = [t for t in trades if t.side == 'buy']
        return sells + buys

Виконання ребалансування

class RebalancingBot:
    async def execute_rebalance(self) -> RebalanceReport:
        # Отримуємо поточний стан
        balances = await self.exchange.get_balances()
        prices = await self.exchange.get_prices(list(self.target_weights.keys()))

        current_weights = self.calculate_weights(balances, prices)

        if not self.should_rebalance_now(current_weights):
            logger.info("Ребалансування не потрібне")
            return RebalanceReport(skipped=True)

        trades = self.calculator.calculate_trades(balances, prices, self.target_weights)
        optimized_trades = self.calculator.optimize_trade_order(trades)

        executed = []
        for trade in optimized_trades:
            try:
                order = await self.exchange.place_market_order(
                    symbol=f"{trade.asset}/USDT",
                    side=trade.side,
                    quantity=float(trade.quantity)
                )
                executed.append({
                    'trade': trade,
                    'fill_price': order.fill_price,
                    'actual_quantity': order.filled_quantity,
                    'fee': order.fee
                })
                logger.info(f"Ребалансовано {trade.asset}: {trade.side} {trade.quantity:.4f}")
            except Exception as e:
                logger.error(f"Не вдалося виконати сділку {trade.asset}: {e}")

        return RebalanceReport(
            executed_trades=executed,
            portfolio_before=current_weights,
            total_cost_usd=sum(t['fee'] for t in executed),
            timestamp=datetime.utcnow()
        )

Цільові аллокації

Приклад конфігурації

portfolio:
  target_weights:
    BTC: 40
    ETH: 30
    SOL: 15
    BNB: 10
    USDT: 5  # кеш-подушка

rebalancing:
  strategy: hybrid
  threshold_percent: 5.0
  check_interval_hours: 24
  min_trade_usd: 20

  # Часові обмеження
  rebalance_window:
    days: ['monday', 'tuesday', 'wednesday', 'thursday', 'friday']
    hours_utc: [8, 20]  # тільки з 8 до 20 UTC

risk:
  max_single_trade_percent: 20  # не більше 20% портфеля за раз
  slippage_tolerance: 0.5

Динамічні ваги

Продвинутий варіант: ваги змінюються в залежності від рыночних умов:

def calculate_dynamic_weights(market_data: dict) -> dict:
    """
    Risk-parity: розподіляємо вагу обернено пропорціонально волатильності.
    Активи з меншою волатильністю отримують більший вага.
    """
    assets = ['BTC', 'ETH', 'SOL', 'BNB']
    volatilities = {a: market_data[a]['vol_30d'] for a in assets}

    # Обернена волатильність
    inv_vol = {a: 1 / v for a, v in volatilities.items()}
    total_inv_vol = sum(inv_vol.values())

    weights = {a: inv_vol[a] / total_inv_vol * 100 for a in assets}
    return weights

Податкові розраховування

Кожна ребалансування — це податковою подія в більшості юрисдикцій (реалізація capital gain або loss). При високій частоті ребалансувань податкові зобов'язання можуть перевищити вигоду від ребалансування.

Оптимізація: ребалансувати через збиткові позиції (tax-loss harvesting) — продавати збиткові активи, перекладаючи в растучие. Автоматизація tax-loss harvesting — окрема та вмст потребувана функція для податкових юрисдикцій з деталізованим crypto reporting (США, Німеччина).

Ребалансуючий бот — це дисципліна, автоматизована в код. Дослідження показують: систематична ребалансування раз на квартал перевищує buy-and-hold на 0.5-2% в рік на волатільних активах за рахунок rebalancing premium.