커뮤니티

자동종목검색 매수식에 매도식 추가 부탁드려요

프로필 이미지
dedoyes
2025-09-08 22:05:27.0
73
글번호 226387
답변완료
스팟 입문자이오니 양해바랍니다. 스팟언어로 자동 종목검색, 매수하는 코드는 찾았고 정상작동했습니다. 스탑주문의 매도 외 필요한 사항이 있어 위 종목검색 및 매수식에 추가하고 싶은데 어제의 고가, 저가, 시가, 종가 본 커뮤니티 문답을 좀 찾았고 객체 언급하셔서 직접 좀 실습처럼 뒤적거리니 종목을 특정하는 듯 보였고 (오해일 듯 합니다만) 종목 특정 아니고 자동종목으로 매수된 종목에 대하여 어제의 저가 이탈시 매도식 등을 추가하고 싶습니다. 입문자 실력없어 부록은 스팟교육자료 발췌했습니다. 부록 코드에 1. 어제 저가 이탈시 매도 2. 15:15 당일청산 3. 익절 및 손절 청산 추가해 주시기를 정중히 꼭 부탁드립니다. 부록: var timerInterval = 5; // 5초 타이머 간격(매 5초마다 특정 작업을 수행하도록 설정) var 매수금 = 30000; // 추매수할 금액(추가 매수 금액) // 종목검색 후 종목객체 요청할 종목코드를 저장할 배열변수 var MKList = []; // 검색 결과로 나온 종목코드를 저장할 배열 // 종목객체가 만들어진 순서대로 종목객체를 저장할 변수 var MK = []; // 실제 종목객체(MarketData)들이 담길 배열 // 종목객체 요청 카운트 변수 var req; // MKList에서 몇 번째 종목을 요청 중인지 나타내는 인덱스 function Main_OnStart() { var d = new Date(); // 현재 시간 객체 생성 HHMMSS = d.getHours()*10000 + d.getMinutes()*100 + d.getSeconds(); // HHMMSS 형태로 시분초 계산 Main.MessageList(HHMMSS,"|Start"); // 예스스팟 디버깅창에 로그 출력 Main.SetTimer(1, timerInterval*1000); // 1번 타이머를 (5초 * 1000) = 5000ms 간격으로 설정 } function Main_OnTimer(nEventID) { var d = new Date(); // 타이머가 호출될 때마다 현재 시간 다시 계산 HHMMSS = d.getHours()*10000 + d.getMinutes()*100 + d.getSeconds(); // HHMMSS 형태로 시분초 계산 // nEventID가 1번이고, 현재 시각이 09시00분00초(=90000) 이후라면 종목검색 요청 if (nEventID == 1 && HHMMSS >= 90000) { Main.MessageList(HHMMSS,"|종목검색요청"); // 종목검색을 요청한다는 로그 출력 /********* -------------- *********/ Main.ReqPowerSearch("이평선크로스"); // "super search"라는 사용자 검색식으로 종목검색 요청 /********* -------------- *********/ } // nEventID가 2번이면, 종목객체 재요청 로직 수행 if (nEventID == 2) { Main.KillTimer(2); // 2번 타이머 중지 Main.MessageList(HHMMSS,"|종목객체재요청"); // 종목객체 재요청 로그 Main.ReqMarketData(MKList[req]); // req 인덱스에 해당하는 종목코드를 재요청 } } function Main_OnRcvItemList(aItemList, nCount) { var d = new Date(); // 현재 시간 객체 생성 HHMMSS = d.getHours()*10000 + d.getMinutes()*100 + d.getSeconds(); // HHMMSS 형태로 시분초 계산 Main.KillTimer(1); // 1번 타이머 중지(연속 검색 방지 등을 위해) Main.MessageList(HHMMSS,"|종목검색완료|검색된종목수:", nCount); // 검색 종목 수 로그 MKList = []; // MKList 초기화 // 검색 결과가 1개 이상이면 if (nCount > 0) { // 아직 매수된 종목객체(MK)가 전혀 없는 경우 if (MK.length == 0) { // 결과 전체를 MKList에 저장 MKList = aItemList; } else { // 이미 매수된 종목이 있을 경우에는 중복되지 않는 종목만 MKList에 추가 for (var a = 0; a < nCount; a++) { var Add = true; for (var b = 0; b < MK.length; b++) { // 이미 MK에 있는 종목이면 Add를 false로 if (aItemList[a] == MK[b].code) { Add = false; } } // 중복되지 않을 때만 MKList에 push if (Add == true) { MKList.push(aItemList[a]); } } } Main.MessageList(HHMMSS,"|요청할 종목객체수:",MKList.length); // 실제로 요청할 종목 수 로그 } // 새로 요청할 종목이 없다면(=MKList.length==0), 1번 타이머 재설정(다음 검색 대기) if (MKList.length == 0) { Main.SetTimer(1, timerInterval*1000); } else { // 새로 요청할 종목이 있으면 req=0부터 시작해서 MarketData 요청 req = 0; Main.MessageList(HHMMSS,"|종목객체요청",MKList[req]); // 첫 번째 종목 요청 로그 Main.ReqMarketData(MKList[req]); // 실제 종목객체 생성 요청 } } function Main_OnRcvMarketData(MarketData) { var d = new Date(); // 현재 시간 객체 HHMMSS = d.getHours()*10000 + d.getMinutes()*100 + d.getSeconds(); // HHMMSS 형태로 시분초 계산 // 수신된 MarketData 객체의 code가 현재 요청중인 MKList[req]와 같다면 if (MarketData.code == MKList[req]) { Main.MessageList(HHMMSS,"|종목객체생성",MarketData.code); // 종목객체 생성 로그 Account1.OrderBuy(MarketData.code, Math.floor(매수금 / MarketData.Ask(2)), MarketData.Ask(2), 0); //Main.MessageList(HHMMSS,"|매수주문",MarketData.code,MarketData.Ask(3)); // 매수 주문 로그 Main.MessageList(HHMMSS,"|매수주문",MarketData.code,MarketData.Close); // 해당 종목의 종목객체를 MK 배열에 추가 MK.push(MarketData); // 다음 종목 요청 인덱스를 1 증가 req = req + 1; // 아직 요청할 종목이 남아 있다면 if (req < MKList.length) { Main.MessageList(HHMMSS,"|종목객체요청",MKList[req]); // 다음 종목 요청 로그 var S = Main.ReqMarketData(MKList[req]); // 다음 종목 요청 // 15초에 60번 이상 요청하면 시간제한(-1) 받을 수 있음 if (S == -1) { // 제한에 걸리면 2번 타이머를 15초 후로 설정하여 재시도 Main.MessageList(HHMMSS,"|종목객체생성 15초제한"); Main.SetTimer(2, 15000); } } else { // 모든 종목객체를 요청 끝냈을 때 Main.MessageList(HHMMSS,"|종목객체생성끝"); // 다시 1번 타이머(검색)를 5초 간격으로 재시작 Main.SetTimer(1, timerInterval*1000); } } }
답변 1
프로필 이미지

