Trong thế giới đầu tư định lượng, việc xây dựng mô hình đa yếu tố (multi-factor model) là chìa khóa để tạo ra lợi nhuận bền vững. Bài viết này sẽ hướng dẫn bạn cách sử dụng Tardis API để thu thập dữ liệu chất lượng cao, từ đó xây dựng bộ yếu tố (factors) bao gồm: momentum (động lực giá), volatility (biến động), và liquidity (thanh khoản) cho danh mục đầu tư cryptocurrency.

Tại sao cần Multi-Factor Model trong Crypto?

Thị trường tiền mã hóa nổi tiếng với sự biến động mạnh và tính thanh khoản không đồng đều. Một chiến lược đầu tư đơn thuần dựa trên buy-and-hold thường gặp rủi ro cao. Multi-factor model giúp:

Tardis API - Nguồn Dữ Liệu Đáng Tin Cậy

Trước khi đi vào chi tiết kỹ thuật, hãy xem xét chi phí xử lý dữ liệu với các API AI hàng đầu năm 2026:

ModelGiá (USD/MTok)10M Tokens/thángPhù hợp cho
GPT-4.1$8.00$80Phân tích phức tạp
Claude Sonnet 4.5$15.00$150Reasoning dài
Gemini 2.5 Flash$2.50$25Xử lý nhanh
DeepSeek V3.2$0.42$4.20Xử lý dữ liệu lớn

Với chi phí chỉ $0.42/MTok, DeepSeek V3.2 trên HolySheep AI là lựa chọn tối ưu cho việc xử lý hàng triệu dữ liệu tick trong multi-factor model. Tiết kiệm đến 85%+ so với các provider khác.

Kiến Trúc Hệ Thống Factor Investing


┌─────────────────────────────────────────────────────────────┐
│                   MULTI-FACTOR MODEL ARCHITECTURE           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐   │
│  │   TARDIS     │───▶│  FACTOR     │───▶│  PORTFOLIO   │   │
│  │   API        │    │  COMPUTE    │    │  OPTIMIZER   │   │
│  │              │    │             │    │              │   │
│  │ OHLCV Data   │    │ Momentum    │    │ Risk Parity  │   │
│  │ Orderbook    │    │ Volatility  │    │ Mean-Var     │   │
│  │ Trades       │    │ Liquidity   │    │ Black-Litter │   │
│  └──────────────┘    └──────────────┘    └──────────────┘   │
│         │                   │                   │          │
│         ▼                   ▼                   ▼          │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐   │
│  │  HolySheep   │    │  HolySheep   │    │  HolySheep   │   │
│  │  DeepSeek    │    │  DeepSeek    │    │  DeepSeek    │   │
│  │  $0.42/MTok  │    │  $0.42/MTok  │    │  $0.42/MTok  │   │
│  └──────────────┘    └──────────────┘    └──────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Thu Thập Dữ Liệu Từ Tardis API

Đầu tiên, chúng ta cần thu thập dữ liệu OHLCV từ Tardis cho việc tính toán factors. Dưới đây là code Python hoàn chỉnh:


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

class TardisDataFetcher:
    """Thu thập dữ liệu từ Tardis API cho factor computation"""
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.tardis.dev/v1"
    
    def get_ohlcv_data(
        self, 
        exchange: str, 
        symbol: str, 
        start_date: str, 
        end_date: str
    ) -> pd.DataFrame:
        """
        Lấy dữ liệu OHLCV từ Tardis
        - exchange: sàn giao dịch (binance, okx, bybit...)
        - symbol: cặp tiền (BTCUSDT, ETHUSDT...)
        """
        url = f"{self.base_url}/historical/ohlcv"
        
        params = {
            "exchange": exchange,
            "symbol": symbol,
            "startDate": start_date,  # "2025-01-01"
            "endDate": end_date,      # "2025-06-01"
            "interval": "1h"          # 1h, 4h, 1d
        }
        
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        response = requests.get(url, params=params, headers=headers)
        
        if response.status_code == 200:
            data = response.json()
            df = pd.DataFrame(data)
            df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
            return df
        else:
            raise Exception(f"Tardis API Error: {response.status_code}")
    
    def get_orderbook_snapshot(
        self, 
        exchange: str, 
        symbol: str, 
        date: str
    ) -> dict:
        """Lấy snapshot orderbook để tính liquidity factor"""
        url = f"{self.base_url}/historical/orderbooks"
        
        params = {
            "exchange": exchange,
            "symbol": symbol,
            "date": date  # "2025-03-15"
        }
        
        headers = {
            "Authorization": f"Bearer {self.api_key}"
        }
        
        response = requests.get(url, params=params, headers=headers)
        return response.json()

