diff --git a/config.json b/config.json index 5e8981a..b981c7f 100644 --- a/config.json +++ b/config.json @@ -2,9 +2,10 @@ "cctxSymbol": "ETH/USDT:USDT", "symbol": "ETHUSDT", "startBalance": 10000, - "interval": 60, - "ohlcvInterval": "1h", + "interval": 5, + "ohlcvInterval": "5m", "orderSizeQuote": 100, + "forceTime": 15, "leverage": 5, "feeTaker": 0.055, "pendingCancelTime": 1200000, diff --git a/index.js b/index.js index 4a041e0..829f4cc 100644 --- a/index.js +++ b/index.js @@ -172,9 +172,48 @@ function enterMarket(sig) { logger.info(`[FILLED] ${sig.side} 시장가 @${curPrice} qty=${qty}`, { position }); } +function forceExit() { + if(position) { + + const pnl = (position.side === 'LONG' ? curPrice - position.entry : position.entry - curPrice) * position.qty; + const fee = position.qty * curPrice * (cfg.feeTaker / 100); + const netPnl = pnl - fee; + balance += netPnl; + + const tradeRecord = { + ...position, + closed: true, + exitPrice: curPrice, + exitReason: 'force Exit', + pnl: netPnl, + closeTime: Date.now(), + finalBalance: balance, + leverage: cfg.leverage + }; + + trades.push(tradeRecord); + fs.writeFileSync(cfg.logPath, JSON.stringify(trades, null, 2)); + + logger.info(`[FORCEEXIT] @${curPrice.toFixed(4)} | PnL=${netPnl.toFixed(2)} | Balance=${balance.toFixed(2)}`, { + trade: tradeRecord, + market: { currentPrice: curPrice } + }); + + // 종료된 포지션 로깅 + logger.logPosition(tradeRecord, `강제 청산 포지션 종료`); + + position = null; + } +} + function checkExit() { if (!position || curPrice === null) return; + if (Date.now() - position.openTime >= (1000 * 60) *cfg.forceTime) { + forceExit() + return; + } + const { id, side, entry, qty, sl, tp, fe, ib} = position; let exit = null; diff --git a/strategy.js b/strategy.js index 180e5cf..d013895 100644 --- a/strategy.js +++ b/strategy.js @@ -37,47 +37,58 @@ const prompts = { 모든 가격을 가장 가까운 0.1 USDT로 반올림하세요. reason 은 한국어로 대답해줘.`, - '15m': `당신은 2025년 기준 코인 선물 **15분봉 전문 트레이더**입니다. 15분 단위로 신속한 진입/청산이 필수적이며, **2~3배 레버리지**로 고빈도 수익을 추구합니다. 다음 규칙을 철저히 적용하세요. - ### 📌 핵심 분석 지표 (15분봉 최적화) - - **롱 진입 조건** (2가지 충족 시): - 1. EMA9 > EMA21 정배열 + 가격이 **15분 VWAP 상향 돌파** (2회 재테스트 성공) - 2. RSI(9) 30 이하에서 **역다이버전스** + 양봉 체인 2연속 - 3. Funding Rate < -0.03% + Liquidation Cluster(0.2% 구간) 형성 + '5m': `당신은 2025년 기준 코인 선물 **5분봉 전문 트레이더**입니다. 5분 단위로 신속한 진입/청산이 필수적이며, **2~3배 레버리지**로 고빈도 수익을 추구합니다. 다음 규칙을 철저히 적용하세요. + 🔸 롱 포지션 진입 조건 (Long Entry) + 다음 모든 조건을 동시에 충족할 경우 매수 진입 시그널 발생: + + 이동평균선 정배열: + 5일 이동평균선 (MA5) > 20일 이동평균선 (MA20) + CCI (상대강도지수): + CCI > 100 + RSI (60~70 구간): + RSI > 60 AND RSI < 70 + (과매수 직전, 강한 상승 모멘텀) + 거래량 급증: + 현재 캔들 거래량 > (직전 5일 평균 거래량 × 2) + ✅ 진입 시점: 위 4가지 조건이 동시에 충족된 캔들이 마감된 직후 (다음 캔들 시가 기준 진입) + + 🔸 숏 포지션 진입 조건 (Short Entry) + 다음 모든 조건을 동시에 충족할 경우 매도 진입 시그널 발생: - - **숏 진입 조건** (2가지 충족 시): - 1. 볼린저 밴드(14,1.5σ) 상단 **3회 테스트 실패** + MACD(6,13,9) 히스토그램 급감 - 2. OVM에서 **롱 리퀴 헌팅 구간** (Coinalyze 기준 5분 내 집중) - 3. Funding Rate 15분 이동평균 > 0.07% + 이동평균선 역배열: + 5일 이동평균선 (MA5) < 20일 이동평균선 (MA20) + CCI (과매도 영역): + CCI < -100 + RSI (하락 신호): + RSI < 40 **AND** RSI > 30 + (과매도 직전, 강한 하락 모멘텀) + 거래량 급증: + 현재 캔들 거래량 > (직전 5일 평균 거래량 × 2) + ✅ 진입 시점: 위 4가지 조건이 동시에 충족된 캔들이 마감된 직후 (다음 캔들 시가 기준 진입) - ### ⚙️ 15분봉 특화 리스크 관리 (!!!!꼭 지겨야 하는 조건) - - **스탑로스**: 최근 3봉 저점(롱)/고점(숏) ± 0.3% or ATR(7)*1.2 - - **테이크프로핏**: 1:2 비율 (예: SL 0.5% → TP 1.0%) - - **홀드 조건**: - • 롱 숏 포지션에 해당 하지 않고 손실이 발생 할거 같으면 홀드 - ### 📊 15분봉 데이터 해석 핵심 - - **VWAP**: 15분 단위 재계산, **상승 시 0.15% 이내 재테스트** 필수 - - **다이버전스**: RSI/MACD 신호 지속시간 **3봉 이내**만 유효 - - **OVM**: Liquidation Cluster **0.2% 미만 밀집 구간**에만 반응 - ### 📝 출력 형식 (순수 JSON, 추가 설명 금지, !!반드시 JSON 으로만 대답) - { - side: LONG/SHORT/HOLD, - price: 진입가(소수점 2자리), - sl: 손절가(소수점 2자리), - tp: 익절가(소수점 2자리), - reason: 핵심 2가지 지표 조합 (예: EMA9/21 정배열+리퀴 헌팅 구간 형성) - } + ⚠️ 공통 관리 규칙 (초단타 필수 설정) + 스탑로스 (SL): + 롱 진입 시: 최근 3개 캔들 중 가장 낮은 저가 하단 1~2% 아래 + 숏 진입 시: 최근 3개 캔들 중 가장 높은 고가 상단 1~2% 위 + → 리스크 1% 이내 유지 권장 + 테이크프로핏 (TP): + 목표 수익률: 2~3% (리스크 대비 2:1 이상) + 또는, RSI가 각각 70 이상(롱), 30 이하(숏) 진입 후 반전 시 조기 익절 고려 + 보유 시간 제한: + 최대 30분 ~ 1시간 이내 미체결 시 자동 청산 권장 (초단타 특성 반영) + 청산 조건 (조기 종료): + CCI가 100 → 80 이하로 하락 (롱) / -100 → -80 이상으로 상승 (숏) + RSI가 70 초과 또는 30 미만 진입 시 즉시 일부 또는 전체 익절 고려 - ⚠️ **2025년 15분봉 특이사항**: - - 기관 알고리즘 트레이딩으로 **0.5% 미만의 짧은 파동**이 주류 - - Funding Rate 변동 **15분 이동평균**만 고려 (순간값 무시) - - VWAP 재테스트 시 **캔들 종가 기준** 필수 확인" + **JSON만 반환하며, 콜론 뒤에 공백은 포함하지 않습니다.** + {"side":"LONG|SHORT|HOLD","price":,"sl":,"tp":,"reason":"<최대 200단어>"} - - 아래 15분봉 데이터 입니다. + 아래 5분봉 데이터 입니다. [데이터 타입] [{"t":,"o":,"h":,"l":,"c":,"v":}, …] - 캔들스틱 데이터 15분봉 : + 캔들스틱 데이터 5분봉 : + {"side":"LONG|SHORT|HOLD","price":,"sl":,"tp":,"reason":"<최대 200단어>"} ` } @@ -92,7 +103,7 @@ export async function aiSignal(bars) { if (bars.length < 20) return null; console.log(Date.now()) const content = ` - ${prompts["1h"]} + ${prompts["5m"]} ${JSON.stringify(bars)} `; diff --git a/test.js b/test.js index cb85734..95a844e 100644 --- a/test.js +++ b/test.js @@ -11,7 +11,7 @@ const ex = new ccxt.bybit({ options: { defaultType: 'swap' } }); -const ohlcv = await ex.fetchOHLCV(cfg.cctxSymbol, cfg.ohlcvInterval, undefined, 336); +const ohlcv = await ex.fetchOHLCV(cfg.cctxSymbol, cfg.ohlcvInterval, undefined, 288); const bars = ohlcv.map(c => ({ t: c[0], o: c[1],