예스스탁 예스스탁 답변

2025-09-16 09:54:16.0

안녕하세요 예스스탁입니다. 아래식 참고하시기 바랍니다. var timerInterval = 5; // 5초 타이머 간격(매 5초마다 특정 작업을 수행하도록 설정) var 매수금 = 30000; // 추매수할 금액(추가 매수 금액) // 종목검색 후 종목객체 요청할 종목코드를 저장할 배열변수 var MKList = []; // 검색 결과로 나온 종목코드를 저장할 배열 // 종목객체가 만들어진 순서대로 종목객체를 저장할 변수 var MK = []; // 실제 종목객체(MarketData)들이 담길 배열 // 종목객체 요청 카운트 변수 var req; // MKList에서 몇 번째 종목을 요청 중인지 나타내는 인덱스 var 매도감시타이머 = 1; var 손절 = -10;//% var 익절 = 10;//% function Main_OnStart() { var d = new Date(); // 현재 시간 객체 생성 HHMMSS = d.getHours()*10000 + d.getMinutes()*100 + d.getSeconds(); // HHMMSS 형태로 시분초 계산 Main.MessageList(HHMMSS,"|Start"); // 예스스팟 디버깅창에 로그 출력 Main.SetTimer(1, timerInterval*1000); // 1번 타이머를 (5초 * 1000) = 5000ms 간격으로 설정 //손익체크 타이머 Main.SetTimer(99, 매도감시타이머*1000); // 99번 타이머를 (1초 * 1000) = 1000ms 간격으로 설정 } function Main_OnTimer(nEventID) { var d = new Date(); // 타이머가 호출될 때마다 현재 시간 다시 계산 HHMMSS = d.getHours()*10000 + d.getMinutes()*100 + d.getSeconds(); // HHMMSS 형태로 시분초 계산 // nEventID가 1번이고, 현재 시각이 09시00분초~15시15분 전까지 종목검색 요청 if (nEventID == 1 && HHMMSS >= 90000 && HHMMSS < 151500) { Main.MessageList(HHMMSS,"|종목검색요청"); // 종목검색을 요청한다는 로그 출력 /********* -------------- *********/ Main.ReqPowerSearch("이평선크로스"); // "super search"라는 사용자 검색식으로 종목검색 요청 /********* -------------- *********/ } //99번 타이머, 9시 ~ 15시 15분 사이이고 매수종목 1개 이상 if (nEventID == 99 && HHMMSS >= 90000 && HHMMSS < 151500 && MK.length >= 1) { //매수종목 순차적으로 잔고 셋팅해서 for (var i=0; i < MK.length; i++) { Account1.SetBalance(MK[i].code); if (Account1.Balance.count > 0) { //익절조건 충족하면 매도 if(MK[i].current >= Account1.Balance.avgUnitCost*(1+익절/100)) { Main.MessageList(HHMMSS,"|익절발생:",Account1.Balance.code,"현재가:",MK[i].current,"평단가:",Account1.Balance.avgUnitCost); Account1.OrderSell(Account1.Balance.code, Account1.Balance.count, 0, 1); } //손절조건 충족하면 매도 if( MK[i].current >= Account1.Balance.avgUnitCost*(1+손절/100)) { Main.MessageList(HHMMSS,"|손절발생:",Account1.Balance.code,"현재가:",MK[i].current,"평단가:",Account1.Balance.avgUnitCost); Account1.OrderSell(Account1.Balance.code, Account1.Balance.count, 0, 1); } //전일저가이하이면 매도 if(MK[i].current <= MK[i].GetPrevLow(1)) { Main.MessageList(HHMMSS,"|전일저가이하:",Account1.Balance.code,"현재가:",MK[i].current,"전일저가:",MK[i].GetPrevLow(1)); Account1.OrderSell(Account1.Balance.code, Account1.Balance.count, 0, 1); } } } } if (nEventID == 99 && HHMMSS >= 151500) { //종목검색, 손익체크 타이머 모두 중지 Main.KillTimer(1); Main.KillTimer(99); Main.MessageList(HHMMSS,"|당일청산"); for(var i=0; i 0) { Account1.OrderSell(Account1.Balance.code, Account1.Balance.count, 0,1); } } } // nEventID가 2번이면, 종목객체 재요청 로직 수행 if (nEventID == 2) { Main.KillTimer(2); // 2번 타이머 중지 Main.MessageList(HHMMSS,"|종목객체재요청"); // 종목객체 재요청 로그 Main.ReqMarketData(MKList[req],1); // req 인덱스에 해당하는 종목코드를 재요청(전일저가를 알기위해 일간데이터도 1개 추가 요청) } } function Main_OnRcvItemList(aItemList, nCount) { var d = new Date(); // 현재 시간 객체 생성 HHMMSS = d.getHours()*10000 + d.getMinutes()*100 + d.getSeconds(); // HHMMSS 형태로 시분초 계산 Main.KillTimer(1); // 1번 타이머 중지(연속 검색 방지 등을 위해) Main.MessageList(HHMMSS,"|종목검색완료|검색된종목수:", nCount); // 검색 종목 수 로그 MKList = []; // MKList 초기화 // 검색 결과가 1개 이상이면 if (nCount > 0) { // 아직 매수된 종목객체(MK)가 전혀 없는 경우 if (MK.length == 0) { // 결과 전체를 MKList에 저장 MKList = aItemList; } else { // 이미 매수된 종목이 있을 경우에는 중복되지 않는 종목만 MKList에 추가 for (var a = 0; a < nCount; a++) { var Add = true; for (var b = 0; b < MK.length; b++) { // 이미 MK에 있는 종목이면 Add를 false로 if (aItemList[a] == MK[b].code) { Add = false; } } // 중복되지 않을 때만 MKList에 push if (Add == true) { MKList.push(aItemList[a]); } } } Main.MessageList(HHMMSS,"|요청할 종목객체수:",MKList.length); // 실제로 요청할 종목 수 로그 } // 새로 요청할 종목이 없다면(=MKList.length==0), 1번 타이머 재설정(다음 검색 대기) if (MKList.length == 0) { Main.SetTimer(1, timerInterval*1000); } else { // 새로 요청할 종목이 있으면 req=0부터 시작해서 MarketData 요청 req = 0; Main.MessageList(HHMMSS,"|종목객체요청",MKList[req]); // 첫 번째 종목 요청 로그 Main.ReqMarketData(MKList[req],1); // 실제 종목객체 생성 요청(전일저가를 알기위해 일간데이터도 1개 추가 요청) } } function Main_OnRcvMarketData(MarketData) { var d = new Date(); // 현재 시간 객체 HHMMSS = d.getHours()*10000 + d.getMinutes()*100 + d.getSeconds(); // HHMMSS 형태로 시분초 계산 // 수신된 MarketData 객체의 code가 현재 요청중인 MKList[req]와 같다면 if (MarketData.code == MKList[req]) { Main.MessageList(HHMMSS,"|종목객체생성",MarketData.code); // 종목객체 생성 로그 Account1.OrderBuy(MarketData.code, Math.floor(매수금 / MarketData.Ask(2)), MarketData.Ask(2), 0); //Main.MessageList(HHMMSS,"|매수주문",MarketData.code,MarketData.Ask(3)); // 매수 주문 로그 Main.MessageList(HHMMSS,"|매수주문",MarketData.code,MarketData.Close); // 해당 종목의 종목객체를 MK 배열에 추가 MK.push(MarketData); // 다음 종목 요청 인덱스를 1 증가 req = req + 1; // 아직 요청할 종목이 남아 있다면 if (req < MKList.length) { Main.MessageList(HHMMSS,"|종목객체요청",MKList[req]); // 다음 종목 요청 로그 var S = Main.ReqMarketData(MKList[req],1); // 다음 종목 요청(전일저가를 알기위해 일간데이터도 1개 추가 요청) // 15초에 60번 이상 요청하면 시간제한(-1) 받을 수 있음 if (S == -1) { // 제한에 걸리면 2번 타이머를 15초 후로 설정하여 재시도 Main.MessageList(HHMMSS,"|종목객체생성 15초제한"); Main.SetTimer(2, 15000); } } else { // 모든 종목객체를 요청 끝냈을 때 Main.MessageList(HHMMSS,"|종목객체생성끝"); // 다시 1번 타이머(검색)를 5초 간격으로 재시작 Main.SetTimer(1, timerInterval*1000); } } } 즐거운 하루되세요 > dedoyes 님이 쓴 글입니다. > 제목 : 자동종목검색 매수식에 매도식 추가 부탁드려요 > 스팟 입문자이오니 양해바랍니다. 스팟언어로 자동 종목검색, 매수하는 코드는 찾았고 정상작동했습니다. 스탑주문의 매도 외 필요한 사항이 있어 위 종목검색 및 매수식에 추가하고 싶은데 어제의 고가, 저가, 시가, 종가 본 커뮤니티 문답을 좀 찾았고 객체 언급하셔서 직접 좀 실습처럼 뒤적거리니 종목을 특정하는 듯 보였고 (오해일 듯 합니다만) 종목 특정 아니고 자동종목으로 매수된 종목에 대하여 어제의 저가 이탈시 매도식 등을 추가하고 싶습니다. 입문자 실력없어 부록은 스팟교육자료 발췌했습니다. 부록 코드에 1. 어제 저가 이탈시 매도 2. 15:15 당일청산 3. 익절 및 손절 청산 추가해 주시기를 정중히 꼭 부탁드립니다. 부록: var timerInterval = 5; // 5초 타이머 간격(매 5초마다 특정 작업을 수행하도록 설정) var 매수금 = 30000; // 추매수할 금액(추가 매수 금액) // 종목검색 후 종목객체 요청할 종목코드를 저장할 배열변수 var MKList = []; // 검색 결과로 나온 종목코드를 저장할 배열 // 종목객체가 만들어진 순서대로 종목객체를 저장할 변수 var MK = []; // 실제 종목객체(MarketData)들이 담길 배열 // 종목객체 요청 카운트 변수 var req; // MKList에서 몇 번째 종목을 요청 중인지 나타내는 인덱스 function Main_OnStart() { var d = new Date(); // 현재 시간 객체 생성 HHMMSS = d.getHours()*10000 + d.getMinutes()*100 + d.getSeconds(); // HHMMSS 형태로 시분초 계산 Main.MessageList(HHMMSS,"|Start"); // 예스스팟 디버깅창에 로그 출력 Main.SetTimer(1, timerInterval*1000); // 1번 타이머를 (5초 * 1000) = 5000ms 간격으로 설정 } function Main_OnTimer(nEventID) { var d = new Date(); // 타이머가 호출될 때마다 현재 시간 다시 계산 HHMMSS = d.getHours()*10000 + d.getMinutes()*100 + d.getSeconds(); // HHMMSS 형태로 시분초 계산 // nEventID가 1번이고, 현재 시각이 09시00분00초(=90000) 이후라면 종목검색 요청 if (nEventID == 1 && HHMMSS >= 90000) { Main.MessageList(HHMMSS,"|종목검색요청"); // 종목검색을 요청한다는 로그 출력 /********* -------------- *********/ Main.ReqPowerSearch("이평선크로스"); // "super search"라는 사용자 검색식으로 종목검색 요청 /********* -------------- *********/ } // nEventID가 2번이면, 종목객체 재요청 로직 수행 if (nEventID == 2) { Main.KillTimer(2); // 2번 타이머 중지 Main.MessageList(HHMMSS,"|종목객체재요청"); // 종목객체 재요청 로그 Main.ReqMarketData(MKList[req]); // req 인덱스에 해당하는 종목코드를 재요청 } } function Main_OnRcvItemList(aItemList, nCount) { var d = new Date(); // 현재 시간 객체 생성 HHMMSS = d.getHours()*10000 + d.getMinutes()*100 + d.getSeconds(); // HHMMSS 형태로 시분초 계산 Main.KillTimer(1); // 1번 타이머 중지(연속 검색 방지 등을 위해) Main.MessageList(HHMMSS,"|종목검색완료|검색된종목수:", nCount); // 검색 종목 수 로그 MKList = []; // MKList 초기화 // 검색 결과가 1개 이상이면 if (nCount > 0) { // 아직 매수된 종목객체(MK)가 전혀 없는 경우 if (MK.length == 0) { // 결과 전체를 MKList에 저장 MKList = aItemList; } else { // 이미 매수된 종목이 있을 경우에는 중복되지 않는 종목만 MKList에 추가 for (var a = 0; a < nCount; a++) { var Add = true; for (var b = 0; b < MK.length; b++) { // 이미 MK에 있는 종목이면 Add를 false로 if (aItemList[a] == MK[b].code) { Add = false; } } // 중복되지 않을 때만 MKList에 push if (Add == true) { MKList.push(aItemList[a]); } } } Main.MessageList(HHMMSS,"|요청할 종목객체수:",MKList.length); // 실제로 요청할 종목 수 로그 } // 새로 요청할 종목이 없다면(=MKList.length==0), 1번 타이머 재설정(다음 검색 대기) if (MKList.length == 0) { Main.SetTimer(1, timerInterval*1000); } else { // 새로 요청할 종목이 있으면 req=0부터 시작해서 MarketData 요청 req = 0; Main.MessageList(HHMMSS,"|종목객체요청",MKList[req]); // 첫 번째 종목 요청 로그 Main.ReqMarketData(MKList[req]); // 실제 종목객체 생성 요청 } } function Main_OnRcvMarketData(MarketData) { var d = new Date(); // 현재 시간 객체 HHMMSS = d.getHours()*10000 + d.getMinutes()*100 + d.getSeconds(); // HHMMSS 형태로 시분초 계산 // 수신된 MarketData 객체의 code가 현재 요청중인 MKList[req]와 같다면 if (MarketData.code == MKList[req]) { Main.MessageList(HHMMSS,"|종목객체생성",MarketData.code); // 종목객체 생성 로그 Account1.OrderBuy(MarketData.code, Math.floor(매수금 / MarketData.Ask(2)), MarketData.Ask(2), 0); //Main.MessageList(HHMMSS,"|매수주문",MarketData.code,MarketData.Ask(3)); // 매수 주문 로그 Main.MessageList(HHMMSS,"|매수주문",MarketData.code,MarketData.Close); // 해당 종목의 종목객체를 MK 배열에 추가 MK.push(MarketData); // 다음 종목 요청 인덱스를 1 증가 req = req + 1; // 아직 요청할 종목이 남아 있다면 if (req < MKList.length) { Main.MessageList(HHMMSS,"|종목객체요청",MKList[req]); // 다음 종목 요청 로그 var S = Main.ReqMarketData(MKList[req]); // 다음 종목 요청 // 15초에 60번 이상 요청하면 시간제한(-1) 받을 수 있음 if (S == -1) { // 제한에 걸리면 2번 타이머를 15초 후로 설정하여 재시도 Main.MessageList(HHMMSS,"|종목객체생성 15초제한"); Main.SetTimer(2, 15000); } } else { // 모든 종목객체를 요청 끝냈을 때 Main.MessageList(HHMMSS,"|종목객체생성끝"); // 다시 1번 타이머(검색)를 5초 간격으로 재시작 Main.SetTimer(1, timerInterval*1000); } } }