답변완료
자동종목검색 매수식에 매도식 추가 부탁드려요
스팟 입문자이오니 양해바랍니다.
스팟언어로 자동
종목검색, 매수하는 코드는 찾았고
정상작동했습니다.
스탑주문의 매도 외
필요한 사항이 있어
위 종목검색 및 매수식에 추가하고 싶은데
어제의 고가, 저가, 시가, 종가
본 커뮤니티 문답을 좀 찾았고
객체 언급하셔서
직접 좀 실습처럼 뒤적거리니
종목을 특정하는 듯 보였고 (오해일 듯 합니다만)
종목 특정 아니고
자동종목으로 매수된 종목에 대하여
어제의 저가 이탈시 매도식 등을
추가하고 싶습니다.
입문자 실력없어
부록은 스팟교육자료 발췌했습니다. 부록 코드에
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);
}
}
}
2025-09-08
205
글번호 226387
답변완료
예스스팟 스크립트 질문 드립니다.
수고하십니다.
예스스팟 자동매도로 수익이 실현되고 나서 같은날 그 종목이 다시 자동매수되는 경우가 있습니다.
예스스팟 시작후 자동매도됐던 종목은 재매수 하지 않는 부분을 자바스크립트로 만들수 있을까요.
현재 쓰고 있는 자바스크립트에는 보유하고 있는 종목을 재매수 하지 않는 부분은 구현이 되어 있습니다.
var timer5 = 3; // 3초
var 매수금 =100000 ;
var 손절 = 0.95;
var 익절 = 1.03;
var OrderList = [];
var MKList = [];
var req;
function Main_OnStart(){
Main.SetTimer(1, timer5*1000); // 1번 타이머 , 3초
MKList = []; //오늘 매수한 종목관리 배열 초기화
V1 =Account1.GetBalanceETCinfo(100); // 시작시 잔고 평가 금액
}
function Main_OnTimer(nEventID)
{
var d = new Date();
YYYYMMDD = d.getFullYear()* 10000 + (d.getMonth() +1)*100 + d.getDate();
HHMMSS = d.getHours()* 10000+ d.getMinutes()*100 + d.getSeconds();
if (nEventID==1 && HHMMSS>090000 && HHMMSS<151500 )
{
Main.ReqPowerSearch("필필필") // 종목검색수행
}
if (nEventID==1)
{
var num = Account1.GetTheNumberOfBalances(); // 계좌보유종수
if (nEventID==1 && HHMMSS>090000 && HHMMSS<151500 )
{ // 9시 ~ 15시 15분 사이
if(num >= 1)
{ // 보유종목이 1개 이상
if(Account1.GetBalanceETCinfo(100) >=V1*1.04)
{ //계좌평가금액이 스팟시작시 평가금액대비
Main.KillTimer(1); // 1번 타이머 종료
for (var i=0; i<num; i++)
{ //계좌리스트의 순서대로
Account1.SetBalance(i); //잔고를 세팅
if(Account1.Balance.count >0)
{
Account1.OrderSell(Account1.Balance.code, Account1.Balance.count, 0, 1);
}
}
}
else
{
for (var i=0; i<num; i++)
{
Account1.SetBalance(i);
if(Account1.Balance.current >= Account1.Balance.avgUnitCost*익절)
{
Account1.OrderSell(Account1.Balance.code, Account1.Balance.count, 0, 1);
}
}
}
}
}
if (HHMMSS >= 151500)
{
Main.KillTimer(1);
for(var i=0; i <num; i++)
{
Account1.SetBalance(i);
if(Account1.Balance.count>0)
{ Account1.OrderSell(Account1.Balance.code, Account1.Balance.count, 0,1);}
}
}
}
if(nEventID ==2){
Main.ReqMarketData(OrderList[req]);}
}
function Main_OnRcvItemList(aItemList, nCount)
{
Main.KillTimer(1);
OrderList = [];
if (nCount >=1 ){
if(MKList.length == 0){
OrderList = aItemList}
else{
for(var a =0; a<nCount; a++){
var Add = true;
for (var b=0; b<MKList.length; b++){
if(aItemList[a]==MKList[b].code){
Add = false;}
}
if(Add==true && !IsStockInAccount(aItemList[a])){
OrderList.push(aItemList[a]);}
}
}
}
if(OrderList.length==0){
Main.SetTimer(1, timer5*1000);}
else{
req = 0;
Main.ReqMarketData(OrderList[req]);}
}
function Main_OnRcvMarketData(MarketData){
if( MarketData.code == OrderList[req]){
MKList.push(MarketData);
//계좌에 같은 종목 있는지 확인하고 없는 경우만 매수
if(!IsStockInAccount(MarketData.code)){
// Account1.OrderBuy(MarketData.code,1,0,1); // 시장가 한주를 주문한다.
// 지정가로 주문하고자 할때는 아래로 변경
Account1.OrderBuy(MarketData.code,Math.floor(매수금/MarketData.Ask(1)),0,1);
//Account1.OrderBuy(MarketData.code,Math.floor(매수금/MarketData.Ask(1)),MarketData.Ask(1),0);
Main.MessageList(MarketData.code + "주식을 매수합니다");}
else{ Main.MessageList(MarketData.code + "주식을 매수 안 합니다");}
req = req+1;
if(req<OrderList.length){
var aa = Main.ReqMarketData(OrderList[req]);
if( aa = -1 ){Main.SetTimer(2, 15000);}}
else{Main.SetTimer(1, timer5*1000);}
}
}
//계좌에 같은 종목이 있는지 확인
function IsStockInAccount(stockCode){
var numberOfBalances = Account1.GetTheNumberOfBalances();
for (var i = 0; i <numberOfBalances; i++){
Account1.SetBalance(i);
if(stockCode == Account1.Balance.code){return true;} // 계좌에 같은 종목이 있으면 트루 반환
}
return false; // 계좌에 같은 종목이 없으면 폴스 반환
}
2025-09-03
195
글번호 226384
답변완료
3:40-4:00 시간외종가 주문
Account1.OrderBuy(MarketData.code, Math.floor(매수금 / MarketData.Close), MarketData.Close, 12);
이렇게 자동주문 예스스팟 나갔는데 "주문단가 잘못입력" 오류안내 메시지인데 뭐가 잘못되었는지 검토 및 수정 부탁드립니다..
추가 참조:
Account1.OrderBuy(MarketData.code, Math.floor(매수금 / MarketData.Close), 0, 12);으로 바꾸니 수량 문제 오류 안내되었고
Account1.OrderBuy(MarketData.code, Math.floor(매수금 / MarketData.Close), 0, 18);으로 바꾸니 udefined 오류 안내되었습니다.
2025-08-27
162
글번호 226380