Ví dụ sử dụng

fetcher = TardisDataFetcher(api_key="YOUR_TARDIS_API_KEY")

Lấy dữ liệu BTCUSDT từ Binance

btc_data = fetcher.get_ohlcv_data( exchange="binance", symbol="BTCUSDT", start_date="2025-01-01", end_date="2025-06-01" ) print(f"Đã tải {len(btc_data)} records cho BTCUSDT") print(btc_data.head())

Tính Toán Momentum Factor

Momentum factor đo lường xu hướng giá trong quá khứ. Chúng ta sẽ sử dụng nhiều khung thời gian để tạo ra robust momentum signal:


import numpy as np
from typing import List

class MomentumFactor:
    """
    Tính toán Momentum Factor với nhiều chiến lược:
    - Return-based momentum (ROC)
    - Risk-adjusted momentum (Sharpe-based)
    - Time-series momentum
    """
    
    def __init__(self, returns: pd.Series):
        self.returns = returns
    
    def simple_roc(self, period: int = 20) -> pd.Series:
        """
        Rate of Change - momentum cơ bản
        ROC = (Price_t - Price_{t-n}) / Price_{t-n}
        """
        return self.returns.pct_change(periods=period)
    
    def risk_adjusted_momentum(
        self, 
        lookback: int = 20, 
        annualize: bool = True
    ) -> pd.Series:
        """
        Risk-adjusted momentum = Mean Return / Std Dev
        Sharpe-like momentum calculation
        """
        rolling_mean = self.returns.rolling(window=lookback).mean()
        rolling_std = self.returns.rolling(window=lookback).std()
        
        momentum = rolling_mean / rolling_std
        
        if annualize:
            momentum = momentum * np.sqrt(365)  # Annualize cho daily data
        
        return momentum
    
    def ts_momentum(
        self, 
        formation: int = 60, 
        holding: int = 20
    ) -> pd.Series:
        """
        Time-series momentum:
        Long positions when past returns > 0
        Signal = sign of cumulative return over formation period
        """
        cum_returns = (1 + self.returns).rolling(window=formation).apply(
            lambda x: x.prod() - 1, raw=False
        )
        return np.sign(cum_returns)
    
    def multi_period_momentum(self) -> pd.DataFrame:
        """
        Kết hợp momentum từ nhiều khung thời gian
        5D, 10D, 20D, 60D
        """
        periods = [5, 10, 20, 60]
        result = pd.DataFrame()
        
        for p in periods:
            result[f'momentum_{p}d'] = self.simple_roc(period=p)
        
        # Equal-weight combination
        result['combined_momentum'] = result.mean(axis=1)
        
        return result

def compute_momentum_for_portfolio(
    prices_df: pd.DataFrame,
    lookback_periods: List[int] = [5, 10, 20, 60]
) -> pd.DataFrame:
    """
    Tính momentum cho toàn bộ danh mục
    
    prices_df: DataFrame với columns = symbols, rows = dates
    """
    returns = prices_df.pct_change()
    
    momentum_signals = {}
    
    for symbol in prices_df.columns:
        mom_factor = MomentumFactor(returns[symbol])
        
        for period in lookback_periods:
            momentum_signals[f'{symbol}_mom_{period}d'] = mom_factor.simple_roc(period)
    
    return pd.DataFrame(momentum_signals)

Ví dụ sử dụng với HolySheep AI để phân tích

def analyze_momentum_with_holysheep(momentum_data: pd.DataFrame): """ Sử dụng HolySheep AI để phân tích momentum signals Chi phí cực thấp với DeepSeek V3.2: $0.42/MTok """ prompt = f""" Phân tích momentum data sau đây và đưa ra top 5 cryptocurrencies có momentum signal mạnh nhất: {momentum_data.tail(10).to_string()} Yêu cầu: 1. Liệt kê top 5 coins theo momentum score 2. Đề xuất chiến lược long/short dựa trên momentum 3. Cảnh báo về potential reversal signals """ # Sử dụng HolySheep API - Chi phí chỉ $0.42/MTok response = call_holysheep_api(prompt, model="deepseek-v3.2") return response

