Việc xây dựng chiến lược market making trên Hyperliquid đòi hỏi nguồn dữ liệu L2 orderbook chính xác và đáng tin cậy. Tuy nhiên, Hyperliquid không cung cấp API lịch sử chính thức cho dữ liệu orderbook, khiến nhiều nhà phát triển gặp khó khăn trong việc backtest chiến lược. Bài viết này sẽ hướng dẫn bạn cách tiếp cận vấn đề này một cách hiệu quả, đồng thời so sánh các giải pháp có sẵn.

So Sánh Các Nguồn Dữ Liệu Orderbook

Trước khi đi vào chi tiết kỹ thuật, chúng ta cùng xem bảng so sánh giữa các nguồn cung cấp dữ liệu orderbook Hyperliquid hiện nay:

Tiêu chí HolySheep AI API Chính thức Hyperliquid Các dịch vụ Relay khác
Dữ liệu L2 Orderbook Lưu trữ đầy đủ, truy xuất theo timestamp Chỉ real-time, không lưu trữ lịch sử Hạn chế về độ sâu và độ chính xác
Historical Data Có, với độ phân giải cao Không hỗ trợ Lưu trữ ngắn hạn, thường 7-30 ngày
Độ trễ (Latency) <50ms Real-time 100-500ms
Giá cả Từ $0.42/MTok (DeepSeek V3.2) Miễn phí (giới hạn rate) $10-50/tháng
Phương thức thanh toán WeChat, Alipay, USDT, Credit Card Không áp dụng Thường chỉ USD
API Endpoint https://api.holysheep.ai/v1 hyperliquid.xyz Đa dạng

Tại Sao Cần Dữ Liệu L2 Orderbook Cho Market Making?

Market making là chiến lược đặt lệnh mua/bán liên tục để hưởng chênh lệch bid-ask. Để backtest hiệu quả, bạn cần:

Kiến Trúc Hệ Thống Backtest Với HolySheep AI

Đăng ký tại đây để bắt đầu sử dụng HolySheep AI - nơi cung cấp dữ liệu orderbook Hyperliquid với độ trễ dưới 50ms và chi phí chỉ từ $0.42/MTok khi sử dụng DeepSeek V3.2.

Sơ Đồ Luồng Dữ Liệu


┌─────────────────────────────────────────────────────────────────┐
│                    KIẾN TRÚC BACKTEST MARKET MAKING              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   ┌──────────────┐         ┌──────────────┐         ┌────────┐ │
│   │  Hyperliquid │────────▶│   HolySheep  │────────▶│ Your   │ │
│   │  Exchange    │  L2 API │   API Proxy  │  Rest   │ Python │ │
│   └──────────────┘         └──────────────┘         │ Script │ │
│                              │                      └────────┘ │
│                              │                             │     │
│                              ▼                             ▼     │
│                   ┌──────────────────┐           ┌──────────┐   │
│                   │ Historical Store │           │ Backtest │   │
│                   │ (Orderbook DB)   │           │ Engine   │   │
│                   └──────────────────┘           └──────────┘   │
│                                                            │     │
│                                                            ▼     │
│                                                   ┌────────────┐ │
│                                                   │ Results &  │ │
│                                                   │ Analytics  │ │
│                                                   └────────────┘ │
└─────────────────────────────────────────────────────────────────┘

Hướng Dẫn Kỹ Thuật Chi Tiết

Bước 1: Cài Đặt Môi Trường và Kết Nối API

# Cài đặt các thư viện cần thiết
pip install pandas numpy requests python-dotenv asyncio aiohttp

Cấu hình API HolySheep

import os import requests import pandas as pd from datetime import datetime, timedelta

Cấu hình API Key - lấy từ HolySheep Dashboard

HOLYSHEEP_API_KEY = "YOUR_HOLYSHEEP_API_KEY" # Thay bằng API key thực tế HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1"

Headers cho request

