// strategy.js import logger from './logger.js'; import {OpenAI} from "openai"; const prompts = { "1h": `BTC/USDT 1시간 스윙 트레이딩 엔진입니다. - 시간대: 1시간 캔들만. - 일일 거래 빈도 목표: ≥ 3개의 유효 설정. - 거래당 위험: 계좌 잔액의 1% 이하. - 동시에 2개 이상의 포지션을 보유하지 마십시오. - 최종 JSON 외부에 해설을 추가하지 마십시오. [입력] 최근 1시간 캔들 50개(최근 캔들 순, 형식: [{"t":,"o":,"h":,"l":,"c":,"v":}, …] LONG: - 9-EMA > 21-EMA (둘 다 상승). - RSI14가 40~60 사이이고 이전 캔들 대비 상승하는 경우. - Close ≥ VWAP. - Close ≤ 스윙 고점 - ATR14×0.5 (작은 하락 구간). SHORT: - 9-EMA < 21-EMA (둘 다 하락). - RSI14가 40~60 사이이고 이전 캔들 대비 하락하는 경우. - Close ≤ VWAP. - Close ≥ 스윙 저점 + ATR14×0.5 (작은 하락 구간). HOLD: - 매수 또는 매도 조건이 모두 충족되지 않는 경우. JSON만 반환하며, 콜론 뒤에 공백은 포함하지 않습니다. {"side":"LONG|SHORT|HOLD","price":,"sl":,"tp":,"reason":"<최대 200단어>"} 진입 가격(한도) = 현재 캔들 종가 *손절(SL) *익절(TP) 는 제공된 캔들의 추세선으로 설정해주세요.(중요) 모든 가격을 가장 가까운 0.1 USDT로 반올림하세요. reason 은 한국어로 대답해줘.`, '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) 다음 모든 조건을 동시에 충족할 경우 매도 진입 시그널 발생: 이동평균선 역배열: 5일 이동평균선 (MA5) < 20일 이동평균선 (MA20) CCI (과매도 영역): CCI < -100 이전 캔들 대비 하락하는 경우. RSI (하락 신호): RSI < 40 **AND** RSI > 30 이전 캔들 대비 하락하는 경우. (과매도 직전, 강한 하락 모멘텀) 거래량 급증: 현재 캔들 거래량 > (직전 5일 평균 거래량 × 2) ✅ 진입 시점: 위 4가지 조건이 동시에 충족된 캔들이 마감된 직후 (다음 캔들 시가 기준 진입) ⚠️ 공통 관리 규칙 (초단타 필수 설정) 스탑로스 (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 미만 진입 시 즉시 일부 또는 전체 익절 고려 **JSON만 반환하며, 콜론 뒤에 공백은 포함하지 않습니다.** {"side":"LONG|SHORT|HOLD","price":,"sl":,"tp":,"reason":"<최대 200단어>"} 아래 5분봉 데이터 입니다. [데이터 타입] [{"t":,"o":,"h":,"l":,"c":,"v":}, …] 캔들스틱 데이터 5분봉 : {"side":"LONG|SHORT|HOLD","price":,"sl":,"tp":,"reason":"<최대 200단어>"} ` } const openai = new OpenAI({ baseURL: 'https://openrouter.ai/api/v1', apiKey: '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', }); export async function aiSignal(bars) { if (bars.length < 20) return null; console.log(Date.now()) const content = ` ${prompts["5m"]} ${JSON.stringify(bars)} `; const completion = await openai.chat.completions.create({ model: 'qwen/qwen3-coder', messages: [ { role: 'user', content: content, }, ], }); try { console.log(Date.now()) const msg = completion.choices[0].message.content logger.debug(msg); const sig = JSON.parse(msg) return sig; } catch(e) { return {side : 'HOLD'} } }