Tính Toán Volatility Factor

Volatility factor đo lường mức độ biến động giá, rất quan trọng trong risk management:


class VolatilityFactor:
    """
    Tính toán Volatility Factor với nhiều phương pháp:
    - Historical Volatility (HV)
    - Parkinson Volatility
    - GARCH-based Volatility
    - Implied Volatility approximation
    """
    
    def __init__(self, ohlcv_df: pd.DataFrame):
        self.df = ohlcv_df
        self.high = ohlcv_df['high']
        self.low = ohlcv_df['low']
        self.close = ohlcv_df['close']
        self.open = ohlcv_df['open']
    
    def historical_volatility(
        self, 
        window: int = 20, 
        annualize: bool = True
    ) -> pd.Series:
        """
        Historical Volatility = Std Dev of returns
        HV = σ * √(252) cho daily data
        """
        log_returns = np.log(self.close / self.close.shift(1))
        hv = log_returns.rolling(window=window).std()
        
        if annualize:
            hv = hv * np.sqrt(365)  # Annualize
        
        return hv
    
    def parkinson_volatility(self, window: int = 20) -> pd.Series:
        """
        Parkinson Volatility - dùng High-Low range
        PVol = √(1/(4*ln(2)) * Σ(ln(H/L))²)
        Hiệu quả hơn với less smoothing needed
        """
        log_hl = np.log(self.high / self.low)
        pv = np.sqrt(
            (1 / (4 * np.log(2))) * 
            log_hl.pow(2).rolling(window=window).mean()
        )
        return pv * np.sqrt(365)  # Annualize
    
    def rogers_satchell_volatility(self, window: int = 20) -> pd.Series:
        """
        Rogers-Satchell Volatility - dùng O/H/L/C
        """
        log_ho = np.log(self.high / self.open)
        log_hc = np.log(self.high / self.close)
        log_lo = np.log(self.low / self.open)
        log_lc = np.log(self.low / self.close)
        
        rs = log_ho * log_hc + log_lo * log_lc
        rv = np.sqrt(rs.rolling(window=window).mean())
        
        return rv * np.sqrt(365)
    
    def ewma_volatility(
        self, 
        halflife: int = 20,
        annualize: bool = True
    ) -> pd.Series:
        """
        Exponentially Weighted Moving Average Volatility
        Lambda = 0.94 cho RiskMetrics standard
        """
        log_returns = np.log(self.close / self.close.shift(1))
        
        # EWMA với halflife
        ewma_vol = log_returns.ewm(halflife=halflife).std()
        
        if annualize:
            ewma_vol = ewma_vol * np.sqrt(365)
        
        return ewma_vol
    
    def garch_volatility(
        self, 
        p: int = 1, 
        q: int = 1,
        n_periods: int = 252
    ) -> pd.Series:
        """
        GARCH(1,1) Volatility Model
        σ²_t = ω + α*ε²_{t-1} + β*σ²_{t-1}
        """
        from arch import arch_model
        
        log_returns = np.log(self.close / self.close.shift(1)).dropna() * 100
        
        model = arch_model(
            log_returns, 
            vol='Garch', 
            p=p, 
            q=q,
            rescale=False
        )
        result = model.fit(disp='off')
        
        # Forecast future volatility
        forecasts = result.forecast(horizon=n_periods)
        garch_vol = np.sqrt(forecasts.variance.values[-1, :].mean()) / 100
        
        return pd.Series(
            garch_vol, 
            index=[self.close.index[-1] + pd.Timedelta(days=i) for i in range(n_periods)]
        )
    
    def volatility_regime(self, window: int = 60) -> pd.Series:
        """
        Xác định Volatility Regime:
        - Low volatility regime (Z-score < -1)
        - Normal volatility (Z-score -1 to 1)
        - High volatility regime (Z-score > 1)
        """
        hv = self.historical_volatility(window=window)
        hv_zscore = (hv - hv.rolling(window).mean()) / hv.rolling(window).std()
        
        regime = pd.cut(
            hv_zscore, 
            bins=[-np.inf, -1, 1, np.inf],
            labels=['Low', 'Normal', 'High']
        )
        
        return regime

Sử dụng HolySheep AI để phân tích volatility regime

