Ngày 30 tháng 5 năm 2026, đội ngũ kỹ thuật của chúng tôi gặp một lỗi nghiêm trọng khi đang xây dựng hệ thống factor engineering cho chiến lược long-short trên Bybit USDT-M perpetual futures. Kịch bản lỗi cụ thể như sau:

ConnectionError: HTTPSConnectionPool(host='api.tardis.dev', port=443): 
Max retries exceeded with url: /v1/coins/okx/perpetual-futures?symbol=BTC-USDT-SWAP
(Caused by NewConnectionError(<urllib3.connection.HTTPSConnection object at 0x7f...>:
Failed to establish a new connection: [Errno 110] Connection timed out))

API Rate Limit Exceeded: 429 Too Many Requests
Retry-After: 60 seconds

Sau 3 ngày debug và tối ưu hóa, chúng tôi đã tìm ra giải pháp hoàn chỉnh sử dụng HolySheep AI làm gateway trung tâm để thu thập và xử lý dữ liệu OI (Open Interest), holdings, và long-short ratio từ cả OKX và Bybit. Bài viết này sẽ chia sẻ toàn bộ quy trình, code mẫu, và những bài học xương máu từ thực chiến.

Tại Sao Cần Tardis + Bybit Data Cho Factor Engineering?

Trong trading system hiện đại, Open Interest (OI) và long-short position ratio là hai chỉ báo cực kỳ quan trọng để đo lường "smart money flow". Khi kết hợp dữ liệu từ nhiều sàn như OKX và Bybit, traders có thể:

Tardis cung cấp API chuẩn hóa cho dữ liệu perpetual futures từ nhiều sàn, trong khi HolySheep AI đóng vai trò như một orchestration layer mạnh mẽ để xử lý, transform và cache data với độ trễ dưới 50ms.

Kiến Trúc Hệ Thống Hoàn Chỉnh

Kiến trúc mà chúng tôi đã triển khai bao gồm 4 thành phần chính:

Cài Đặt Môi Trường Và Dependencies

# requirements.txt

pip install -r requirements.txt

pandas>=2.0.0 numpy>=1.24.0 httpx>=0.25.0 asyncpg>=0.29.0 redis>=5.0.0 python-dotenv>=1.0.0 ta>=0.10.0 sqlalchemy>=2.0.0

Kết nối HolySheep

openai>=1.12.0
# config.py
import os
from dotenv import load_dotenv

load_dotenv()

=== HOLYSHEEP CONFIG (BẮT BUỘC) ===

HOLYSHEEP_API_KEY = os.getenv("HOLYSHEEP_API_KEY") HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1" # KHÔNG dùng api.openai.com

=== TARDIS CONFIG ===

TARDIS_API_KEY = os.getenv("TARDIS_API_KEY") TARDIS_BASE_URL = "https://api.tardis.dev/v1"

=== BYBIT CONFIG ===

BYBIT_PUBLIC_URL = "https://api.bybit.com/v5"

=== DATABASE CONFIG ===

POSTGRES_URL = os.getenv("POSTGRES_URL", "postgresql://user:pass@localhost:5432/crypto") REDIS_URL = os.getenv("REDIS_URL", "redis://localhost:6379/0")

=== CACHE TTL ===

CACHE_TTL_OKX_OI = 30 # giây CACHE_TTL_BYBIT_POSITIONS = 60 # giây

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

# tardis_client.py
import httpx
import asyncio
from typing import Dict, List, Optional
from datetime import datetime
import pandas as pd
import json

