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ể:
- Phát hiện divergence giữa giá và OI để dự đoán reversal
- So sánh long-short ratio giữa các sàn để tìm arbitrage opportunity
- Xây dựng momentum factor từ changes in holdings
- Tạo signal cross-sectional bằng cách so sánh BTC vs ETH OI trends
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:
- Tardis API: Nguồn dữ liệu thô từ OKX perpetual futures
- Bybit Public API: Dữ liệu USDT-M perpetual (OI, positions)
- HolySheep AI: Orchestration, transformation, và LLM-powered analysis
- Storage Layer: PostgreSQL cho time-series data + Redis cho real-time cache
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