def get_volatility_regime_analysis( volatility_df: pd.DataFrame, current_vol: float ): """ Sử dụng HolySheep DeepSeek V3.2 ($0.42/MTok) để phân tích volatility regime """ prompt = f""" Phân tích volatility data cho risk management: Current Volatility: {current_vol:.4f} Historical Statistics: {volatility_df.describe().to_string()} Đưa ra: 1. Current regime classification 2. Risk-adjusted position sizing recommendation 3. hedging strategy nếu volatility cao """ # HolySheep AI - Chi phí tối ưu response = call_holysheep_api(prompt, model="deepseek-v3.2") return response

Tính Toán Liquidity Factor

Liquidity factor đo lường khả năng giao dịch mà không ảnh hưởng đến giá:


class LiquidityFactor:
    """
    Tính toán Liquidity Factor từ dữ liệu orderbook và trades:
    - Amihud Illiquidity Ratio
    - Order Flow Imbalance
    - Bid-Ask Spread
    - Volume Profile
    """
    
    def __init__(self, trades_df: pd.DataFrame, orderbook_df: dict = None):
        self.trades = trades_df
        self.orderbook = orderbook_df
    
    def amihud_illiquidity(
        self, 
        window: int = 20,
        annualize: bool = True
    ) -> pd.Series:
        """
        Amihud Illiquidity Ratio
        ILLIQ = (1/D) * Σ(|Ret_d| / Vol_d)
        
        Đo lường impact của volume lên giá
        Giá trị cao = Low liquidity (khó giao dịch mà không ảnh hưởng giá)
        """
        daily_returns = self.trades.groupby(
            pd.Grouper(key='timestamp', freq='D')
        )['price'].last().pct_change()
        
        daily_volume = self.trades.groupby(
            pd.Grouper(key='timestamp', freq='D')
        )['volume'].sum()
        
        illiq = (daily_returns.abs() / daily_volume).rolling(window=window).mean()
        
        if annualize:
            illiq = illiq * 252
        
        return illiq
    
    def order_flow_imbalance(
        self,
        orderbook_snapshot: dict
    ) -> float:
        """
        Order Flow Imbalance = (BidVolume - AskVolume) / (BidVolume + AskVolume)
        OFI > 0: Buying pressure
        OFI < 0: Selling pressure
        """
        bids = orderbook_snapshot.get('bids', [])
        asks = orderbook_snapshot.get('asks', [])
        
        bid_volume = sum([float(b[1]) for b in bids[:10]])
        ask_volume = sum([float(a[1]) for a in asks[:10]])
        
        ofi = (bid_volume - ask_volume) / (bid_volume + ask_volume)
        return ofi
    
    def bid_ask_spread(
        self,
        orderbook_snapshot: dict
    ) -> float:
        """
        Bid-Ask Spread = (Ask - Bid) / ((Ask + Bid) / 2)
        Spread càng nhỏ = Liquidity càng cao
        """
        bids = orderbook_snapshot.get('bids', [])
        asks = orderbook_snapshot.get('asks', [])
        
        best_bid = float(bids[0][0]) if bids else 0
        best_ask = float(asks[0][0]) if asks else 0
        
        if best_bid > 0 and best_ask > 0:
            spread = (best_ask - best_bid) / ((best_ask + best_bid) / 2)
        else:
            spread = np.nan
        
        return spread
    
    def volume_imbalance(
        self,
        window: int = 60
    ) -> pd.Series:
        """
        Volume Imbalance = (Buy Volume - Sell Volume) / Total Volume
        Dựa trên trade direction classification
        """
        trades = self.trades.copy()
        trades['minute'] = trades['timestamp'].dt.floor('T')
        
        # Classify trades as buy or sell dựa trên price movement
        trades['is_buy'] = trades['price'] >= trades['price'].shift(1)
        
        minute_volumes = trades.groupby('minute').agg({
            'volume': 'sum',
            'is_buy': lambda x: (x * trades.loc[x.index, 'volume']).sum()
        })
        
        minute_volumes.columns = ['total_volume', 'buy_volume']
        minute_volumes['sell_volume'] = (
            minute_volumes['total_volume'] - minute_volumes['buy_volume']
        )
        
        vi = (
            minute_volumes['buy_volume'] - minute_volumes['sell_volume']
        ) / minute_volumes['total_volume']
        
        return vi.rolling(window=window).mean()
    
    def liquidity_score(self) -> pd.DataFrame:
        """
        Composite Liquidity Score từ nhiều metrics
        """
        scores = pd.DataFrame()
        
        scores['amihud'] = 1 / (1 + self.amihud_illiquidity())
        scores['vol_imbalance'] = self.volume_imbalance()
        
        # Normalize
        for col in scores.columns:
            scores[col] = (scores[col] - scores[col].mean()) / scores[col].std()
        
        scores['composite_liquidity'] = scores.mean(axis=1)
        
        return scores