class TardisOKXClient:
    """
    Client kết nối Tardis API để lấy dữ liệu OKX perpetual futures.
    Lưu ý: Tardis cần API key có quota, nếu hết rate limit sẽ trả 429.
    """
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.tardis.dev/v1"
        self.timeout = httpx.Timeout(30.0, connect=10.0)
        self._session: Optional[httpx.AsyncClient] = None
    
    async def __aenter__(self):
        self._session = httpx.AsyncClient(
            timeout=self.timeout,
            headers={
                "Authorization": f"Bearer {self.api_key}",
                "Content-Type": "application/json"
            }
        )
        return self
    
    async def __aexit__(self, *args):
        if self._session:
            await self._session.aclose()
    
    async def get_perpetual_oi(
        self, 
        symbol: str = "BTC-USDT-SWAP",
        start_date: str = None,
        end_date: str = None
    ) -> pd.DataFrame:
        """
        Lấy Open Interest history cho perpetual futures.
        
        Args:
            symbol: VD 'BTC-USDT-SWAP', 'ETH-USDT-SWAP'
            start_date: ISO format '2026-05-01'
            end_date: ISO format '2026-05-30'
        
        Returns:
            DataFrame với columns: timestamp, open_interest_usd, volume_24h
        """
        # QUAN TRỌNG: Tardis format symbol khác Bybit
        # OKX: BTC-USDT-SWAP
        # Bybit: BTCUSDT
        params = {
            "symbol": symbol,
            "resolution": "1",  # 1 phút
            "from": start_date or "2026-05-01T00:00:00Z",
            "to": end_date or datetime.utcnow().isoformat() + "Z"
        }
        
        try:
            response = await self._session.get(
                f"{self.base_url}/coins/okx/perpetual-futures",
                params=params
            )
            
            if response.status_code == 401:
                raise ConnectionError("Tardis API: 401 Unauthorized - Kiểm tra API key")
            
            if response.status_code == 429:
                retry_after = response.headers.get("Retry-After", "60")
                raise ConnectionError(f"Tardis Rate Limit: Chờ {retry_after} giây")
            
            response.raise_for_status()
            data = response.json()
            
            # Transform sang DataFrame
            df = pd.DataFrame(data.get("data", []))
            if not df.empty:
                df["timestamp"] = pd.to_datetime(df["t"], unit="s")
                df = df.rename(columns={
                    "oi": "open_interest_usd",
                    "volume": "volume_24h"
                })
            
            return df
            
        except httpx.ConnectTimeout:
            # Lỗi timeout thường gặp - Tardis server quá tải
            raise ConnectionError(
                "Tardis timeout: Kiểm tra network hoặc dùng HolySheep cache"
            )
    
    async def get_funding_rate(self, symbol: str) -> Dict:
        """Lấy funding rate history"""
        params = {"symbol": symbol}
        response = await self._session.get(
            f"{self.base_url}/coins/okx/funding-rate",
            params=params
        )
        return response.json()


=== SỬ DỤNG VỚI HOLYSHEEP ===

async def fetch_with_fallback(symbol: str) -> pd.DataFrame: """ Strategy: Thử Tardis trước, nếu lỗi thì dùng HolySheep cache """ from holyseep_client import HolySheepClient holyseep = HolySheepClient() try: async with TardisOKXClient(TARDIS_API_KEY) as client: df = await client.get_perpetual_oi(symbol) # Cache kết quả vào HolySheep để tái sử dụng await holyseep.cache_oi_data(symbol, df) return df except (ConnectionError, httpx.HTTPError) as e: print(f"Tardis lỗi: {e}, đang fallback sang HolySheep cache...") return await holyseep.get_cached_oi(symbol)

Module Thu Thập Dữ Liệu Bybit USDT-M

# bybit_client.py
import httpx
import asyncio
from typing import Dict, List
import pandas as pd
from datetime import datetime

