예스스탁
예스스탁 답변
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);
}
}
}