커뮤니티

파워종목검색 오류

프로필 이미지
3프로
2026-02-09 14:08:28
79
글번호 230466
답변완료

아무리 코드를 짜도 저장된 파워종목검색을 찾지 못하는지 파일 이름도 맞게 되었고 파워종목검색에서 저장 하였는데 해당 검색식을 찾지 못하네요 혹시 예스랭규ㅣ지로 만든 검색식을 파워종목에서 불러와서 저장해서 안될까요?



코드가 잘못되엇는지 봐주세요

/* [예스스팟 통합: 터틀 전략 - 검색식 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;

}



image.png

답변 1
프로필 이미지

예스스탁 예스스탁 답변

2026-02-20 13:35:12

안녕하세요 예스스탁입니다. 1 종목검색은 사용자검색조건명만 정확히 지정하시면 됩니다. var SearchName = "tur"; Main.ReqPowerSearch(SearchName); 올리신 수식에 tur로 정상적으로 지정이 되어 있습니다. 2 다만 수식을 작성하실때 이벤트명을 임의로 지정하시면 안됩니다. 종목검색 후에 발동되는 이벤트는 아래 이벤트입니다. function Main_OnRcvItemList(aItemList, nCount, aValues) 작성하신 수식에는 아래와 같이 알수 없는 내용으로 작성되어 있습니다. 스팟도움말에서 각 이벤트 설명 참고하셔서 변경학시기 바랍니다. function Main_OnRcvSearchResult(nCount) { 즐거운 하루되세요