class BybitUSDTMClient:
    """
    Client cho Bybit USDT-M perpetual futures API (public endpoints).
    Không cần API key cho public data.
    """
    
    BASE_URL = "https://api.bybit.com/v5"
    
    def __init__(self):
        self.timeout = httpx.Timeout(15.0, connect=5.0)
        self._session: httpx.AsyncClient = None
    
    async def __aenter__(self):
        self._session = httpx.AsyncClient(timeout=self.timeout)
        return self
    
    async def __aexit__(self, *args):
        await self._session.aclose()
    
    async def get_open_interest(self, category: str = "linear") -> pd.DataFrame:
        """
        Lấy Open Interest tổng hợp cho USDT-M perpetual.
        
        Endpoint: GET /v5/market/open-interest
        
        Returns:
            DataFrame với columns: symbol, open_interest, change_24h
        """
        all_oi = []
        symbols = ["BTCUSDT", "ETHUSDT", "SOLUSDT", "BNBUSDT"]
        
        for symbol in symbols:
            params = {
                "category": category,
                "symbol": symbol,
                "intervalTime": "1d"  # daily aggregation
            }
            
            response = await self._session.get(
                f"{self.BASE_URL}/market/open-interest",
                params=params
            )
            
            if response.status_code != 200:
                print(f"Bybit API lỗi {response.status_code} cho {symbol}")
                continue
            
            data = response.json()
            
            if data.get("retCode") == 0:
                items = data.get("result", {}).get("list", [])
                for item in items:
                    all_oi.append({
                        "symbol": symbol,
                        "timestamp": datetime.fromtimestamp(int(item["timestamp"]) / 1000),
                        "open_interest_usd": float(item["openInterest"]),
                        "category": "usdt_m_perpetual"
                    })
            
            # Tránh hit rate limit
            await asyncio.sleep(0.2)
        
        return pd.DataFrame(all_oi)
    
    async def get_long_short_ratio(self, symbol: str = "BTCUSDT") -> pd.DataFrame:
        """
        Lấy long-short position ratio từ Bybit.
        
        Endpoint: GET /v5/market/account-ratio
        
        Returns:
            DataFrame với columns: timestamp, long_ratio, short_ratio, symbol
        """
        params = {
            "category": "linear",
            "symbol": symbol,
            "limit": 200  # max 200 records per request
        }
        
        response = await self._session.get(
            f"{self.BASE_URL}/market/account-ratio",
            params=params
        )
        
        data = response.json()
        
        if data.get("retCode") != 0:
            raise ValueError(f"Bybit API error: {data.get('retMsg')}")
        
        items = data.get("result", {}).get("list", [])
        
        df = pd.DataFrame([{
            "timestamp": datetime.fromtimestamp(int(item["timestamp"]) / 1000),
            "symbol": symbol,
            "long_account_ratio": float(item["longAccount"]),
            "short_account_ratio": float(item["shortAccount"]),
            "long_short_ratio": float(item["longAccount"]) / float(item["shortAccount"])
        } for item in items])
        
        return df
    
    async def get_taker_flow(self, symbol: str = "BTCUSDT") -> pd.DataFrame:
        """
        Lấy taker flow data (buy/sell volume).
        """
        params = {
            "category": "linear",
            "symbol": symbol,
            "limit": 200
        }
        
        response = await self._session.get(
            f"{self.BASE_URL}/market/taker-flow",
            params=params
        )
        
        data = response.json()
        items = data.get("result", {}).get("list", [])
        
        return pd.DataFrame([{
            "timestamp": datetime.fromtimestamp(int(item["timestamp"]) / 1000),
            "buy_taker_volume": float(item["buyMe"]),
            "sell_taker_volume": float(item["sellMe"]),
            "net_flow": float(item["buyMe"]) - float(item["sellMe"])
        } for item in items])


=== DEMO USAGE ===

async def main(): async with BybitUSDTMClient() as client: # Lấy OI cho nhiều symbol oi_df = await client.get_open_interest() print(f"Lấy được {len(oi_df)} records OI từ Bybit") # Lấy long-short ratio btc_ratio = await client.get_long_short_ratio("BTCUSDT") print(f"BTC Long/Short Ratio hiện tại: {btc_ratio['long_short_ratio'].iloc[0]:.4f}") # Taker flow taker_df = await client.get_taker_flow("BTCUSDT") print(f"Net Taker Flow 24h: {taker_df['net_flow'].sum():.2f} USDT") if __name__ == "__main__": asyncio.run(main())

