Technical indicators alert system development

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Technical indicators alert system development
Medium
~3-5 business days
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1214
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

Development of Crypto Social Trading Platform

Social trading is copying deals of successful traders in real time. eToro made this mainstream in traditional finance, then crypto-analogs appeared: Bybit Copy Trading, Bitget Copy Trade, OKX Copy Trading. Developing own platform—complex task with unique challenges in order synchronization and commission distribution.

Platform Architecture

Participant Roles

Provider (master trader)—experienced trader whose deals are copied. Earns profit share (usually 5–30% of follower profit) or fixed subscription.

Follower (copier)—user allocating part of capital for copying. Chooses provider by stats, sets limits.

Platform—gets commission from each copied deal or from profit share.

Order Copying

Key technical challenge: when provider places order, need synchronously place proportional orders for all active followers.

type CopyEngine struct {
    orderEngine *OrderEngine
    db          *DB
    mu          sync.RWMutex
}

func (ce *CopyEngine) OnProviderOrder(providerOrder Order) {
    followers := ce.getActiveFollowers(providerOrder.UserID)
    
    if len(followers) == 0 {
        return
    }
    
    // Parallel order placement for all copiers
    var wg sync.WaitGroup
    errors := make(chan error, len(followers))
    
    for _, follower := range followers {
        wg.Add(1)
        go func(f Follower) {
            defer wg.Done()
            
            copyOrder, err := ce.buildCopyOrder(providerOrder, f)
            if err != nil {
                errors <- fmt.Errorf("follower %d: %w", f.UserID, err)
                return
            }
            
            _, err = ce.orderEngine.PlaceOrder(copyOrder)
            if err != nil {
                errors <- fmt.Errorf("follower %d order failed: %w", f.UserID, err)
            }
        }(follower)
    }
    
    wg.Wait()
    close(errors)
    
    // Log failed copies
    for err := range errors {
        log.Error("Copy order failed", "error", err)
    }
}

Follower Position Sizing

Provider may have $100k, follower—$500. Need proportional adaptation:

type PositionSizer struct{}

func (ps *PositionSizer) Calculate(
    providerOrder Order,
    providerBalance Decimal,
    follower Follower,
) (Decimal, error) {
    // What % of balance does provider use
    providerUsagePct := providerOrder.Quantity.Mul(providerOrder.Price).
        Div(providerBalance).Mul(Decimal("100"))
    
    // Three copy modes
    switch follower.CopyMode {
    case "fixed_amount":
        // Always copy fixed amount
        return follower.FixedAmount.Div(providerOrder.Price), nil
        
    case "proportional":
        // Same % of follower's balance
        copyAmount := follower.AllocatedBalance.Mul(providerUsagePct).Div(Decimal("100"))
        return copyAmount.Div(providerOrder.Price), nil
        
    case "multiplier":
        // X-times the relative size
        copyAmount := follower.AllocatedBalance.Mul(providerUsagePct).
            Mul(follower.Multiplier).Div(Decimal("100"))
        return copyAmount.Div(providerOrder.Price), nil
    }
    
    return Decimal("0"), ErrUnknownCopyMode
}

Important checks before copying:

  • Enough free balance for follower
  • Position doesn't exceed max risk limit
  • Position doesn't exceed max open positions setting

Position Close Synchronization

When provider closes position—close all copied positions:

func (ce *CopyEngine) OnProviderPositionClose(providerTradeID string) {
    // Find all open copy orders linked to this trade
    copyOrders := ce.db.GetCopyOrdersByProviderTrade(providerTradeID)
    
    for _, copyOrder := range copyOrders {
        if copyOrder.Status == OrderStatusOpen {
            // Close with market order immediately
            closeOrder := Order{
                UserID: copyOrder.FollowerID,
                Pair:   copyOrder.Pair,
                Side:   copyOrder.Side.Opposite(),
                Type:   Market,
                Quantity: copyOrder.RemainingQty,
            }
            ce.orderEngine.PlaceOrder(closeOrder)
        }
    }
}

Provider Statistics

Statistics—main tool for provider selection. Must be honest and server-verified (not provider-submitted).

CREATE MATERIALIZED VIEW provider_stats AS
SELECT
    p.user_id,
    p.display_name,
    -- Key metrics
    COUNT(DISTINCT t.id) AS total_trades,
    COUNT(CASE WHEN t.pnl > 0 THEN 1 END)::float / 
        NULLIF(COUNT(DISTINCT t.id), 0) * 100 AS win_rate,
    SUM(t.pnl) AS total_pnl_usd,
    -- ROI by periods
    SUM(CASE WHEN t.closed_at >= NOW() - INTERVAL '7 days' 
        THEN t.pnl_pct ELSE 0 END) AS roi_7d,
    SUM(CASE WHEN t.closed_at >= NOW() - INTERVAL '30 days' 
        THEN t.pnl_pct ELSE 0 END) AS roi_30d,
    -- Risk metrics
    MIN(t.pnl_pct) AS max_loss_single_trade,
    MAX(dd.drawdown) AS max_drawdown,
    -- Sharpe Ratio (simplified)
    AVG(t.pnl_pct) / NULLIF(STDDEV(t.pnl_pct), 0) AS sharpe,
    -- Activity
    COUNT(DISTINCT f.user_id) AS active_followers,
    SUM(f.allocated_balance) AS total_aum
