Files
bot/strategy.js
2025-09-02 13:03:45 +09:00

128 lines
5.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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":<Unix ts>,"o":<float>,"h":<float>,"l":<float>,"c":<float>,"v":<float>}, …]
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":<float>,"sl":<float>,"tp":<float>,"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":<float>,"sl":<float>,"tp":<float>,"reason":"<최대 200단어>"}
아래 5분봉 데이터 입니다.
[데이터 타입]
[{"t":<Unix ts>,"o":<float>,"h":<float>,"l":<float>,"c":<float>,"v":<float>}, …]
캔들스틱 데이터 5분봉 :
{"side":"LONG|SHORT|HOLD","price":<float>,"sl":<float>,"tp":<float>,"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'}
}
}