Tích Hợp HolySheep AI Cho Factor Engineering

# holyseep_client.py
"""
HolySheep AI Client cho Crypto Factor Engineering.
Base URL: https://api.holysheep.ai/v1 (KHÔNG dùng api.openai.com)
"""

import httpx
import json
from typing import Dict, List, Optional, Any
import pandas as pd
from datetime import datetime
import hashlib

class HolySheepClient:
    """
    Client chính thức để kết nối HolySheep AI API.
    
   Ưu điểm so với direct API:
    - Độ trễ <50ms (so với 200-500ms của OpenAI/Anthropic)
    - Giá chỉ từ $0.42/MTok với DeepSeek V3.2
    - Hỗ trợ WeChat/Alipay thanh toán
    - Free credits khi đăng ký
    """
    
    BASE_URL = "https://api.holysheep.ai/v1"  # BẮT BUỘC
    
    def __init__(self, api_key: Optional[str] = None):
        self.api_key = api_key or "YOUR_HOLYSHEEP_API_KEY"
        self.timeout = httpx.Timeout(60.0, connect=5.0)
        self._cache: Dict[str, Any] = {}
        self._cache_ttl: Dict[str, datetime] = {}
    
    def _get_cache_key(self, prefix: str, params: Dict) -> str:
        """Tạo cache key duy nhất cho request"""
        param_str = json.dumps(params, sort_keys=True)
        return f"{prefix}:{hashlib.md5(param_str.encode()).hexdigest()}"
    
    def _is_cache_valid(self, key: str, ttl_seconds: int) -> bool:
        """Kiểm tra cache còn valid không"""
        if key not in self._cache_ttl:
            return False
        elapsed = (datetime.now() - self._cache_ttl[key]).total_seconds()
        return elapsed < ttl_seconds
    
    async def chat_completion(
        self,
        messages: List[Dict],
        model: str = "deepseek-v3.2",
        temperature: float = 0.3
    ) -> str:
        """
        Gọi LLM qua HolySheep để phân tích factor signals.
        
        Args:
            messages: List of message dicts [{role, content}]
            model: Model name (deepseek-v3.2, gpt-4.1, claude-sonnet-4.5, gemini-2.5-flash)
            temperature: Sampling temperature
        
        Returns:
            Response text từ LLM
        """
        cache_key = self._get_cache_key("llm", {"messages": messages, "model": model})
        
        # Check cache trước
        if self._is_cache_valid(cache_key, 300):  # 5 phút cache
            return self._cache[cache_key]
        
        async with httpx.AsyncClient(timeout=self.timeout) as client:
            response = await client.post(
                f"{self.BASE_URL}/chat/completions",
                headers={
                    "Authorization": f"Bearer {self.api_key}",
                    "Content-Type": "application/json"
                },
                json={
                    "model": model,
                    "messages": messages,
                    "temperature": temperature,
                    "max_tokens": 2000
                }
            )
            
            if response.status_code == 401:
                raise ConnectionError(
                    "HolySheep 401 Unauthorized - Kiểm tra API key tại "
                    "https://www.holysheep.ai/register"
                )
            
            if response.status_code != 200:
                raise ConnectionError(f"HolySheep API error: {response.status_code}")
            
            result = response.json()
            content = result["choices"][0]["message"]["content"]
            
            # Cache kết quả
            self._cache[cache_key] = content
            self._cache_ttl[cache_key] = datetime.now()
            
            return content
    
    async def cache_oi_data(self, symbol: str, df: pd.DataFrame):
        """Cache OI data để fallback khi Tardis lỗi"""
        cache_key = f"oi:{symbol}"
        self._cache[cache_key] = df.to_dict()
        self._cache_ttl[cache_key] = datetime.now()
    
    async def get_cached_oi(self, symbol: str) -> pd.DataFrame:
        """Lấy OI data từ cache"""
        cache_key = f"oi:{symbol}"
        if cache_key in self._cache:
            return pd.DataFrame(self._cache[cache_key])
        raise ValueError(f"Không có cache cho {symbol}")
    
    async def analyze_factor_signals(
        self,
        oi_okx: pd.DataFrame,
        oi_bybit: pd.DataFrame,
        long_short_ratio: pd.DataFrame
    ) -> Dict:
        """
        Sử dụng LLM để phân tích multi-factor signals.
        
        Factor inputs:
        - OKX Open Interest trends
        - Bybit Open Interest trends  
        - Long-short position ratio
        - Taker flow data
        
        Returns:
            Dict với analysis, signals, và confidence scores
        """
        # Tính toán features cơ bản
        features = {
            "okx_btc_oi_change_pct": self._calculate_oi_change(oi_okx),
            "bybit_btc_oi_change_pct": self._calculate_oi_change(oi_bybit),
            "long_short_ratio_current": long_short_ratio["long_short_ratio"].iloc[-1],
            "long_short_ratio_24h_ago": long_short_ratio["long_short_ratio"].iloc[-24] 
                if len(long_short_ratio) > 24 else None,
            "oi_divergence": self._calculate_divergence(oi_okx, oi_bybit)
        }
        
        # Gọi LLM để phân tích
        messages = [
            {"role": "system", "content": """Bạn là chuyên gia phân tích crypto derivatives.
Phân tích các factor signals và đưa ra trading recommendations.
Trả lời JSON format với fields: analysis, signal (bullish/bearish/neutral), confidence (0-1), key_levels."""},
            {"role": "user", "content": f"""
Phân tích factor signals cho BTC Perpetual Futures:

**OKX OI Change 24h**: {features['okx_btc_oi_change_pct']:.2f}%
**Bybit OI Change 24h**: {features['bybit_btc_oi_change_pct']:.2f}%
**Long/Short Ratio hiện tại**: {features['long_short_ratio_current']:.4f}
**Long/Short Ratio 24h trước**: {features['long_short_ratio_24h_ago']:.4f}
**OI Divergence Score**: {features['oi_divergence']:.4f}

Phân tích:
1. OI trend (tăng/giảm/b sideways) và implications
2. Long-short ratio shift và sentiment
3. Divergence giữa OKX và Bybit
4. Overall signal với confidence score
"""}
        ]
        
        llm_response = await self.chat_completion(
            messages,
            model="deepseek-v3.2"  # Rẻ nhất, hiệu quả cho task này
        )
        
        return {
            "features": features,
            "llm_analysis": llm_response,
            "timestamp": datetime.now().isoformat()
        }
    
    def _calculate_oi_change(self, df: pd.DataFrame) -> float:
        """Tính % thay đổi OI 24h"""
        if len(df) < 24:
            return 0.0
        current = df["open_interest_usd"].iloc[-1]
        past = df["open_interest_usd"].iloc[-24]
        return ((current - past) / past) * 100
    
    def _calculate_divergence(self, df1: pd.DataFrame, df2: pd.DataFrame) -> float:
        """
        Tính divergence score giữa OKX và Bybit OI.
        Score > 0: OKX tăng nhanh hơn Bybit (potential bullish divergence)
        Score < 0: Bybit tăng nhanh hơn OKX
        """
        change1 = self._calculate_oi_change(df1)
        change2 = self._calculate_oi_change(df2)
        return change1 - change2


