커뮤니티
파워종목검색 오류
아무리 코드를 짜도 저장된 파워종목검색을 찾지 못하는지 파일 이름도 맞게 되었고 파워종목검색에서 저장 하였는데 해당 검색식을 찾지 못하네요 혹시 예스랭규ㅣ지로 만든 검색식을 파워종목에서 불러와서 저장해서 안될까요?
코드가 잘못되엇는지 봐주세요
/* [예스스팟 통합: 터틀 전략 - 검색식 tur 전용] */
// =========================================================
// 1. 설정 변수
// =========================================================
var SearchName = "tur"; // 파워종목검색 이름
var RiskPercent = 0.01; // 자산의 1% 리스크
var EntryPeriod = 55; // 55일 신고가
var ExitPeriod = 20; // 20일 신저가
var ATRLen = 20;
var LongFilter = 200;
var MaxUnits = 4;
var SearchTimerID = 1; // 검색 타이머
var CalcTimerID = 2; // 매매 감시 타이머
var ItemState = {};
var ChartList = [];
var IsSearching = false; // 현재 검색 중인지 확인
function Main_OnStart() {
Main.MessageLog("==========================================");
Main.MessageLog("▶ [1단계] 시스템 가동 시작 (검색식: " + SearchName + ")");
// 계좌 잔고 확인
var money = Account1.GetBalanceETCinfo(0);
Main.MessageLog("▶ 현재 계좌 잔고: " + money.toLocaleString() + "원");
// 시작 2초 후 첫 검색 실행
Main.SetTimer(SearchTimerID, 2000);
// 5초마다 매매 로직 감시
Main.SetTimer(CalcTimerID, 5000);
}
// [2] 타이머 이벤트
function Main_OnTimer(nEventID) {
if (nEventID == SearchTimerID) {
// 응답을 받을 때까지 10초마다 계속 요청 (응답 없으면 무한 재시도)
Main.MessageLog("▶ [2단계] 서버에 '" + SearchName + "' 검색 요청 전송");
Main.ReqPowerSearch(SearchName);
IsSearching = true;
// 검색 주기를 10초로 짧게 설정 (응답 받으면 OnRcvSearchResult에서 60초로 늘림)
Main.KillTimer(SearchTimerID);
Main.SetTimer(SearchTimerID, 10000);
}
if (nEventID == CalcTimerID) {
if (ChartList.length > 0) {
for (var i = 0; i < ChartList.length; i++) {
RunTurtleLogic(ChartList[i]);
}
}
}
}
// [3] 검색 결과 수신 (서버 대답)
function Main_OnRcvSearchResult(nCount) {
IsSearching = false;
// 응답을 받았으므로 다음 검색 주기를 정상(60초)으로 변경
Main.KillTimer(SearchTimerID);
Main.SetTimer(SearchTimerID, 60000);
Main.MessageLog("▶ [3단계] 서버 응답 도착! 발견 종목: " + nCount + "개");
if (nCount > 0) {
for (var i = 0; i < nCount; i++) {
var sCode = Main.GetSearchResult(i);
// 이미 감시 중인 종목인지 확인
var isExist = false;
for (var j = 0; j < ChartList.length; j++) {
if (ChartList[j].GetCode() == sCode) isExist = true;
}
if (!isExist) {
Main.MessageLog(" >> 신규 종목 [" + sCode + "] 차트 생성 요청");
var chartSet = new ReqChartItem(sCode, 1, CHART_PERIOD_DAILY, 500, CHART_REQCOUNT_BAR, false, false);
Main.ReqChartEx(chartSet);
}
}
} else {
Main.MessageLog(" ?? 현재 조건에 맞는 종목이 0개입니다.");
}
}
// [4] 차트 객체 생성 완료
function Main_OnRcvChartEx(oChart) {
var sCode = oChart.GetCode();
ChartList.push(oChart);
if (!ItemState[sCode]) {
ItemState[sCode] = { unitCount: 0, lastPrice: 0 };
}
Main.MessageLog("▶ [4단계] 종목 [" + sCode + "] 감시 시작");
}
// [5] 터틀 매매 로직
function RunTurtleLogic(sChartEx) {
var sCode = sChartEx.GetCode();
if (sChartEx.GetBarCount() < LongFilter) return;
var curMoney = Account1.GetBalanceETCinfo(0);
var vN = Cal_ATR(sChartEx, ATRLen);
var vHighEntry = Cal_Highest(sChartEx, 1, EntryPeriod);
var vLowExit = Cal_Lowest(sChartEx, 1, ExitPeriod);
var vMaLong = Cal_SMA(sChartEx, LongFilter);
var curClose = sChartEx.GetClose(0);
var curHigh = sChartEx.GetHigh(0);
// 1유닛 수량
var vPosSize = 0;
if (vN > 0) {
vPosSize = Math.floor((curMoney * RiskPercent) / (vN * 2));
}
Account1.SetBalanceItem(sCode, 0);
var currentQty = Account1.Balance.count;
// 매수 및 피라미딩
if (currentQty == 0 && vPosSize > 0) {
if (curHigh > vHighEntry && curClose > vMaLong) {
Account1.OrderBuy(sCode, vPosSize, 0, 1);
ItemState[sCode].unitCount = 1;
ItemState[sCode].lastPrice = curClose;
Main.MessageLog("[" + sCode + "] Unit 1 진입 시도");
}
} else if (currentQty > 0 && ItemState[sCode].unitCount < MaxUnits) {
var nextEntry = ItemState[sCode].lastPrice + (vN * 0.5);
if (curHigh >= nextEntry) {
Account1.OrderBuy(sCode, vPosSize, 0, 1);
ItemState[sCode].unitCount++;
ItemState[sCode].lastPrice = curClose;
Main.MessageLog("[" + sCode + "] Unit " + ItemState[sCode].unitCount + " 추가매수");
}
}
// 청산
if (currentQty > 0) {
var stopPrice = ItemState[sCode].lastPrice - (vN * 2);
if (curClose <= stopPrice || curClose < vLowExit || curClose < vMaLong) {
Account1.OrderSell(sCode, currentQty, 0, 1);
ItemState[sCode] = { unitCount: 0, lastPrice: 0 };
Main.MessageLog("[" + sCode + "] 전량 청산 로직 가동");
}
}
}
// 보조 지표 함수
function Cal_SMA(c, p) { var s=0; for(var i=0; i<p; i++) s+=c.GetClose(i); return s/p; }
function Cal_Highest(c, s, p) { var m=0; for(var i=s; i<s+p; i++) m=Math.max(m, c.GetHigh(i)); return m; }
function Cal_Lowest(c, s, p) { var m=9e9; for(var i=s; i<s+p; i++) m=Math.min(m, c.GetLow(i)); return m; }
function Cal_ATR(c, p) {
var st=0;
for(var i=0; i<p; i++) {
var t = Math.max(c.GetHigh(i)-c.GetLow(i), Math.abs(c.GetHigh(i)-c.GetClose(i+1)), Math.abs(c.GetLow(i)-c.GetClose(i+1)));
st += t;
}
return st/p;
}

답변 1
예스스탁 예스스탁 답변
2026-02-20 13:35:12