FROM providers p
JOIN trades t ON t.user_id = p.user_id AND t.is_copy_trade = false
LEFT JOIN drawdowns dd ON dd.provider_id = p.user_id
LEFT JOIN copy_relationships f ON f.provider_id = p.user_id AND f.status = 'active'
GROUP BY p.user_id, p.display_name;

REFRESH MATERIALIZED VIEW CONCURRENTLY provider_stats;  -- every 5 minutes

Equity Curve

For each provider—equity curve history—$10,000 hypothetical deposit growth. Best visual indicator of results stability.

def calculate_equity_curve(trades: list[Trade], initial_equity: float = 10000) -> list[dict]:
    equity = initial_equity
    curve = [{'date': trades[0].opened_at.date(), 'equity': equity}]
    
    for trade in sorted(trades, key=lambda t: t.closed_at):
        pnl_usd = equity * (trade.pnl_pct / 100)
        equity += pnl_usd
        curve.append({
            'date': trade.closed_at.date(),
            'equity': round(equity, 2),
            'pnl_pct': round(trade.pnl_pct, 2),
        })
    
    return curve

Monetization Model and Profit Distribution

Profit Share Calculation (High Watermark)

High Watermark—standard model for hedge funds and copy trading: provider gets profit share only from new record profits. If capital drops and recovers to old max—no profit share.

class ProfitShareCalculator:
    def calculate(self, follower_id: int, provider_id: int) -> Decimal:
        hwm = self.get_high_watermark(follower_id, provider_id)
        current_equity = self.get_follower_equity_for_provider(follower_id, provider_id)
        
        if current_equity <= hwm:
            return Decimal('0')  # no new profit—no profit share
        
        new_profit = current_equity - hwm
        provider_share_pct = self.get_provider_share_pct(provider_id)  # e.g., 20%
        platform_fee_pct = Decimal('2')  # 2% platform takes from profit share
        
        provider_earnings = new_profit * (provider_share_pct / 100)
        platform_earnings = provider_earnings * (platform_fee_pct / 100)
        
        # Update high watermark
        self.update_high_watermark(follower_id, provider_id, current_equity)
        
        return provider_earnings - platform_earnings

Settlement Schedule

Profit share calculated weekly or monthly. Settlement workflow:

  1. Snapshot all equity positions on settlement date
  2. Calculate profit share for each (follower, provider) pair
  3. Transfer commissions: debit from follower, credit to provider
  4. Notify both sides
  5. Update high watermark

Risk Controls for Copiers

type CopyRiskControls struct {
    MaxLoss         Decimal  // -20%: auto-stop on drawdown
    MaxOpenTrades   int      // max open deals
    MaxPerTrade     Decimal  // % of allocated balance per deal
    StopCopyOnClose bool     // stop copying on exit?
}

func (ce *CopyEngine) CheckFollowerRisk(follower Follower, newOrder Order) error {
    // Check drawdown
    currentDrawdown := ce.calculateCurrentDrawdown(follower.ID)
    if currentDrawdown.GreaterThan(follower.RiskControls.MaxLoss.Abs()) {
        ce.stopCopying(follower.ID, "max_loss_reached")
        return ErrMaxLossReached
    }
    
    // Check open positions count
    openTrades := ce.countOpenCopyTrades(follower.ID)
    if openTrades >= follower.RiskControls.MaxOpenTrades {
        return ErrMaxOpenTradesReached
    }
    
    return nil
}

Leaderboard and Discovery

Provider selection page—critical for conversion:

// Leaderboard filters
interface LeaderboardFilters {
  period: '7d' | '30d' | '90d' | 'all';
  minAUM: number;
  minFollowers: number;
  maxDrawdown: number;
  riskLevel: 'low' | 'medium' | 'high';
  strategy: 'spot' | 'futures' | 'mixed';
}

// Provider card
interface ProviderCard {
  userId: string;
  displayName: string;
  avatar: string;
  roi30d: number;
  winRate: number;
  maxDrawdown: number;
  followers: number;
  aum: number;
  profitSharePct: number;
  equityCurve: EquityPoint[];  // mini sparkline
}

Regulatory Aspects

Social trading falls under regulation in many jurisdictions (provider de-facto manages others' funds). Important:

  • Legal consultation on target jurisdiction
  • Disclaimers: past results don't guarantee future
  • Amount limits for unregulated platforms

Timeline and Cost

Component Time
Copy engine (order routing) 4–6 weeks
Position sizing algorithms 2–3 weeks
Provider statistics 3–4 weeks
Profit share calculation 2–3 weeks
Leaderboard and discovery 3–4 weeks
Risk controls for copiers 2–3 weeks

Full social trading platform: 4–6 months.