Development of Social Trading System
Social trading allows less experienced users to copy trades of successful traders, and professionals to monetize their strategies through subscribers. eToro popularized this format in traditional finance; in crypto it's implemented in Bitget Copy Trade, Bybit Copy Trading and independent platforms.
Key Components
Leader Board — trader rating with verified results: P&L, Sharpe ratio, max drawdown, win rate, subscriber count. Data must be verified — cannot rely on self-declaration.
Copy Trading Engine — when receiving signal from master-trader, system automatically repeats order for each follower with scaling by size.
Risk Management for followers — follower sets limits: max position size, max drawdown for auto-stop.
Compensation System — fee calculation for master-traders: fixed subscription fee or performance fee (% of follower profit).
Copy Trading Engine
class CopyTradingEngine:
async def on_master_order(self, master_id: str, order: MasterOrder):
"""Called when master-trader places order"""
followers = await self.follower_repo.get_active_followers(master_id)
if not followers:
return
# Process all followers in parallel
tasks = [
self.copy_order_for_follower(follower, order)
for follower in followers
]
results = await asyncio.gather(*tasks, return_exceptions=True)
# Log results
for follower, result in zip(followers, results):
if isinstance(result, Exception):
logger.error(f"Copy failed for {follower.id}: {result}")
async def copy_order_for_follower(self, follower: FollowerConfig, master_order: MasterOrder):
# Calculate position size with follower settings
follower_balance = await self.get_usdt_balance(follower.user_id)
scaled_quantity = self.scale_quantity(
master_order.quantity,
master_order.master_portfolio_value,
follower_balance,
follower.allocation_pct,
)
# Check follower risk limits
risk_check = await self.risk_manager.check(
follower_id=follower.user_id,
symbol=master_order.symbol,
quantity=scaled_quantity,
side=master_order.side,
)
if not risk_check.approved:
logger.warning(f"Risk check failed: {risk_check.reason}")
return None
# Place order
return await self.order_service.place_order(
user_id=follower.user_id,
exchange=follower.exchange,
symbol=master_order.symbol,
side=master_order.side,
order_type='MARKET',
quantity=scaled_quantity,
copy_reference=master_order.id,
)
Trade History Verification
Critical: master-trader results must be verified through real exchange data, not self-declared.
class TradeHistoryVerifier:
async def verify_master_account(self, user_id: str, exchange_api_key: str):
"""Verify trade history via read-only API key"""
exchange = ExchangeClient(exchange_api_key, permissions=['READ_ONLY'])
orders = await exchange.get_order_history(days=90)
trades = await exchange.get_trade_history(days=90)
metrics = calculate_performance_metrics(orders, trades)
await self.performance_repo.save(
user_id=user_id,
metrics=metrics,
verified=True,
verification_time=datetime.utcnow(),
)
return VerificationResult(verified=True, metrics=metrics)
Performance Metrics
def calculate_performance_metrics(orders: list, trades: list):
daily_returns = compute_daily_returns(trades)
return PerformanceMetrics(
total_pnl=sum(t.pnl for t in trades),
win_rate=len([t for t in trades if t.pnl > 0]) / len(trades),
sharpe_ratio=sharpe(daily_returns),
sortino_ratio=sortino(daily_returns),
max_drawdown=max_drawdown(daily_returns),
profit_factor=sum(t.pnl for t in trades if t.pnl > 0) / abs(sum(t.pnl for t in trades if t.pnl < 0)),
total_trades=len(trades),
)
Fee Structure
Compensation for master-traders — key element of platform economics:
Performance Fee (20%) — master gets 20% of follower profit. Calculated via high-water mark: fee only on new profits exceeding previous peak.
Management Fee — fixed monthly charge from follower (e.g., $10-50/month).
Platform commission — platform keeps 30-40% of master's fee.
Risk Controls for Followers
Mandatory protective mechanisms:
- Max drawdown stop — auto-stop copying at drawdown > N%
- Max position size — no more than X% of capital in one position
- Whitelist symbols — copy only specific assets
- Pause/Resume — manual control without unlinking
- Emergency close — close all open positions at once
Users must always have control — this is not optional but requirement for serious platform.