def calculate_liquidity_for_portfolio(
    tardis_fetcher: object,
    symbols: List[str],
    exchange: str = "binance"
) -> pd.DataFrame:
    """
    Tính liquidity factor cho toàn bộ danh mục
    """
    liquidity_data = {}
    
    for symbol in symbols:
        # Lấy trades data
        trades = tardis_fetcher.get_trades(exchange, symbol)
        
        # Tính liquidity
        liq_factor = LiquidityFactor(trades)
        liquidity_data[symbol] = liq_factor.amihud_illiquidity()
    
    return pd.DataFrame(liquidity_data)

Tích Hợp HolySheep AI Cho Phân Tích Toàn Diện

Để tận dụng chi phí thấp nhất ($0.42/MTok) với độ trễ dưới 50ms, HolySheep AI là lựa chọn tối ưu cho việc xử lý multi-factor model:


import requests
import json
from typing import Optional, Dict, Any

class HolySheepAIClient:
    """
    HolySheep AI Client - Chi phí thấp nhất: $0.42/MTok
    Hỗ trợ: DeepSeek V3.2, GPT-4.1, Claude Sonnet 4.5, Gemini 2.5 Flash
    
    Tính năng:
    - Độ trễ < 50ms
    - Thanh toán: WeChat/Alipay
    - Tỷ giá: ¥1 = $1 (tiết kiệm 85%+)
    """
    
    BASE_URL = "https://api.holysheep.ai/v1"
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
    
    def analyze_multi_factor(
        self,
        momentum_data: pd.DataFrame,
        volatility_data: pd.DataFrame,
        liquidity_data: pd.DataFrame
    ) -> Dict[str, Any]:
        """
        Sử dụng DeepSeek V3.2 ($0.42/MTok) để phân tích đa yếu tố
        """
        prompt = self._build_factor_prompt(
            momentum_data, volatility_data, liquidity_data
        )
        
        response = self._call_model(
            model="deepseek-v3.2",
            messages=[{"role": "user", "content": prompt}]
        )
        
        return response
    
    def generate_trading_signals(
        self,
        factor_scores: pd.DataFrame,
        top_n: int = 5
    ) -> Dict[str, Any]:
        """
        Tạo trading signals từ factor scores
        Sử dụng DeepSeek V3.2 cho cost-effectiveness
        """
        prompt = f"""
        Dựa trên factor scores sau đây, hãy đề xuất top {top_n} coins để long:
        
        {factor_scores.to_string()}
        
        Yêu cầu:
        1. Rank theo composite factor score
        2. Đề xuất position sizing
        3. Stop-loss và take-profit levels
        4. Risk-reward ratio
        """
        
        response = self._call_model(
            model="deepseek-v3.2",
            messages=[{"role": "user", "content": prompt}]
        )
        
        return response
    
    def backtest_analysis(
        self,
        trades_df: pd.DataFrame,
        factors_df: pd.DataFrame
    ) -> Dict[str, Any]:
        """
        Phân tích backtest với HolySheep AI
        Chi phí cho 10M tokens: chỉ $4.20 với DeepSeek V3.2
        """
        prompt = f"""
        Phân tích backtest results cho multi-factor strategy:
        
        Trades: {trades_df.tail(20).to_string()}
        Factor Correlations: {factors_df.corr().to_string()}
        
        Đưa ra:
        1. Performance metrics (Sharpe, Sortino, Max Drawdown)
        2. Factor attribution
        3. Recommendations để cải thiện
        """
        
        response = self._call_model(
            model="deepseek-v3.2",
            messages=[{"role": "user", "content": prompt}],
            temperature=0.3  # Lower temperature for quantitative analysis
        )
        
        return response
    
    def _call_model(
        self,
        model: str,
        messages: list,
        temperature: float = 0.7,
        max_tokens: int = 2000
    ) -> Dict[str, Any]:
        """
        Gọi HolySheep AI API
        """
        payload = {
            "model": model,
            "messages": messages,
            "temperature": temperature,
            "max_tokens": max_tokens
        }
        
        response = requests.post(
            f"{self.BASE_URL}/chat/completions",
            headers=self.headers,
            json=payload
        )
        
        if response.status_code == 200:
            return response.json()
        else:
            raise Exception(f"HolySheep API Error: {response.status_code}")
    
    def _build_factor_prompt(
        self,
        momentum: pd.DataFrame,
        volatility: pd.DataFrame,
        liquidity: pd.DataFrame
    ) -> str:
        """Build prompt cho factor analysis"""
        return f"""
        Phân tích Multi-Factor Model cho Cryptocurrency Portfolio:
        
        === MOMENTUM DATA ===
        {momentum.tail(5).to_string()}
        
        === VOLATILITY DATA ===
        {volatility.tail(5).to_string()}
        
        === LIQUIDITY DATA ===  
        {liquidity.tail(5).to_string()}
        
        Yêu cầu phân tích:
        1. Tương quan giữa các factors
        2. Top 5 coins với combined factor score cao nhất
        3. Risk-adjusted recommendations
        4. Portfolio allocation suggestions
        """


