암호화폐 선물 거래에서 수익성 있는 전략을 구축하려면 체계적인 백테스팅이 필수입니다. 이 튜토리얼에서는 OKX 선물 API에서Historical 데이터를 수집하고, 데이터 정제 과정을 거쳐, 주요 기술 지표를 계산하는 전체 파이프라인을 다루겠습니다. 특히 HolySheep AI를 활용하여 백테스팅 결과를 AI로 분석하고 전략 최적화建议你하는 방법까지 포함합니다.
HolySheep AI vs 공식 API vs 기타 릴레이 서비스
| 항목 | HolySheep AI | OKX 공식 API | 기타 릴레이 서비스 |
|---|---|---|---|
| 기본 용도 | AI 모델 통합 게이트웨이 | 거래소 API 직접 접근 | API 우회/중계 서비스 |
| 데이터 수집 | 없음 (거래소 API 직접 사용) | 완벽한 Historical 데이터 | 제한적 또는 불안정 |
| AI 분석 기능 | GPT-4.1, Claude, Gemini 통합 | 없음 | 없음 |
| 비용 | Gemini 2.5 Flash $2.50/MTok | 무료 (API 키만) | 유료 또는 숨은 비용 |
| 백테스트 분석 | AI 기반 인사이트 생성 | 수동 분석 필요 | 제한적 |
| 결제 방식 | 로컬 결제 지원 (신용카드 불필요) | 해당 없음 | 해외 결제만 가능 |
| 신뢰성 | 공식 모델 직접 연동 | 100% 신뢰 | 중단 위험 높음 |
이런 팀에 적합 / 비적합
✅ HolySheep AI가 적합한 팀
- 퀀트 트레이딩 팀: 백테스팅 결과를 AI로 자동 분석하고 인사이트를 얻고 싶은 개발자
- 개인 트레이더: 해외 신용카드 없이 AI 도구를 활용하여 전략을 최적화하려는 분
- 암호화폐 분석가: 다중 AI 모델을 활용하여 시장 데이터를 심층 분석하고 싶은 분
- 자동화 파이프라인 구축자: OKX 데이터 + AI 분석을 하나의 파이프라인으로 통합하려는 분
❌ HolySheep AI가 불필요한 경우
- 단순 거래 실행만 필요: AI 분석 없이 거래소 API만으로 충분한 경우
- 이미 검증된 AI 분석 파이프라인 보유: 자체 AI 시스템으로 백테스트 분석을 이미 자동화한 경우
- 비용 최적화가 최우선: 무료 API만으로도 충분한 분석이 가능한 경우
가격과 ROI
백테스팅 분석에 AI를 활용할 때 비용 효율성을 고려해야 합니다. HolySheep AI의 가격 구조는 다음과 같습니다:
| AI 모델 | 가격 ($/MTok) | 백테스트 분석 1회 비용* | 월간 예상 비용** |
|---|---|---|---|
| Gemini 2.5 Flash | $2.50 | ~$0.015 | $5-15 |
| DeepSeek V3.2 | $0.42 | ~$0.003 | $1-5 |
| Claude Sonnet 4 | $15.00 | ~$0.09 | $20-50 |
| GPT-4.1 | $8.00 | ~$0.048 | $10-30 |
* 1회 백테스트 분석: 약 6,000 토큰 기준
** 월간 300회 백테스트 분석 기준
ROI 분석: HolySheep AI를 활용하면 수동 분석 대비 백테스트 Iteration 시간을 70% 이상 단축할 수 있습니다. 전문가 consultoria 비용을 고려하면 월 $50 이하의 비용으로 상당한 시간과 인적 자원을 절약할 수 있습니다.
왜 HolySheep AI를 선택해야 하나
저는 퀀트 트레이딩을 시작했을 때 백테스트 결과를 Excel로 수동 분석하느라 상당한 시간을 낭비했습니다. HolySheep AI를 도입한 후 백테스트 결과를 API로 전송하고 AI 인사이트를 얻는 자동화 파이프라인을 구축했더니, 전략 최적화 속도가 눈에 띄게 빨라졌습니다.
HolySheep AI가 다른 서비스와 차별화되는 핵심 이유는:
- 단일 API 키로 다중 모델 활용: Gemini로 빠른 분석, Claude로 심층 분석 등 용도에 맞게 선택
- 해외 신용카드 불필요: 한국 개발자도 로컬 결제 방식으로 간편하게 시작
- 무료 크레딧 제공: 가입 시 프로모션 크레딧으로 위험 없이 체험 가능
- 안정적인 연결: 글로벌 게이트웨이架构으로 일관된 응답 속도
1. OKX 선물 API 기본 설정
먼저 OKX 공식 API에서 Historical 데이터를 가져오는 기본 환경을 설정합니다. OKX API는 공식 서비스이므로 직접 사용하고, HolySheep AI는 백테스트 결과 분석에만 활용합니다.
# requirements.txt
pip install requests pandas numpy
import requests
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import time
class OKXDataCollector:
"""OKX 선물 Historical 데이터 수집기"""
def __init__(self, api_key='', secret_key='', passphrase='', use_sandbox=False):
self.base_url = 'https://www.okx.com' if not use_sandbox else 'https://www.okx.com/sandbox'
self.api_key = api_key
self.secret_key = secret_key
self.passphrase = passphrase
def get_historical_klines(self, symbol, interval='1h', start='', end='', limit=100):
"""
Historical K라인 데이터 조회
Args:
symbol: 거래대기 (예: 'BTC-USDT-SWAP')
interval: 시간간격 (1m, 5m, 1H, 1D)
start: 시작 시간 (ISO format)
end: 종료 시간 (ISO format)
limit: 조회 개수 (최대 100)
"""
endpoint = '/api/v5/market/history-candles'
params = {
'instId': symbol,
'bar': interval,
'limit': limit
}
if start:
params['after'] = start
if end:
params['before'] = end
url = f"{self.base_url}{endpoint}"
response = requests.get(url, params=params)
if response.status_code == 200:
data = response.json()
if data.get('code') == '0':
return self._parse_klines(data['data'])
else:
print(f"API 오류: {data.get('msg')}")
return None
else:
print(f"HTTP 오류: {response.status_code}")
return None
def _parse_klines(self, raw_data):
"""K라인 데이터 파싱 및 DataFrame 변환"""
columns = ['timestamp', 'open', 'high', 'low', 'close', 'volume', 'quote_volume']
df = pd.DataFrame(raw_data, columns=columns)
# 데이터 타입 변환
for col in ['open', 'high', 'low', 'close', 'volume', 'quote_volume']:
df[col] = pd.to_numeric(df[col])
# 타임스탬프 변환 (밀리초 → datetime)
df['datetime'] = pd.to_datetime(df['timestamp'].astype(np.int64), unit='ms')
df = df.sort_values('datetime').reset_index(drop=True)
return df
사용 예시
collector = OKXDataCollector()
df = collector.get_historical_klines(
symbol='BTC-USDT-SWAP',
interval='1H',
limit=100
)
print(f"수집된 데이터: {len(df)}개")
print(df.tail())
2. Historical 데이터 정제 파이프라인
OKX에서 수집한 Raw 데이터에는 결측치, 이상치, 비정형 데이터가 포함되어 있습니다. 백테스팅의 정확도를 위해 체계적인 정제 과정이 필수입니다.
import pandas as pd
import numpy as np
from typing import Tuple, List
class DataCleaner:
"""Historical 데이터 정제 유틸리티"""
@staticmethod
def clean_ohlcv(df: pd.DataFrame) -> pd.DataFrame:
"""
OHLCV 데이터 정제
정제 항목:
1. 필수 컬럼 확인
2. 결측치 처리
3. 이상치 제거
4. 중복 타임스탬프 처리
"""
df = df.copy()
# 1. 필수 컬럼 확인
required_cols = ['open', 'high', 'low', 'close', 'volume']
missing_cols = [col for col in required_cols if col not in df.columns]
if missing_cols:
raise ValueError(f"누락된 컬럼: {missing_cols}")
# 2. 결측치 처리
initial_len = len(df)
# forward fill (가격 데이터)
df['open'] = df['open'].fillna(method='ffill')
df['high'] = df['high'].fillna(method='ffill')
df['low'] = df['low'].fillna(method='ffill')
df['close'] = df['close'].fillna(method='ffill')
df['volume'] = df['volume'].fillna(0)
# 3. 이상치 제거 - 고가/저가 Validations
# 고가는 항상 저가보다 높아야 함
df = df[df['high'] >= df['low']]
# 고가는 항상 open, close보다 높거나 같아야 함
df = df[df['high'] >= df[['open', 'close']].max(axis=1)]
# 저가는 항상 open, close보다 낮거나 같아야 함
df = df[df['low'] <= df[['open', 'close']].min(axis=1)]
# 거래량은 음수가 아니어야 함
df = df[df['volume'] >= 0]
# 가격은 양수여야 함
df = df[df['close'] > 0]
# 4. 중복 타임스탬프 처리
if 'datetime' in df.columns:
df = df.drop_duplicates(subset=['datetime'], keep='last')
elif 'timestamp' in df.columns:
df = df.drop_duplicates(subset=['timestamp'], keep='last')
cleaned_len = len(df)
removed = initial_len - cleaned_len
print(f"[DataCleaner] 정제 완료: {initial_len} → {cleaned_len} (제거: {removed}개, {removed/initial_len*100:.2f}%)")
return df.reset_index(drop=True)
@staticmethod
def detect_outliers_zscore(df: pd.DataFrame, column: str, threshold: float = 3.0) -> pd.DataFrame:
"""
Z-score 기반 이상치 탐지
Args:
df: 데이터프레임
column: 대상 컬럼
threshold: Z-score 임계값 (기본: 3.0)
"""
df = df.copy()
mean = df[column].mean()
std = df[column].std()
df[f'{column}_zscore'] = np.abs((df[column] - mean) / std)
outliers = df[df[f'{column}_zscore'] > threshold]
print(f"[Outlier Detection] {column}: {len(outliers)}개 이상치 탐지")
# 이상치 표시
if len(outliers) > 0:
print(outliers[['datetime', column, f'{column}_zscore']].head())
return df
사용 예시
cleaner = DataCleaner()
df_clean = cleaner.clean_ohlcv(df)
이상치 탐지
df_with_outliers = cleaner.detect_outliers_zscore(df_clean, 'volume', threshold=3.0)
print(f"\n정제 후 데이터 샘플:")
print(df_clean.head(10))
3. 기술 지표 계산 모듈
백테스팅의 핵심은 다양한 기술 지표를 계산하고 이를 기반으로 거래 신호를 생성하는 것입니다. 주요 지표들을 모듈화하여 구현합니다.
import pandas as pd
import numpy as np
class TechnicalIndicators:
"""기술 지표 계산기"""
@staticmethod
def sma(df: pd.DataFrame, column: str, period: int) -> pd.Series:
"""단순 이동평균 (SMA)"""
return df[column].rolling(window=period).mean()
@staticmethod
def ema(df: pd.DataFrame, column: str, period: int) -> pd.Series:
"""지수 이동평균 (EMA)"""
return df[column].ewm(span=period, adjust=False).mean()
@staticmethod
def rsi(df: pd.DataFrame, column: str = 'close', period: int = 14) -> pd.Series:
"""상대강도지수 (RSI)"""
delta = df[column].diff()
gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
rs = gain / loss
rsi = 100 - (100 / (1 + rs))
return rsi
@staticmethod
def bollinger_bands(df: pd.DataFrame, column: str = 'close',
period: int = 20, std_dev: float = 2.0) -> pd.DataFrame:
"""볼린저 밴드"""
sma = df[column].rolling(window=period).mean()
std = df[column].rolling(window=period).std()
return pd.DataFrame({
'bb_middle': sma,
'bb_upper': sma + (std * std_dev),
'bb_lower': sma - (std * std_dev)
})
@staticmethod
def macd(df: pd.DataFrame, column: str = 'close',
fast: int = 12, slow: int = 26, signal: int = 9) -> pd.DataFrame:
"""MACD (Moving Average Convergence Divergence)"""
ema_fast = df[column].ewm(span=fast, adjust=False).mean()
ema_slow = df[column].ewm(span=slow, adjust=False).mean()
macd_line = ema_fast - ema_slow
signal_line = macd_line.ewm(span=signal, adjust=False).mean()
histogram = macd_line - signal_line
return pd.DataFrame({
'macd': macd_line,
'macd_signal': signal_line,
'macd_histogram': histogram
})
@staticmethod
def atr(df: pd.DataFrame, period: int = 14) -> pd.Series:
"""평균 진정 범위 (ATR)"""
high_low = df['high'] - df['low']
high_close = np.abs(df['high'] - df['close'].shift())
low_close = np.abs(df['low'] - df['close'].shift())
true_range = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1)
atr = true_range.rolling(window=period).mean()
return atr
@staticmethod
def adx(df: pd.DataFrame, period: int = 14) -> pd.DataFrame:
"""방향성 지수 (ADX)"""
high_diff = df['high'].diff()
low_diff = -df['low'].diff()
pos_dm = high_diff.where((high_diff > low_diff) & (high_diff > 0), 0)
neg_dm = low_diff.where((low_diff > high_diff) & (low_diff > 0), 0)
atr = TechnicalIndicators.atr(df, period)
pos_di = 100 * (pos_dm.rolling(window=period).mean() / atr)
neg_di = 100 * (neg_dm.rolling(window=period).mean() / atr)
dx = 100 * np.abs(pos_di - neg_di) / (pos_di + neg_di)
adx = dx.rolling(window=period).mean()
return pd.DataFrame({
'adx': adx,
'plus_di': pos_di,
'minus_di': neg_di
})
사용 예시
indicators = TechnicalIndicators()
모든 지표 계산
df_clean['sma_20'] = indicators.sma(df_clean, 'close', 20)
df_clean['sma_50'] = indicators.sma(df_clean, 'close', 50)
df_clean['ema_12'] = indicators.ema(df_clean, 'close', 12)
df_clean['rsi_14'] = indicators.rsi(df_clean, 'close', 14)
볼린저 밴드
bb = indicators.bollinger_bands(df_clean, 'close', 20, 2.0)
df_clean = pd.concat([df_clean, bb], axis=1)
MACD
macd = indicators.macd(df_clean, 'close')
df_clean = pd.concat([df_clean, macd], axis=1)
ATR
df_clean['atr_14'] = indicators.atr(df_clean, 14)
ADX
adx = indicators.adx(df_clean, 14)
df_clean = pd.concat([df_clean, adx], axis=1)
print("기술 지표 계산 완료:")
print(df_clean[['datetime', 'close', 'sma_20', 'rsi_14', 'macd', 'atr_14']].tail(10))
4. HolySheep AI를 활용한 백테스트 결과 분석
여기서 HolySheep AI의 진정한 가치를 발휘합니다. 백테스트 결과를 HolySheep AI API로 전송하면, AI가 전략의 강점과 약점을 분석하고 최적화建议你를 제공합니다.
import requests
import json
from datetime import datetime
class BacktestAnalyzer:
"""HolySheep AI 기반 백테스트 분석기"""
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = 'https://api.holysheep.ai/v1'
self.model = 'gemini-2.5-flash' # 비용 효율적인 모델 선택
def analyze_results(self, backtest_results: dict) -> str:
"""
백테스트 결과를 AI로 분석
Args:
backtest_results: 백테스트 결과 딕셔너리
- total_trades: int
- win_rate: float
- profit_factor: float
- max_drawdown: float
- sharpe_ratio: float
- avg_trade_duration: float
- monthly_returns: list
Returns:
AI 인사이트 (문자열)
"""
prompt = self._build_analysis_prompt(backtest_results)
headers = {
'Authorization': f'Bearer {self.api_key}',
'Content-Type': 'application/json'
}
payload = {
'model': self.model,
'messages': [
{
'role': 'user',
'content': prompt
}
],
'temperature': 0.7,
'max_tokens': 2000
}
try:
response = requests.post(
f'{self.base_url}/chat/completions',
headers=headers,
json=payload,
timeout=30
)
if response.status_code == 200:
result = response.json()
return result['choices'][0]['message']['content']
else:
return f"API 오류 발생: {response.status_code} - {response.text}"
except requests.exceptions.Timeout:
return "요청 시간 초과. 다시 시도해주세요."
except Exception as e:
return f"분석 중 오류 발생: {str(e)}"
def _build_analysis_prompt(self, results: dict) -> str:
"""분석 프롬프트 구성"""
prompt = f"""암호화폐 선물 거래 백테스트 결과를 분석하고, 구체적인 최적화建议你를 제공해주세요.
【백테스트 결과 요약】
- 총 거래 횟수: {results.get('total_trades', 0)}회
- 승률: {results.get('win_rate', 0):.2f}%
- 수익 요인 (Profit Factor): {results.get('profit_factor', 0):.2f}
- 최대 드로우다운: {results.get('max_drawdown', 0):.2f}%
- 샤프 비율: {results.get('sharpe_ratio', 0):.2f}
- 평균 거래 시간: {results.get('avg_trade_duration', 0):.2f}시간
【분석 요청】
1. 이 전략의 주요 강점과 약점は何ですか?
2. 수익 개선을 위한 구체적인建议你 3가지를 제시해주세요.
3. 리스크 관점에서 개선이 필요한 부분은?
4. 최적의 거래 조건 (시장 환경, 시간대 등)은何ですか?
한국어로詳細하게 분석해주세요."""
return prompt
def generate_strategy_summary(self, df_with_indicators: pd.DataFrame,
trade_log: list) -> str:
"""거래 로그와 지표를 기반으로 전략 요약 생성"""
# 최근 데이터 요약
recent_data = df_with_indicators.tail(30)
summary = f"""【최근 30개 캔들 요약】
- 평균 가격 변동성: {recent_data['atr_14'].mean():.2f}
- RSI 평균: {recent_data['rsi_14'].mean():.2f}
- MACD 히스토그램 평균: {recent_data['macd_histogram'].mean():.4f}
【거래 로그 요약】
- 최근 거래 수: {len(trade_log)}회
- 승리 거래: {sum(1 for t in trade_log if t.get('profit', 0) > 0)}회
- 패배 거래: {sum(1 for t in trade_log if t.get('profit', 0) <= 0)}회
이 데이터 기반으로:
1. 현재 시장 상태 진단
2. 최적 진입/청산 타이밍建议你
3. 포지션 사이즈 조정 전략
을 한국어로 제시해주세요."""
return summary
사용 예시
analyzer = BacktestAnalyzer(api_key='YOUR_HOLYSHEEP_API_KEY')
샘플 백테스트 결과
sample_results = {
'total_trades': 156,
'win_rate': 58.33,
'profit_factor': 1.45,
'max_drawdown': 12.5,
'sharpe_ratio': 1.82,
'avg_trade_duration': 4.5
}
AI 분석 요청
insights = analyzer.analyze_results(sample_results)
print("【HolySheep AI 분석 결과】")
print(insights)
5. 완전한 백테스팅 파이프라인 통합
이제 모든 모듈을 통합하여 End-to-End 백테스팅 파이프라인을 구축합니다. OKX에서 데이터를 수집하고, 정제하며, 지표를 계산하고, HolySheep AI로 분석하는 전체流程을 자동화합니다.
import requests
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import time
import json
class OKXBacktestPipeline:
"""OKX 선물 백테스팅 통합 파이프라인"""
def __init__(self, holysheep_api_key: str):
self.holysheep_analyzer = BacktestAnalyzer(holysheep_api_key)
self.data_collector = OKXDataCollector()
self.data_cleaner = DataCleaner()
self.indicators = TechnicalIndicators()
def run_full_pipeline(self, symbol: str = 'BTC-USDT-SWAP',
interval: str = '1H',
days: int = 90) -> dict:
"""
전체 백테스팅 파이프라인 실행
Returns:
분석 결과 및 메트릭 딕셔너리
"""
print(f"\n{'='*60}")
print(f" OKX 백테스팅 파이프라인 시작")
print(f" 심볼: {symbol} | 간격: {interval} | 기간: {days}일")
print(f"{'='*60}\n")
# 1단계: 데이터 수집
print("【1단계】Historical 데이터 수집 중...")
start_time = int((datetime.now() - timedelta(days=days)).timestamp() * 1000)
end_time = int(datetime.now().timestamp() * 1000)
all_data = []
current_start = start_time
while current_start < end_time:
batch = self.data_collector.get_historical_klines(
symbol=symbol,
interval=interval,
start=str(current_start),
limit=100
)
if batch is not None and len(batch) > 0:
all_data.append(batch)
current_start = int(batch['timestamp'].iloc[-1]) + 1
print(f" 수집 완료: {len(batch)}개 (총 {sum(len(d) for d in all_data)}개)")
else:
break
time.sleep(0.2) # API Rate Limit 방지
if not all_data:
print("데이터 수집 실패")
return None
df_raw = pd.concat(all_data, ignore_index=True)
print(f" 총 수집 데이터: {len(df_raw)}개\n")
# 2단계: 데이터 정제
print("【2단계】데이터 정제 중...")
df_clean = self.data_cleaner.clean_ohlcv(df_raw)
print(f" 정제 후 데이터: {len(df_clean)}개\n")
# 3단계: 기술 지표 계산
print("【3단계】기술 지표 계산 중...")
df_clean = self._calculate_all_indicators(df_clean)
print(" 모든 지표 계산 완료\n")
# 4단계: 백테스트 시뮬레이션
print("【4단계】백테스트 시뮬레이션 중...")
backtest_results, trade_log = self._run_backtest_simulation(df_clean)
print(f" 총 거래: {backtest_results['total_trades']}회")
print(f" 승률: {backtest_results['win_rate']:.2f}%\n")
# 5단계: HolySheep AI 분석
print("【5단계】HolySheep AI 분석 요청 중...")
ai_insights = self.holysheep_analyzer.analyze_results(backtest_results)
print(f" AI 분석 완료\n")
# 결과 통합
final_results = {
'data_info': {
'symbol': symbol,
'interval': interval,
'period': f'{days} days',
'total_candles': len(df_clean)
},
'backtest_metrics': backtest_results,
'ai_insights': ai_insights,
'trade_log': trade_log,
'processed_data': df_clean
}
return final_results
def _calculate_all_indicators(self, df: pd.DataFrame) -> pd.DataFrame:
"""모든 기술 지표 계산"""
df = df.copy()
# 이동평균선
df['sma_10'] = self.indicators.sma(df, 'close', 10)
df['sma_20'] = self.indicators.sma(df, 'close', 20)
df['sma_50'] = self.indicators.sma(df, 'close', 50)
df['ema_12'] = self.indicators.ema(df, 'close', 12)
df['ema_26'] = self.indicators.ema(df, 'close', 26)
# RSI
df['rsi_14'] = self.indicators.rsi(df, 'close', 14)
# 볼린저 밴드
bb = self.indicators.bollinger_bands(df, 'close', 20, 2.0)
df = pd.concat([df, bb], axis=1)
# MACD
macd = self.indicators.macd(df, 'close')
df = pd.concat([df, macd], axis=1)
# ATR
df['atr_14'] = self.indicators.atr(df, 14)
return df
def _run_backtest_simulation(self, df: pd.DataFrame) -> tuple:
"""단순 이동평균 교차 전략 시뮬레이션"""
df = df.dropna().copy()
trades = []
position = None
entry_price = 0
for i in range(1, len(df)):
row = df.iloc[i]
prev_row = df.iloc[i-1]
#買いエントリー条件: SMA 10이 SMA 20 위로 교차
if prev_row['sma_10'] <= prev_row['sma_20'] and row['sma_10'] > row['sma_20']:
if position is None:
position = 'long'
entry_price = row['close']
entry_time = row['datetime']
#卖出条件: SMA 10이 SMA 20 아래로 교차
elif prev_row['sma_10'] >= prev_row['sma_20'] and row['sma_10'] < row['sma_20']:
if position == 'long':
exit_price = row['close']
profit = (exit_price - entry_price) / entry_price * 100
duration = (row['datetime'] - entry_time).total_seconds() / 3600
trades.append({
'entry_time': entry_time,
'exit_time': row['datetime'],
'entry_price': entry_price,
'exit_price': exit_price,
'profit': profit,
'duration_hours': duration,
'direction': 'long'
})
position = None
# 메트릭 계산
if not trades:
return {
'total_trades': 0,
'win_rate': 0,
'profit_factor': 0,
'max_drawdown': 0,
'sharpe_ratio': 0,
'avg_trade_duration': 0
}, []
wins = [t for t in trades if t['profit'] > 0]
losses = [t for t in trades if t['profit'] <= 0]
total_profit = sum(t['profit'] for t in wins)
total_loss = abs(sum(t['profit'] for t in losses))
# 손익 계산 (단순화)
cumulative = 0
peak = 0
max_dd = 0
for t in trades:
cumulative += t['profit']
if cumulative > peak:
peak = cumulative
dd = peak - cumulative
if dd