headers = { "Authorization": f"Bearer {HOLYSHEEP_API_KEY}", "Content-Type": "application/json" } def get_hyperliquid_orderbook_snapshot(symbol="BTC-USD", timestamp=None): """ Lấy snapshot orderbook Hyperliquid tại một thời điểm cụ thể """ endpoint = f"{HOLYSHEEP_BASE_URL}/hyperliquid/orderbook/history" params = { "symbol": symbol, "timestamp": timestamp or int(datetime.now().timestamp() * 1000), "depth": 20 # Số lượng level bid/ask } response = requests.get(endpoint, headers=headers, params=params) if response.status_code == 200: return response.json() else: raise Exception(f"API Error: {response.status_code} - {response.text}")

Test kết nối

try: data = get_hyperliquid_orderbook_snapshot("BTC-USD") print(f"✅ Kết nối thành công! Timestamp: {data.get('timestamp')}") print(f"Bid levels: {len(data.get('bids', []))}") print(f"Ask levels: {len(data.get('asks', []))}") except Exception as e: print(f"❌ Lỗi kết nối: {e}")

Bước 2: Tải Dữ Liệu Lịch Sử Cho Backtest

import asyncio
import aiohttp
from typing import List, Dict
import json

class HyperliquidBacktestDataLoader:
    """
    Class để tải dữ liệu orderbook lịch sử từ HolySheep cho market making backtest
    """
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.holysheep.ai/v1"
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
    
    async def fetch_orderbook_batch(
        self,
        session: aiohttp.ClientSession,
        symbol: str,
        start_ts: int,
        end_ts: int,
        interval_ms: int = 1000  # Mỗi giây lấy 1 snapshot
    ) -> List[Dict]:
        """
        Tải batch orderbook trong khoảng thời gian
        
        Args:
            session: aiohttp session
            symbol: Cặp giao dịch (VD: "BTC-USD")
            start_ts: Timestamp bắt đầu (milliseconds)
            end_ts: Timestamp kết thúc (milliseconds)
            interval_ms: Khoảng cách giữa các snapshot (ms)
        
        Returns:
            List các snapshot orderbook
        """
        endpoint = f"{self.base_url}/hyperliquid/orderbook/history/batch"
        
        payload = {
            "symbol": symbol,
            "start_timestamp": start_ts,
            "end_timestamp": end_ts,
            "interval_ms": interval_ms,
            "include_trades": True  # Bao gồm cả trade data
        }
        
        async with session.post(endpoint, headers=self.headers, json=payload) as resp:
            if resp.status == 200:
                return await resp.json()
            else:
                error_text = await resp.text()
                raise Exception(f"Batch fetch failed: {resp.status} - {error_text}")
    
    async def load_backtest_dataset(
        self,
        symbol: str,
        start_date: datetime,
        end_date: datetime,
        interval_ms: int = 1000
    ) -> pd.DataFrame:
        """
        Tải toàn bộ dataset cho backtest
        
        Returns:
            DataFrame với columns: timestamp, bids, asks, price, volume
        """
        start_ts = int(start_date.timestamp() * 1000)
        end_ts = int(end_date.timestamp() * 1000)
        
        all_snapshots = []
        batch_size = 24 * 60 * 60 * 1000  # 1 ngày mỗi batch
        
        connector = aiohttp.TCPConnector(limit=10)
        timeout = aiohttp.ClientTimeout(total=300)
        
        async with aiohttp.ClientSession(connector=connector, timeout=timeout) as session:
            current_ts = start_ts
            batch_count = 0
            
            while current_ts < end_ts:
                batch_end = min(current_ts + batch_size, end_ts)
                
                print(f"📥 Đang tải batch {batch_count + 1}: "
                      f"{datetime.fromtimestamp(current_ts/1000)} -> "
                      f"{datetime.fromtimestamp(batch_end/1000)}")
                
                try:
                    batch_data = await self.fetch_orderbook_batch(
                        session, symbol, current_ts, batch_end, interval_ms
                    )
                    all_snapshots.extend(batch_data.get('snapshots', []))
                    batch_count += 1
                    
                except Exception as e:
                    print(f"⚠️ Lỗi batch {batch_count + 1}: {e}")
                    # Retry sau 5 giây
                    await asyncio.sleep(5)
                
                current_ts = batch_end
        
        # Chuyển đổi sang DataFrame
        df = pd.DataFrame(all_snapshots)
        df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
        df = df.sort_values('timestamp')
        
        return df

Sử dụng

loader = HyperliquidBacktestDataLoader(api_key="YOUR_HOLYSHEEP_API_KEY")

Tải 7 ngày dữ liệu

start = datetime.now() - timedelta(days=7) end = datetime.now() print("🚀 Bắt đầu tải dữ liệu backtest...") df_orderbook = await loader.load_backtest_dataset( symbol="BTC-USD", start_date=start, end_date=end, interval_ms=1000 # 1 snapshot mỗi giây ) print(f"✅ Hoàn thành! Tổng snapshot: {len(df_orderbook)}") print(f"💾 Dung lượng: {df_orderbook.memory_usage(deep=True).sum() / 1024 / 1024:.2f} MB") df_orderbook.to_parquet('hyperliquid_orderbook_backtest.parquet')

Bước 3: Xây Dựng Market Making Backtest Engine

import numpy as np
from dataclasses import dataclass
from typing import Optional, Tuple
import pandas as pd

@dataclass
class Order:
    """Đại diện cho một lệnh đặt"""
    timestamp: pd.Timestamp
    side: str  # 'bid' hoặc 'ask'
    price: float
    quantity: float
    filled: bool = False
    fill_price: Optional[float] = None

@dataclass
class MarketMakingParams:
    """Tham số chiến lược market making"""
    spread_bps: float = 10.0       # Spread cơ bản (basis points)
    order_size: float = 0.1       # Kích thước mỗi lệnh (BTC)
    inventory_target: float = 0.0 # Mục tiêu inventory (0 = neutral)
    max_position: float = 1.0     # Vị thế tối đa cho phép
    cancel_threshold_ms: int = 5000 # Hủy lệnh sau bao lâu (ms)
    skew_factor: float = 0.5      # Hệ số nghiêng inventory (0-1)

class MarketMakingBacktester:
    """
    Engine backtest cho chiến lược market making trên Hyperliquid
    """
    
    def __init__(self, params: MarketMakingParams, maker_fee: float = 0.0003):
        self.params = params
        self.maker_fee = maker_fee  # Phí maker Hyperliquid: 0.03%
        self.orders: list[Order] = []
        self.position = 0.0
        self.cash = 0.0
        self.trades_history = []
        self.inventory_penalty = 0.0001  # Penalty per unit inventory
    
    def calculate_adjusted_spread(self, mid_price: float, volatility: float) -> float:
        """
        Tính spread đã điều chỉnh theo volatility
        """
        base_spread = self.params.spread_bps / 10000 * mid_price
        volatility_adjustment = volatility * mid_price * 2
        return max(base_spread, volatility_adjustment)
    
    def calculate_skew(self) -> float:
        """
        Tính độ nghiêng bid/ask dựa trên inventory
        """
        inventory_skew = (self.position - self.params.inventory_target) / self.params.max_position
        return 1 + inventory_skew * self.params.skew_factor
    
    def simulate_orderbook_fill(
        self,
        order_price: float,
        order_side: str,
        orderbook: dict,
        volume: float
    ) -> Tuple[bool, float]:
        """
        Mô phỏng fill lệnh dựa trên orderbook state
        """
        levels = orderbook['bids'] if order_side == 'bid' else orderbook['asks']
        
        remaining_qty = volume
        total_cost = 0.0
        
        for level_price, level_qty in levels:
            if order_side == 'bid':
                # Bid fill khi price >= level_price
                if order_price >= level_price:
                    fill_qty = min(remaining_qty, level_qty)
                    total_cost += fill_qty * level_price
                    remaining_qty -= fill_qty
            else:
                # Ask fill khi price <= level_price
                if order_price <= level_price:
                    fill_qty = min(remaining_qty, level_qty)
                    total_cost += fill_qty * level_price
                    remaining_qty -= fill_qty
            
            if remaining_qty <= 0:
                break
        
        filled = remaining_qty < volume
        avg_price = total_cost / (volume - remaining_qty) if filled else 0
        
        return filled, avg_price
    
    def calculate_pnl(
        self,
        df: pd.DataFrame,
        start_balance: float = 100000.0
    ) -> dict:
        """
        Chạy backtest và tính P&L
        
        Args:
            df: DataFrame với dữ liệu orderbook
            start_balance: Số dư ban đầu (USD)
        
        Returns:
            Dictionary chứa kết quả backtest
        """
        self.cash = start_balance
        self.position = 0
        self.orders = []
        self.trades_history = []
        
        for idx, row in df.iterrows():
            timestamp = row['timestamp']
            mid_price = (float(row['best_bid']) + float(row['best_ask'])) / 2
            
            # Tính volatility từ recent prices (simplified)
            volatility = float(row.get('volatility', 0.001))
            
            # Tính spread và skew
            spread = self.calculate_adjusted_spread(mid_price, volatility)
            skew = self.calculate_skew()
            
            # Kiểm tra và xử lý orders cũ
            self.process_expired_orders(timestamp)
            
            # Kiểm tra limit orders với orderbook hiện tại
            self.check_fills(row)
            
            # Đặt lệnh mới nếu position trong giới hạn
            if self.position < self.params.max_position:
                bid_price = mid_price - spread / 2 * skew
                self.place_order(timestamp, 'bid', bid_price, self.params.order_size)
            
            if self.position > -self.params.max_position:
                ask_price = mid_price + spread / 2 / skew
                self.place_order(timestamp, 'ask', ask_price, self.params.order_size)
            
            # Cập nhật unrealized P&L
            current_value = self.cash + self.position * mid_price
            self.trades_history.append({
                'timestamp': timestamp,
                'position': self.position,
                'cash': self.cash,
                'total_value': current_value,
                'mid_price': mid_price
            })
        
        return self.generate_report()
    
    def place_order(self, timestamp: pd.Timestamp, side: str, price: float, qty: float):
        """Đặt một lệnh mới"""
        order = Order(
            timestamp=timestamp,
            side=side,
            price=price,
            quantity=qty
        )
        self.orders.append(order)
    
    def process_expired_orders(self, current_time: pd.Timestamp):
        """Xử lý các lệnh đã hết hạn"""
        self.orders = [o for o in self.orders if o.filled]
    
    def check_fills(self, orderbook_row: pd.Series):
        """Kiểm tra xem các lệnh có được fill không"""
        best_bid = float(orderbook_row['best_bid'])
        best_ask = float(orderbook_row['best_ask'])
        bid_volume = float(orderbook_row.get('bid_volume', 0))
        ask_volume = float(orderbook_row.get('ask_volume', 0))
        
        for order in self.orders:
            if order.filled:
                continue
            
            if order.side == 'bid' and order.price >= best_ask:
                # Bid được fill ở giá ask
                order.filled = True
                self.position += order.quantity
                fee = order.quantity * best_ask * self.maker_fee
                self.cash -= order.quantity * best_ask + fee
                
            elif order.side == 'ask' and order.price <= best_bid:
                # Ask được fill ở giá bid
                order.filled = True
                self.position -= order.quantity
                fee = order.quantity * best_bid * self.maker_fee
                self.cash += order.quantity * best_bid - fee
    
    def generate_report(self) -> dict:
        """Tạo báo cáo kết quả backtest"""
        df_trades = pd.DataFrame(self.trades_history)
        
        if len(df_trades) < 2:
            return {"error": "Not enough data"}
        
        returns = df_trades['total_value'].pct_change().dropna()
        
        total_return = (df_trades['total_value'].iloc[-1] / 
                       df_trades['total_value'].iloc[0] - 1) * 100
        
        sharpe = returns.mean() / returns.std() * np.sqrt(252 * 24 * 3600) if returns.std() > 0 else 0
        
        max_dd = (df_trades['total_value'].cummax() - 
                 df_trades['total_value']).max() / df_trades['total_value'].cummax().max() * 100
        
        return {
            'total_return_pct': total_return,
            'sharpe_ratio': sharpe,
            'max_drawdown_pct': max_dd,
            'final_position': self.position,
            'final_cash': self.cash,
            'total_trades': len([o for o in self.orders if o.filled]),
            'avg_trade_size': self.params.order_size,
            'df_history': df_trades
        }

Chạy backtest

params = MarketMakingParams( spread_bps=15.0, order_size=0.05, max_position=0.5, skew_factor=0.3 ) backtester = MarketMakingBacktester(params) results = backtester.calculate_pnl(df_orderbook) print("=" * 50) print("📊 KẾT QUẢ BACKTEST MARKET MAKING") print("=" * 50) print(f"💰 Tổng lợi nhuận: {results['total_return_pct']:.2f}%") print(f"📈 Sharpe Ratio: {results['sharpe_ratio']:.2f}") print(f"📉 Max Drawdown: {results['max_drawdown_pct']:.2f}%") print(f"🔢 Tổng số lệnh fill: {results['total_trades']}")

Tích Hợp AI Để Phân Tích Chiến Lược

Một ưu điểm lớn khi sử dụng HolySheep AI là khả năng tích hợp các mô hình AI để phân tích và tối ưu chiến lược market making. Với chi phí chỉ từ $0.42/MTok cho DeepSeek V3.2, bạn có thể:

import requests
import json

class StrategyOptimizer:
    """
    Sử dụng AI để phân tích và đề xuất cải thiện chiến lược
    """
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.holysheep.ai/v1"
    
    def analyze_backtest_results(self, results: dict, orderbook_data: pd.DataFrame) -> dict:
        """
        Gửi kết quả backtest lên AI để phân tích
        """
        # Chuẩn bị prompt cho AI
        analysis_prompt = f"""
        Phân tích chiến lược market making với kết quả sau:
        
        Kết quả định lượng:
        - Tổng lợi nhuận: {results['total_return_pct']:.2f}%
        - Sharpe Ratio: {results['sharpe_ratio']:.2f}
        - Max Drawdown: {results['max_drawdown_pct']:.2f}%
        - Số lệnh fill: {results['total_trades']}
        
        Đặc điểm thị trường (từ orderbook):
        - Volatility trung bình: {orderbook_data['volatility'].mean() if 'volatility' in orderbook_data else 'N/A'}
        - Volume trung bình: {orderbook_data.get('volume', pd.Series([0])).mean():.2f}
        - Bid-Ask spread trung bình: {((orderbook_data['best_ask'] - orderbook_data['best_bid']) / orderbook_data['best_bid'] * 10000).mean():.2f} bps
        
        Hãy đề xuất:
        1. Các điều chỉnh tham số (spread, skew factor)
        2. Chiến lược quản lý rủi ro
        3. Cải thiện inventory management
        4. Thời điểm tốt để tăng/giảm position size
        """
        
        # Gọi DeepSeek V3.2 để phân tích - chi phí chỉ $0.42/MTok
        response = requests.post(
            f"{self.base_url}/chat/completions",
            headers={
                "Authorization": f"Bearer {self.api_key}",
                "Content-Type": "application/json"
            },
            json={
                "model": "deepseek-v3.2",
                "messages": [
                    {"role": "system", "content": "Bạn là chuyên gia market making và trading strategy."},
                    {"role": "user", "content": analysis_prompt}
                ],
                "temperature": 0.7,
                "max_tokens": 1000
            }
        )
        
        if response.status_code == 200:
            result = response.json()
            return {
                'analysis': result['choices'][0]['message']['content'],
                'model_used': 'deepseek-v3.2',
                'cost_estimate': result.get('usage', {}).get('total_tokens', 0) * 0.42 / 1000
            }
        else:
            raise Exception(f"AI Analysis failed: {response.text}")
    
    def optimize_params(self, historical_data: pd.DataFrame, 
                       target_sharpe: float = 2.0) -> dict:
        """
        Tối ưu hóa tham số chiến lược bằng grid search + AI
        
        Returns:
            Dictionary với tham số tối ưu
        """
        # Grid search để tìm sweet spot
        best_sharpe = -999
        best_params = None
        
        spread_range = [5, 10, 15, 20, 30]  # bps
        skew_range = [0.2, 0.4, 0.6, 0.8, 1.0]
        max_pos_range = [0.3, 0.5, 0.8, 1.0]
        
        results_grid = []
        
        for spread in spread_range:
            for skew in skew_range:
                for max_pos in max_pos_range:
                    params = MarketMakingParams(
                        spread_bps=spread,
                        skew_factor=skew,
                        max_position=max_pos
                    )
                    
                    backtester = MarketMakingBacktester(params)
                    results = backtester.calculate_pnl(historical_data)
                    
                    results_grid.append({
                        'spread_bps': spread,
                        'skew_factor': skew,
                        'max_position': max_pos,
                        'sharpe': results.get('sharpe_ratio', 0),
                        'return': results.get('total_return_pct', 0),
                        'max_dd': results.get('max_drawdown_pct', 0)
                    })
                    
                    if results.get('sharpe_ratio', -999) > best_sharpe:
                        best_sharpe = results['sharpe_ratio']
                        best_params = params
        
        return {
            'best_params': best_params,
            'best_sharpe': best_sharpe,
            'all_results': pd.DataFrame(results_grid),
            'optimization_time': len(results_grid)
        }

Sử dụng AI Analysis

optimizer = StrategyOptimizer(api_key="YOUR_HOLYSHEEP_API_KEY")

Phân tích chiến lược với AI

print("🤖 Đang phân tích với AI (DeepSeek V3.2 - $0.42/MTok)...") ai_analysis = optimizer.analyze_backtest_results(results, df_orderbook) print("\n" + "=" * 50) print("📝 PHÂN TÍCH TỪ AI") print("=" * 50) print(ai_analysis['analysis']) print(f"\n💰 Chi phí AI: ~${ai_analysis['cost_estimate']:.4f}")

Đánh Giá Chiến Lược Và Tối Ưu Hóa

import matplotlib.pyplot as plt
import matplotlib.dates as mdates

def visualize_backtest_results(results: dict, df_orderbook: pd.DataFrame):
    """
    Trực quan hóa kết quả backtest
    """
    fig, axes = plt.subplots(3, 1, figsize=(14, 12))
    
    df_trades = results['df_history']
    
    # Plot 1: Equity Curve
    ax1 = axes[0]
    ax1.plot(df_trades['timestamp'], df_trades['total_value'], 
             label='Total Value', color='blue')
    ax1.fill_between(df_trades['timestamp'], df_trades['total_value'], 
                     alpha=0.3)
    ax1.set_title('📈 Equity Curve - Market Making Strategy', fontsize=14)
    ax1.set_ylabel('Portfolio Value (USD)')
    ax1.legend()
    ax1.grid(True, alpha=0.3)
    ax1.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d'))
    
    # Plot 2: Position Over Time
    ax2 = axes[1]
    ax2.plot(df_trades['timestamp'], df_trades['position'], 
             label='Position', color='green')
    ax2.axhline(y=0, color='black', linestyle='--', alpha=0.5)
    ax2.set_title('📊 Position Over Time', fontsize=14)
    ax2.set_ylabel('Position (BTC)')
    ax2.legend()
    ax2.grid(True, alpha=0.3)
    ax2.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d'))
    
    # Plot 3: Drawdown
    ax3 = axes[2]
    cummax = df_trades['total_value'].cummax()
    drawdown = (cummax - df_trades['total_value']) / cummax * 100
    ax3.fill_between(df_trades['timestamp'], drawdown, 
                     color='red', alpha=0.5)
    ax3.set_title('📉 Drawdown Analysis', fontsize=14)
    ax3.set_ylabel('Drawdown (%)')
    ax3.set_xlabel('Time')
    ax3.grid(True, alpha=0.3)
    ax3.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d'))
    
    plt.tight_layout()
    plt.savefig('backtest_results.png', dpi=150)
    plt.show()
    
    # In báo cáo tổng hợp
    print("\n" + "=" * 60)
    print("📊 BÁO CÁO BACKTEST TỔNG HỢP")
    print("=" * 60)
    print(f"📅 Thời gian backtest: {df_trades['timestamp'].min()} -> {df_trades['timestamp'].max()}")
    print(f"💰 Lợi nhuận: {results['total_return_pct']:.2f}%")
    print(f"📈 Sharpe Ratio: {results['sharpe_ratio']:.2f}")
    print(f"📉 Max Drawdown: {results['max_drawdown_pct']:.2f}%")
    print(f"🔢 Tổng giao dịch: {results['total_trades']}")
    print(f"💵 Vị thế cuối: {results['final_position']:.4f} BTC")
    print(f"💵 Cash cuối: ${results['final_cash']:.2f}")
    print("=" *