=== SỬ DỤNG MẪU ===

Khởi tạo client với API key từ HolySheep

holysheep = HolySheepAIClient(api_key="YOUR_HOLYSHEEP_API_KEY")

Phân tích đa yếu tố với chi phí cực thấp

factor_analysis = holysheep.analyze_multi_factor( momentum_data=momentum_df, volatility_data=volatility_df, liquidity_data=liquidity_df ) print(f"Chi phí sử dụng: ${factor_analysis.get('usage', {}).get('cost_usd', 0):.4f}") print(f"Tokens used: {factor_analysis.get('usage', {}).get('total_tokens', 0)}")

Xây Dựng Combined Factor Model


class MultiFactorModel:
    """
    Kết hợp Momentum, Volatility, Liquidity factors
    thành Combined Factor Score
    """
    
    def __init__(
        self,
        momentum_df: pd.DataFrame,
        volatility_df: pd.DataFrame,
        liquidity_df: pd.DataFrame
    ):
        self.momentum = momentum_df
        self.volatility = volatility_df
        self.liquidity = liquidity_df
    
    def normalize_factors(
        self,
        method: str = 'zscore'
    ) -> pd.DataFrame:
        """
        Normalize factors về cùng scale
        - zscore: (x - mean) / std
        - minmax: (x - min) / (max - min)
        - rank: percentile rank
        """
        normalized = pd.DataFrame()
        
        for name, df in {
            'momentum': self.momentum,
            'volatility': self.volatility,
            'liquidity': self.liquidity
        }.items():
            if method == 'zscore':
                normalized[name] = (df - df.mean()) / df.std()
            elif method == 'minmax':
                normalized[name] = (df - df.min()) / (df.max() - df.min())
            elif method == 'rank':
                normalized[name] = df.rank(pct=True)
        
        return normalized
    
    def compute_combined_score(
        self,
        weights: Dict[str, float] = None,
        long_only: bool = True
    ) -> pd.DataFrame:
        """
        Tính Combined Factor Score
        
        weights: dict với weight cho từng factor
        long_only: True = chỉ long, False = long/short
        
        Default weights:
        - Momentum: 0.4 (40%)
        - Volatility: 0.3 (30%) - Low volatility tốt
        - Liquidity: 0.3 (30%) - High liquidity tốt
        """
        if weights is None:
            weights = {
                'momentum': 0.4,
                'volatility': -0.3,  # Negative = lower vol is better
                'liquidity': 0.3
            }
        
        # Normalize
        norm_factors = self.normalize_factors()
        
        # Compute weighted score
        combined = pd.DataFrame()
        
        for symbol in self.momentum.columns:
            score = 0
            for factor, weight in weights.items():
                if factor in norm_factors.columns:
                    score += norm_factors.loc[norm_factors.index[-1], factor] * weight
            
            combined[symbol] = [score]
        
        combined.index = [self.momentum.index[-1]]
        
        return combined.T.sort_values(by=combined.columns[0], ascending=False)
    
    def factor_returns(
        self,
        prices: pd.DataFrame,
        lookback: int = 20
    ) -> pd.DataFrame:
        """
        Tính returns của từng factor portfolio
        """