=== COMPLETE FACTOR ENGINEERING PIPELINE ===

async def run_factor_pipeline(): """ Pipeline hoàn chỉnh để thu thập và phân tích factors. """ from tardis_client import TardisOKXClient from bybit_client import BybitUSDTMClient HOLYSHEEP_API_KEY = "YOUR_HOLYSHEEP_API_KEY" TARDIS_API_KEY = "YOUR_TARDIS_API_KEY" holyseep = HolySheepClient(HOLYSHEEP_API_KEY) # Thu thập dữ liệu song song tasks = [] # 1. Tardis OKX OI (với fallback) try: async with TardisOKXClient(TARDIS_API_KEY) as tardis: okx_oi = await tardis.get_perpetual_oi("BTC-USDT-SWAP") await holyseep.cache_oi_data("okx_btc", okx_oi) except ConnectionError as e: print(f"Tardis lỗi: {e}") okx_oi = await holyseep.get_cached_oi("okx_btc") # 2. Bybit USDT-M Data async with BybitUSDTMClient() as bybit: bybit_oi = await bybit.get_open_interest() long_short = await bybit.get_long_short_ratio("BTCUSDT") # 3. LLM Analysis qua HolySheep analysis = await holyseep.analyze_factor_signals( okx_oi, bybit_oi, long_short ) print("=== FACTOR ANALYSIS RESULT ===") print(json.dumps(analysis, indent=2, default=str)) return analysis if __name__ == "__main__": result = asyncio.run(run_factor_pipeline())

