커뮤니티
예스스팟 Q&A
답변완료
[예스스팟] 파워종목검색 결과값(aValues)에 검색식 계산값을 싣는 방법 문의
안녕하세요. 예스스팟 스크립트로 자동매매 엔진을 운용 중입니다.파워종목검색 결과를 스팟에서 받을 때, 검색식이 계산한 값을 함께 받는 방법을찾지 못해 문의드립니다.■ 목적 하나의 검색식 안에서 If ~ Else If 체인으로 Find(1) ~ Find(13)을 나눠 호출하고 있습니다. 스팟 엔진에서 "이 종목이 몇 번 조건으로 걸렸는지"를 알아야 종목별로 다른 매매 전략(진입 비중, 손절폭, 트레일링)을 적용할 수 있습니다.■ 현재 구성 [3202] 파워종목검색 사용자검색조건 등록 내용 A. [순위 검색] 설정조건에서 [거래량] [상위] 순으로 [300] 종목검색 B. [순위 검색] 설정조건에서 [거래대금] [상위] 순으로 [300] 종목검색 C. [가격대별 주가] 가격대 [2,000] ~ [500,000] E. [차트 Fire+ASGMA(...)] 검색어 ← 예스랭귀지로 작성한 지표 검색식 조합식 : (A or B) and C and E■ 확인된 동작 스팟에서 Main_OnRcvItemList(aItemList, nCount, aValues)로 정상 수신됩니다. (인자 3개 수신 확인, aValues.length == nCount 일치) aValues[i] 가 "1,1,1,0" 형태의 쉼표 결합 문자열로 옵니다. 하루치 608건을 전수 확인한 결과 세 가지 패턴만 나왔습니다. "1,1,1,0" 426건 "0,1,1,0" 125건 "1,0,1,0" 57건 앞 세 자리는 A, B, C 조건과 정확히 대응합니다. · 세 번째 자리(C 가격대)는 항상 1 · 첫째·둘째(A, B) 중 최소 하나는 항상 1 — 조합식 (A or B)와 일치 · 둘 다 1인 경우가 다수, 한쪽만 1인 경우가 소수 그런데 네 번째 자리(E 지표 검색식)는 항상 0입니다. 조합식이 "and E" 이므로 E가 거짓이면 그 종목은 검색되지 않아야 하는데, 검색은 정상적으로 되면서 값만 0으로 옵니다.■ 시도한 것 1) 검색식에 Var : FindTag(0); 를 선언하고 각 분기에서 값을 대입한 뒤 마지막 줄에 FindTag; 를 두었습니다. → aValues 해당 자리 계속 0 2) 변수 문제인지 확인하기 위해 마지막 줄을 상수 7; 로 바꿨습니다. → 조건 삭제 후 재등록, 엔진 재기동까지 하고 353건을 확인했으나 해당 자리는 여전히 0이었습니다. 즉 변수 값이나 대입 시점의 문제가 아니라, 지표 검색식이 계산한 값이 aValues로 전달되는 경로 자체가 없는 것으로 보입니다.■ 질문 1) 지표 검색식(예스랭귀지)에서 계산한 숫자를 aValues로 내보내려면 어떤 문법을 써야 합니까? (전용 함수가 있는지, 특정 변수명 규칙이 있는지, 또는 [3202] 탭 설정에서 결과값 컬럼을 지정해야 하는지) 2) aValues의 각 원소가 쉼표 결합 문자열인 것이 정상 규격입니까? 슬롯 순서는 조건 등록 순서(A, B, C, E)와 항상 일치합니까? 3) 위 방법이 없다면, 검색식에서 호출한 Find(n)의 n 값을 스팟에서 받을 수 있는 다른 방법이 있습니까? (없다면 검색식을 조건별로 나눠 등록하는 방식 외에 권장하시는 구조가 있는지도 알려주시면 감사하겠습니다.)[SEARCH_SHAPE] 검색콜백 원형 | argc:3 n:6 list[0] type:string val:036710 | values:있음 len:6 values[0] type:string val:1,1,1,0감사합니다.
2026-09-02
123
글번호 233464
답변완료
선물에서 난 신호로 옵션에 적용하기
선물 시스템식이 신호가 나면 지정된 옵션프리미엄을 정하고 거기에 가장 가까운 값을 내는 식을 예스스팟편집기로 만들었는데 작동을 하지 않습니다.살펴봐 주세요/ ====================================================================// ★ [사용자 지정 변수 설정 (Input 값)] ★// ====================================================================var TargetPremium = 1.5; // ?? 원하는 옵션 기준 가격 (예: 1.5)var MyVolume = 1; // ?? 진입할 고정 계약수var CallTargetIdx = 1100.0; // ?? 콜옵션 매수 후, '선물 가격'이 이 수치 이상으로 올라가면 익절 청산!var PutTargetIdx = 1000.0; // ?? 풋옵션 매수 후, '선물 가격'이 이 수치 이하로 내려가면 익절 청산!// ====================================================================function Main_OnStart(){ Main.MessageLog("★ [선물 지수 기준 위클리 옵션 실시간 익절 시스템] 가동 ★"); Main.MessageLog("설정 프리미엄: " + TargetPremium + " / 콜익절선물가: " + CallTargetIdx + " / 풋익절선물가: " + PutTargetIdx);}// 옵션의 가격대에 맞게 3호가 단위 값을 자동으로 계산해주는 함수function GetThreeTicks(currentPrice){ if (currentPrice >= 3.00) { return 0.15; } else { return 0.03; }}// 지정한 프리미엄에 가장 가까운 콜옵션 코드를 찾는 함수function GetNearPriceCallCode(){ var minDiff = 9999; var bestCode = ""; for (var i = -10; i <= 10; i++) { var code = Option1.GetATMCallCode(i); var price = Option1.GetCurrent(code); if (price > 0) { var diff = Math.abs(price - TargetPremium); if (diff < minDiff) { minDiff = diff; bestCode = code; } } } return bestCode;}// 지정한 프리미엄에 가장 가까운 풋옵션 코드를 찾는 함수function GetNearPricePutCode(){ var minDiff = 9999; var bestCode = ""; for (var i = -10; i <= 10; i++) { var code = Option1.GetATMPutCode(i); var price = Option1.GetCurrent(code); if (price > 0) { var diff = Math.abs(price - TargetPremium); if (diff < minDiff) { minDiff = diff; bestCode = code; } } } return bestCode;}// [핵심] 차트의 주가 데이터(선물 현재가)가 실시간으로 수신될 때마다 1초에 수십 번씩 호출되는 함수function Chart1_OnJuGaDataRecv(ChartEx){ // 현재 실시간 코스피 200 선물 가격을 가져옵니다. var CurrentFuturePrice = Chart1.GetClose(1, 0); // 1. 콜옵션 실시간 선물 지수 익절 감시 var TargetCallCode = GetNearPriceCallCode(); Account1.SetBalanceItem(TargetCallCode, 0); if (Account1.Balance.count > 0) // 현재 계좌에 콜옵션 잔고가 있을 때만 감시 { // 실시간 선물 지수가 설정해 둔 콜 익절 목표가보다 커지면 즉시 청산! if (CurrentFuturePrice >= CallTargetIdx) { var currentPrice = Option1.GetCurrent(TargetCallCode); var OrderPrice = currentPrice - GetThreeTicks(currentPrice); // -3호가 아래로 던짐 Account1.OrderSell(TargetCallCode, Account1.Balance.count, OrderPrice, 0); Main.MessageLog("?? [선물 지수 콜 익절 도달!] 선물가: " + CurrentFuturePrice + " -> 콜옵션 전량 익절 청산 완료"); } } // 2. 풋옵션 실시간 선물 지수 익절 감시 var TargetPutCode = GetNearPricePutCode(); Account1.SetBalanceItem(TargetPutCode, 0); if (Account1.Balance.count > 0) // 현재 계좌에 풋옵션 잔고가 있을 때만 감시 { // 실시간 선물 지수가 설정해 둔 풋 익절 목표가보다 작아지면 즉시 청산! if (CurrentFuturePrice <= PutTargetIdx) { var currentPrice = Option1.GetCurrent(TargetPutCode); var OrderPrice = currentPrice - GetThreeTicks(currentPrice); // -3호가 아래로 던짐 Account1.OrderSell(TargetPutCode, Account1.Balance.count, OrderPrice, 0); Main.MessageLog("?? [선물 지수 풋 익절 도달!] 선물가: " + CurrentFuturePrice + " -> 풋옵션 전량 익절 청산 완료"); } }}// Chart1(선물 차트)에서 시스템 신호가 발생할 때 실행되는 함수 (진입 및 일반 청산용)function Chart1_OnRiseSignal(Signal){ // 1. 선물 매수 신호 (Buy) 발생 시 -> 콜옵션 추격 매수 if (Signal.signalKind == 1) { var TargetCallCode = GetNearPriceCallCode(); var currentPrice = Option1.GetCurrent(TargetCallCode); if (TargetCallCode != "") { var OrderPrice = currentPrice + GetThreeTicks(currentPrice); Account1.OrderBuy(TargetCallCode, MyVolume, OrderPrice, 0); Main.MessageLog(">> 위클리 콜 자동 발굴 매수: " + TargetCallCode + " (주문가: " + OrderPrice + ")"); } } // 2. 선물 매수청산 신호 (ExitLong) 발생 시 -> 보유 콜옵션 일반 전량 청산 if (Signal.signalKind == 2) { var TargetCallCode = GetNearPriceCallCode(); Account1.SetBalanceItem(TargetCallCode, 0); if (Account1.Balance.count > 0) { var currentPrice = Option1.GetCurrent(TargetCallCode); var OrderPrice = currentPrice - GetThreeTicks(currentPrice); Account1.OrderSell(TargetCallCode, Account1.Balance.count, OrderPrice, 0); Main.MessageLog(">> 선물 시스템 신호에 의한 콜 청산완료: " + TargetCallCode); } } // 3. 선물 매도 신호 (Sell) 발생 시 -> 풋옵션 추격 매수 if (Signal.signalKind == 3) { var TargetPutCode = GetNearPricePutCode(); var currentPrice = Option1.GetCurrent(TargetPutCode); if (TargetPutCode != "") { var OrderPrice = currentPrice + GetThreeTicks(currentPrice); Account1.OrderBuy(TargetPutCode, MyVolume, OrderPrice, 0); Main.MessageLog(">> 위클리 풋 자동 발굴 매수: " + TargetPutCode + " (주문가: " + OrderPrice + ")"); } } // 4. 선물 매도청산 신호 (ExitShort) 발생 시 -> 보유 풋옵션 일반 전량 청산 if (Signal.signalKind == 4) { var TargetPutCode = GetNearPricePutCode(); Account1.SetBalanceItem(TargetPutCode, 0); if (Account1.Balance.count > 0) { var currentPrice = Option1.GetCurrent(TargetPutCode); var OrderPrice = currentPrice - GetThreeTicks(currentPrice); Account1.OrderSell(TargetPutCode, Account1.Balance.count, OrderPrice, 0); Main.MessageLog(">> 선물 시스템 신호에 의한 풋 청산완료: " + TargetPutCode); } }}
2026-08-26
116
글번호 233392
답변완료
예스차트
예스차트[6100]에서 KP200 선물연결의 주간+야간 '복합' 시뮬레이션 분봉을 조회하려면 어떻게 설정하나요? 현재 [6100] KP200 선물연결 5분봉에는 주간장만 표시되고, 차트 속성에도 주간/야간/복합 선택항목이 보이지 않습니다.
2026-08-25
130
글번호 233373
gip07102 님에 의해서 삭제되었습니다.
2026-08-19
18
글번호 233303
불그래 님에 의해서 삭제되었습니다.
2026-08-18
30
글번호 233296
불그래 님에 의해서 삭제되었습니다.
2026-08-18
1
글번호 233295
관리자에 의해 예스랭귀지 QnA로 이동되었습니다.
2026-08-14
56
글번호 233247
답변완료
문의 드립니다.
나무증권에서 실시간으로 검색되는 종목을 자동으로 매매할 수 있도록 예스스팟을 이용하고자 하는데 제가 실력이 모자라서 원격으로 부탁을 드리고자 합니다.다음은 AI가 알려준 방법인데 할 줄 몰라 부탁드립니다. 전화주시면 감사하겠습니다. 010-9732-0530 김현배.나무증권 HTS(1951)에서 실시간으로 포착된 종목을 예스트레이더의 시스템 전략과 연동하여 자동으로 매매하는 가장 정석적이고 강력한 방법은 예스트레이더 내의 예스스팟(YesSpot) 기능을 이용하는 것입니다.나무 HTS의 조건검색 엔진과 예스트레이더를 연결하여 자동매매를 완성하는 구체적인 실행 방법은 다음과 같습니다.핵심 연동 원리나무 HTS(또는 예스트레이더 내장 파워종목검색)에 동일한 조건식을 미리 저장해 둔 뒤, 예스스팟(JavaScript)에서 해당 조건식을 주기적으로 호출합니다. 조건에 맞는 종목이 포착되면 예스스팟이 이를 감지하여 방금 만드신 수정 전략의 매수/물타기/손절 로직에 따라 자동으로 주문을 집행합니다.단계별 구현 방법1단계: 예스트레이더(또는 NH트레이더)에 동일한 조건식 저장하기나무 HTS [1950] 화면에서 사용 중인 조건식을 예스트레이더(또는 연동된 HTS)의 파워종목검색 메뉴에도 똑같이 작성한 후 서버에 저장합니다. (예스스팟 스크립트가 이 저장된 이름을 호출하여 종목을 가져오게 됩니다.)2단계: 예스스팟 편집기에서 스크립트 작성하기예스트레이더에서 [예스스팟] 창을 엽니다.새 자바스크립트(JS) 스크립트를 생성하고, 다음과 같은 흐름의 코드를 구성합니다:타이머 설정: 예를 들어 5초 또는 10초 주기로 타이머를 설정해 장중에 계속해서 조건검색을 실행하도록 만듭니다.종목검색 요청 함수 연동: 예스스팟의 종목검색 객체를 이용해 저장해 둔 조건식 이름을 호출합니다.전략 매칭 및 주문 집행: 검색된 종목 리스트가 넘어오면, 각 종목별로 차트 객체나 주문 객체(Account.OrderBuy)를 연결하여 앞서 완성한 매수 및 물타기, 제비용 마진 조건에 맞춰 자동으로 주문이 들어가도록 제어합니다.3단계: 스팟 실행 및 실전 가동작성한 자바스크립트 코드의 오류 검증(컴파일)을 마치고 스팟 실행 버튼을 누릅니다.장이 시작되면 나무 HTS 화면처럼 예스스팟이 백그라운드에서 실시간으로 조건검색을 수행하며 포착된 종목에 대해 자동으로 계좌 주문을 넣기 시작합니다.
2026-08-13
198
글번호 233236
답변완료
dmp 파일 문의드립니다.
[문의] 나스닥/SP500/골드 분·틱 6개 스크립트 동시 실행 시 약 30분 경과 지점 다운 - 크래시 덤프 분석 결과 첨부■ 증상ReqChartEx 요청 → 응답 → RemoveObject 지연삭제 → 다음 타임프레임 요청, 이 루프를분봉(1~110분) / 틱봉(30~1000틱) 전체 타임프레임에 대해 페이싱 0~1000ms로 끝없이 순환.나스닥(NQU26), SP500(ESU26), Gold(GCZ26) 종목마다 분/틱 파일로 나눠 총 6개 파일을 동시실행하면 약 30분 경과 시점에 프로그램이 다운됩니다.■ 크래시 덤프(.dmp) 분석 결과 (직접 파싱해서 확인한 사실)- 예외 코드: 0xC0000005 (ACCESS_VIOLATION)- 접근 종류: 읽기(read) 시도, 대상 주소 = 0x0 (널 포인터)- 크래시 발생 위치: SystemTrading.dll 모듈 내부, 오프셋 0x3D65D- 크래시 순간 레지스터: EAX=0, EBX=0, ECX=0, EDX=0 (ECX는 x86 MSVC에서 보통 this 포인터를 담는 레지스터라, 이미 유효하지 않은 객체에 대해 멤버함수를 호출하려다 발생한 크래시로 보입니다.)- 크래시 지점 직전 스택(리턴주소 후보): YesChartLibrary.dll, YesSystemChart.dll (둘 다 차트 관련 DLL로, 차트 객체 처리 도중 SystemTrading.dll로 진입해 크래시)■ 저희 쪽에서 자체 점검한 내용- ReqChartEx 응답을 받은 뒤 RemoveObject로 삭제하는 구조에서, 삭제 타이머와 다음 요청 타이머가 동시에 도는 구간이 있어 이론상 삭제 전에 객체가 재할당될 수 있는 구조적 문제를 발견하여 큐(대기열) 방식으로 수정, 삭제 성공/실패 여부와 누적 생성-삭제 카운트를 로그로 추적하도록 진단 스크립트를 개선해 재현 테스트 중입니다.- 다운 직전 로그에서 특정 응답이 7초 이상 지연되는 현상(SLOW_RESPONSE)도 함께 확인되어, 응답 지연과 크래시 사이의 연관 가능성도 의심하고 있습니다.■ 문의드리고 싶은 부분1. SystemTrading.dll+0x3D65D 부근에서 차트 객체(ChartEx)를 참조하는 코드 중, 객체가 삭제되었거나 유효하지 않을 때 널 체크 없이 접근하는 구간이 있는지 내부적으로 확인 가능하신지요.2. 다중 종목(6개 파일)에서 ReqChartEx를 짧은 주기로 반복 호출할 때, 엔진 내부에 차트 객체 핸들 개수 제한이나 동시 요청 제한이 있는지, 있다면 권장 상한값을 안내해주실 수 있는지요.3. RemoveObject 호출 시 이벤트 핸들러(OnRcvChartEx) 내부가 아닌 별도 타이머에서 지연 삭제하는 저희 방식 자체가 엔진 설계상 안전한지, 혹은 권장되는 다른 삭제 시점/방식이 있는지 안내 부탁드립니다.첨부: eBestYesTraderRun_26_08_10_20_30_11.dmp
2026-08-10
154
글번호 233205
답변완료
프로그램 다운 문의 2
약간 다른 방식의 실행파일입니다. 마찬가지로 3개 정도는 잘 다운이 안되는데 4개부터는 30분정도 되면 다운됩니다.방식 : 워밍업이 끝나면 최대 208개 차트객체를 세션 내내 동시 보유하고, Main_OnBarAppended로 실시간 봉을 받는 구조입니다. 여기에 3종목을 동시에 돌리면 최대 624개 객체가 동시에 떠 있게 됩니다. 뭐가 문제가 있는건지 확인 부탁드립니다.// [2안 진단본 - 예스스팟 문의용 최소 구조]function Main_OnStart(){ // 타임프레임 목록(분봉110+틱봉98=208개) 순서대로 워밍업 요청 시작 processNext();}function processNext(){ var ChartSet = new ReqChartItem(MARKET_DATA_CODE); ChartSet.code = MARKET_DATA_CODE; ChartSet.period = CHART_PERIOD_MINUTE; // 또는 CHART_PERIOD_TICK ChartSet.cycle = 현재타임프레임; ChartSet.count = 워밍업봉수; // 큰 창(최대 4000) Main.ReqChartEx(ChartSet);}function Main_OnRcvChartEx(ChartEx){ // [1안과의 핵심 차이] 여기서 삭제하지 않고 계속 들고 있음 chartObjs[현재타임프레임라벨] = ChartEx; processNext(); // 다음 타임프레임 워밍업으로. 208개 끝나면 워밍업 종료.}function Main_OnBarAppended(ChartEx, nData){ // [2안 핵심] 보유중인 208개 차트객체 중 하나에서 새 봉이 완성될 때마다 // 예스스팟이 자동으로 호출 - 별도 재요청/폴링 없이 실시간 감지 var 라벨 = ChartEx에 매칭되는 타임프레임 찾기; var high = ChartEx.GetHigh(nData, 1); var low = ChartEx.GetLow(nData, 1); // (신호계산 없이 수신만 확인)}// [부가기능] 30분마다 "임시" 차트객체를 하나 더 받아서(원본은 안 건드림)// 최신 데이터로 대조하고, 그 임시객체만 지연삭제 - 온/오프 가능function attemptRefresh(){ var TempChartSet = new ReqChartItem(MARKET_DATA_CODE); TempChartSet.code = MARKET_DATA_CODE; TempChartSet.cycle = 대상타임프레임; Main.ReqChartEx(TempChartSet); // 응답 오면 대조 후 임시객체만 RemoveObject}
2026-08-10
164
글번호 233203