4.2 KiB
🤖 Cursor AI 전용: 포지션 종속성 선택 기능 구현 요청 프롬프트 🎯 구현 목표 (Goal) 매매 전략 실행 및 백테스팅 엔진 가동 시, "매도 시그널이 발생했을 때 이전 매수 기록(포지션)이 있어야만 실행할 것인가"에 대한 제약 조건을 유저가 직접 제어할 수 있도록 시스템을 확장합니다. 유저의 설정에 따라 Ta4j의 엄격한 포지션 검증 로직을 타거나, 혹은 순수 지표 조건 매칭 분기로 우회 구동되도록 구현해 주세요.
🛠️ 1. 요구사항 명세 및 정책 (Requirements) ① 설정 화면 UI 항목 추가 (Frontend) 매매 시그널 발생 조건 제어 (라디오 버튼 또는 셀렉트 박스):
-
보유 자산 기준 매매 (Long-Only 모드): 기존에 매수한 이력(Open Position)이 완벽히 존재할 때만 매도 시그널 허용.
-
순수 기술 지표 기준 매매 (Signal-Only 모드): 이전 매수 이력 존재 여부와 완전히 무관하게, 기술적 지표 규칙만 만족하면 매도 시그널을 즉시 허용.
② 백엔드 전략 평가 코어 제어 정책 (Backend Logic) 유저가 선택한 옵션값은 데이터베이스(UserStrategySettings)에 저장되며, 실시간 감시 엔진 및 과거 데이터 백테스팅 중계기(HistoricalDataService) 연산 시 공통 분기 조건으로 사용됩니다.
[Mode 1] LONG_ONLY (보유 자산 기준 매매) 처리 프로토콜:
Ta4j의 표준 strategy.shouldExit(index, tradingRecord) 형식을 그대로 유지합니다.
내부적으로 TradingRecord에 현재 열려 있는 포지션이 없다면 매도 조건을 만족하더라도 시그널을 내보내지 않습니다.
[Mode 2] SIGNAL_ONLY (순수 기술 지표 기준 매매) 처리 프로토콜:
Ta4j Strategy 객체의 포지션 검증을 우회하기 위해, 내부 Rule 인스턴스를 직접 추출하여 판단합니다.
매수 판단 시: strategy.getEntryRule().isSatisfied(index) 호출
매도 판단 시: strategy.getExitRule().isSatisfied(index) 호출 ➔ 이전 매수 기록 유무와 무관하게 지표 수식만 맞으면 무조건 매도("SELL") 시그널 확정
💾 2. 데이터 구조 및 인터페이스 설계 (Data Struct) ① [PUT] /api/strategy/settings (기존 설정 API 데이터 구조 확장) JSON { "market": "KRW-BTC", "isLiveCheck": true, "executionType": "CANDLE_CLOSE", "positionMode": "SIGNAL_ONLY" // "LONG_ONLY" (방식1) 또는 "SIGNAL_ONLY" (방식2) 추가 } ② API 반영처 명시 이 positionMode 옵션은 아래 두 가지 비즈니스 로직 내부의 시그널 판정 구간에 반드시 녹아들어야 합니다.
HistoricalDataService: 차트 초기 로딩 및 과거 스크롤 시, 과거 캔들 배열 각각에 "BUY"/"SELL"을 태깅하여 넘겨주는 백테스팅 로직 부문.
LiveStrategyEvaluator: 3초 스케줄러 또는 봉 마감 이벤트 발생 시, 실시간 STOMP 패킷의 signal 필드에 값을 주입하는 실시간 감시 로직 부문.
💻 3. 백엔드 참고 가이드 코드 (Reference Code for AI) Java @Component @RequiredArgsConstructor public class StrategySignalDeterminer {
/**
* 유저 설정 정보(positionMode)에 따라 포지션 제약 유무를 분기하여 시그널을 결정하는 코어 메서드
*/
public String determineSignal(Strategy strategy, BarSeries series, TradingRecord tradingRecord, int index, String positionMode) {
// 1. 보유 자산 기준 매매 (Long-Only) -> Ta4j 표준 엄격 모드
if ("LONG_ONLY".equals(positionMode)) {
if (strategy.shouldEnter(index, tradingRecord)) {
return "BUY";
}
if (strategy.shouldExit(index, tradingRecord)) {
return "SELL";
}
return "NONE";
}
// 2. 순수 기술 지표 기준 매매 (Signal-Only) -> 포지션 락 우회 모드
if ("SIGNAL_ONLY".equals(positionMode)) {
boolean isEntrySatisfied = strategy.getEntryRule().isSatisfied(index);
boolean isExitSatisfied = strategy.getExitRule().isSatisfied(index);
if (isEntrySatisfied) return "BUY";
if (isExitSatisfied) return "SELL";
return "NONE";
}
return "NONE";
}
}