Xây Dựng Multi-Factor Signal System

# factor_system.py
"""
Hệ thống multi-factor signal cho crypto trading.
Kết hợp OI, Long-Short Ratio, Taker Flow thành composite score.
"""

import pandas as pd
import numpy as np
from typing import Dict, Tuple
from datetime import datetime, timedelta

class CryptoFactorSystem:
    """
    Multi-factor system sử dụng dữ liệu từ Tardis + Bybit.
    
    Factors:
    1. OI Momentum (weight: 0.3)
    2. Long-Short Ratio Shift (weight: 0.35)
    3. Taker Flow Sentiment (weight: 0.25)
    4. Cross-Exchange Divergence (weight: 0.1)
    """
    
    def __init__(self):
        self.weights = {
            "oi_momentum": 0.30,
            "long_short_shift": 0.35,
            "taker_flow": 0.25,
            "divergence": 0.10
        }
    
    def calculate_oi_momentum(
        self, 
        oi_df: pd.DataFrame, 
        lookback_hours: int = 24
    ) -> float:
        """
        Tính OI Momentum Factor.
        > 0: OI đang tăng (dòng tiền vào leverage positions)
        < 0: OI đang giảm (dòng tiền ra hoặc liquidation)
        """
        if len(oi_df) < lookback_hours:
            return 0.0
        
        current_oi = oi_df["open_interest_usd"].iloc[-1]
        past_oi = oi_df["open_interest_usd"].iloc[-lookback_hours]
        
        momentum = ((current_oi - past_oi) / past_oi) * 100
        
        # Normalize về -1 to 1 scale
        return np.clip(momentum / 10, -1, 1)
    
    def calculate_long_short_shift(
        self,
        ratio_df: pd.DataFrame,
        lookback_hours: int = 24
    ) -> float:
        """
        Tính Long-Short Shift Factor.
        > 0: Retail đang short nhiều hơn (potential squeeze)
        < 0: Retail đang long nhiều hơn
        """
        if len(ratio_df) < lookback_hours:
            return 0.0
        
        current_ratio = ratio_df["long_short_ratio"].iloc[-1]
        past_ratio = ratio_df["long_short_ratio"].iloc[-lookback_hours]
        
        shift = current_ratio - past_ratio
        
        # Threshold-based scoring
        if shift > 0.05:
            return 0.8  # Strong shift towards longs
        elif shift > 0.02:
            return 0.4
        elif shift < -0.05:
            return -0.8
        elif shift < -0.02:
            return -0.4
        return 0.0
    
    def calculate_taker_sentiment(
        self,
        taker_df: pd.DataFrame
    ) -> float:
        """
        Tính Taker Flow Sentiment.
        Net buy volume > Net sell volume = Bullish
        """
        if taker_df.empty:
            return 0.0
        
        buy_vol = taker_df["buy_taker_volume"].sum()
        sell_vol = taker_df["sell_taker_volume"].sum()
        
        if buy_vol + sell_vol == 0:
            return 0.0
        
        net_ratio = (buy_vol - sell_vol) / (buy_vol + sell_vol)
        return np.clip(net_ratio, -1, 1)
    
    def calculate_divergence(
        self,
        oi_okx: pd.DataFrame,
        oi_bybit: pd.DataFrame
    ) -> float:
        """
        Tính Cross-Exchange Divergence Factor.
        > 0: OKX OI tăng nhanh hơn Bybit (potential OKX-led move)
        < 0: Bybit OI tăng nhanh hơn OKX
        """
        if oi_okx.empty or oi_bybit.empty:
            return 0.0
        
        momentum_okx = self.calculate_oi_momentum(oi_okx)
        momentum_bybit = self.calculate_oi_momentum(oi_bybit)
        
        divergence = momentum_okx - momentum_bybit
        return np.clip(divergence, -1, 1)
    
    def calculate_composite_signal(
        self,
        oi_okx: pd.DataFrame,
        oi_bybit: pd.DataFrame,
        ratio_df: pd.DataFrame,
        taker_df: pd.DataFrame
    ) -> Dict:
        """
        Tính composite signal từ tất cả factors.
        
        Returns:
            Dict với composite_score và breakdown
        """
        factors = {
            "oi_momentum": self.calculate_oi_momentum(oi_okx),
            "long_short_shift": self.calculate_long_short_shift(ratio_df),
            "taker_flow": self.calculate_taker_sentiment(taker_df),
            "divergence": self.calculate_divergence(oi_okx, oi_bybit)
        }
        
        # Weighted sum
        composite = sum(
            factors[key] * self.weights[key] 
            for key in self.weights.keys()
        )
        
        # Signal classification
        if composite > 0.3:
            signal = "BULLISH"
        elif composite < -0.3:
            signal = "BEARISH"
        else:
            signal = "NEUTRAL"
        
        return {
            "composite_score": round(composite, 4),
            "signal": signal,
            "factors": {k: round(v, 4) for k, v in factors.items()},
            "weights": self.weights,
            "timestamp": datetime.now().isoformat(),
            "confidence": abs(composite)  # Higher abs score = higher confidence
        }
    
    def generate_trading_signal(
        self,
        composite_result: Dict,
        price: float,
        entry_zone: Tuple[float, float] = None
    ) -> Dict:
        """
        Tạo trading signal với entry/stop/PT levels.
        """
        score = composite_result["composite_score"]
        signal = composite_result["signal"]
        
        if signal == "BULLISH":
            return {
                "action": "LONG",
                "entry": price,
                "stop_loss": price * 0.985,  # -1.5%
                "take_profit_1": price * 1.02,  # +2%
                "take_profit_2": price * 1.04,  # +4%
                "position_size_recommendation": "MEDIUM",  # Based on confidence
                "risk_reward_ratio": 2.0
            }
        elif signal == "BEARISH":
            return {
                "action": "SHORT",
                "entry": price,
                "stop_loss": price * 1.015,  # +1.5%
                "take_profit_1": price * 0.98,
                "take_profit_2": price * 0.96,
                "position_size_recommendation": "MEDIUM",
                "risk_reward_ratio": 2.0
            }
        else:
            return {
                "action": "NO_POSITION",
                "reason": "Signal below threshold",
                "composite_score_required": 0.3
            }


=== BACKTESTING THỦ TỤC ===

def backtest_factor_system( historical_data: Dict[str, pd.DataFrame], initial_capital: float = 10000 ) -> Dict: """ Backtest hệ thống factor trên dữ liệu lịch sử. """ system = CryptoFactorSystem() trades = [] equity_curve = [initial_capital] for i in range(24, len(historical_data["okx_oi"])): # Calculate factors tại