Search
📝

예제21. 종목검색으로 매수하고 매수종목의 차트에서 지표값이 특정조건 만족하면 매도

종목검색과 지표을 연동하는 수식입니다.
1.
전략내용
종목이 검색되면 바로 매수하고 해당 종목의 특정 주기의 차트를 생성하고 차트에서 봉완성시 지표값으로 특정조건 만족여부를 체크해서 만족하면 매도하는 수식입니다. 최대 20종목까지 매수합니다.
2.
스크립트 객체화면 설정
계좌객체를 추가한 후 속성에서 객체명은 Account1으로 지정하고 계좌번호로 지정합니다.
3.
사용자검색조건 설정
스팟에서는 Main.ReqPowerSearch(”사용자검색조건명”); 함수로 종목검색을 수행하게 되는데 이때 지정하는 사용자검색조건명은 예스랭귀지로 작성한 종목검색식의 이름이 아닙니다. 종목검색식 자체는 아이디어를 코딩한 내용뿐이고 주기등 세부설정이 있지 않습니다. 좌측의 리스트에서 작성한 종목검색식이나 시장검색등을 선택해서 우측 조건리스트에 추가하고 주기등 필요한 설정을 완료한 후에 조건저장 버튼을 클릭하면 이름을 지정해서 사용자검색조건으로 저장이 되고 스팟수식에는 이렇게 저장한 사용자검색조건명을 지정해 주셔야 합니다. ※예 스랭귀지로 작성한 종목검색식은 문법검증이 완료되면 파워종목검색화면의 좌측 리스트의 기술적지표에 추가가 됩니다.
4.
스팟수식
//var userSearchName = "사용자조건검색명"; var userSearchName = "내검색"; var 검색주기 = 10; //60초 var MKList = []; //종목검색 후 종목객체 요청할 종목의 종목코드를 리스트할 배열변수 var MK = []; //종목객체를 저장할 배열변수 var CT = []; //차트객체를 저장할 배열변수 var B = []; //주문흐름 저장할 배열변수 var req; //종목객체 요청 횟수를 저장할 변수 var 최대매수종목수 = 20; //매수할 최대 종목수 var 매수금 = 1000000; //종목당 매수금 //스팟 시작 function Main_OnStart() { Main.MessageList("Start"); //1번 타이머, 60초 Main.SetTimer(1, 검색주기*1000); } //타이머 동작 function Main_OnTimer(nEventID) { //자바스크립트 날짜시간 객체에서 값을 가져와 HHMMSS형식으로 시간 계산 var d = new Date(); HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds(); //1번 타이머 동작하고 9시~15시 사이이면 if (nEventID == 1 && HHMMSS >= 90000 && HHMMSS <= 150000) { //타이머 종료 Main.KillTimer(1); //지정한 이름의 사용자조건검색을 실행 Main.ReqPowerSearch(userSearchName); } if (nEventID == 2) { Main.KillTimer(2); //재요청 Main.ReqMarketData(MKList[req]); } } //종목검색완료 function Main_OnRcvItemList(aItemList, nCount, aValues) { Main.MessageList("검색된종목수",nCount); //검색된 종목이 한종목 이상 if (nCount >= 1) { //종목객체 요청리스트를 초기화 MKList = []; //처음 종목이 검색이 될 떄는 if (MK.length == 0) { //검색된 종목 중 잔고에 없는 종목으로 최대20개만 MKList에 저장 for (var a = 0; a < nCount; a++) { Account1.SetBalance(aItemList[a],0); if (Account1.Balance.count == 0 && MKList.length < 최대매수종목수) { MKList.push(aItemList[a]); } } } else { //1종목이상 검색이 된 이후에는 if (MK.length < 최대매수종목수) { for (var a = 0; a < nCount; a++) { //종목객체가 만들어진 종목은 제외 var Add = true; for (var b = 0; b < MK.length; b++) { if (aItemList[a] == MK[b].code) { Add = false; } } //계좌 잔고에 보유중인 종목 제외 Account1.SetBalance(aItemList[a],0); if (Account1.Balance.count > 0) Add = false; //종목객체로 만들어 지지 않았고 잔고에 없는 종목으로 선정하여 //요청리스트에 저장 if (Add == true && MKList.length < 최대매수종목수-MK.length) { MKList.push(aItemList[a]); } } } } Main.MessageList("주문할 종목수:",MKList.length); //요청할 종목이 없고 if (MKList.length == 0) { //종목객체가 최대매수종목수 미만이면 1번 타이머 재셋팅 if (MK.length < 최대매수종목수) { //1번 타이머, 60초 Main.SetTimer(1, 검색주기*1000); } else { //종목객체가 최대매수종목수와 같으면 메세지 출력하고 종료 Main.MessageList("최대종목수 도달 검색종료"); } } else //요청할 종목이 있으면 { //요청리스트의 첫종목 부터 종목객체 요청(배열이므로 종목코드가 0번방 부터 존재) req = 0; Main.MessageList(req,"종목객체요청",MKList[req]); Main.ReqMarketData(MKList[req]); } } } //요청한 종목객체가 만들어 지면 function Main_OnRcvMarketData(MarketData) { //직전 요청한 종목이 맞는지 확인후에 if (MarketData.code == MKList[req]) { Main.MessageList(req,"종목객체생성",MarketData.code); //생성된 순서로 //종목객체는 MK에 추가하고 //B에 매수의미로 1값 추가 MK.push(MarketData); B.push(1); //매수주문가격(매도1호가), 없으면 현재가 var OP = MarketData.Ask(1); if (OP > 0) { OP = MarketData.current; } //수량 var OV = Math.floor(매수금/OP); //지정한 가격, 지정한 수량으로 매수주문 if (OV > 0) { Account1.OrderBuy(MarketData.code,OV,OP,0); Main.MessageList(req,"매수주문",MarketData.code,OV,OP); } else Main.MessageList(req,"금액부족"); //차트 셋팅 var ChartSet = new ReqChartItem(MKList[req],5,CHART_PERIOD_MINUTE, 1000, CHART_REQCOUNT_BAR, false, false); //지표 셋팅(지표는 복수로 지정이 가능흐므로 Array에 담아 지정) var IndSet = new Array(new IndicatorInfo("Stochastics")); //지정한 셋팅으로 차트객체 요청, 차트 셋팅 제외하고 시스템,자표,참조데이터는 생략가능, 생략하면 null로 지정 Main.ReqChartEx(ChartSet, null, IndSet); Main.MessageList("차트객체요청",MKList[req]); } } function Main_OnRcvChartEx(ChartEx) { if (ChartEx.GetCode(1) == MKList[req]) { Main.MessageList("차트객체생성",ChartEx.GetCode(1)); CT.push(ChartEx); //요청횟수 1증가 req = req+1; //요청횟수가 요청할 종목갯수보다 작으면 다음 종목객체 요청 if (req < MKList.length) { Main.MessageList(req,"종목객체요청",MKList[req]); var XX = Main.ReqMarketData(MKList[req]); //종목객체 생성제한 if (XX == -1) { //2번 타이머 15초 Main.SetTimer(2,15000); } } else //요청횟수가 요청할 종목갯수에 도달했으면 종목객체 생성 종료 { Main.MessageList(req,"종목객체생성끝"); //최대매수종목수에 도달하지 않았으면 종목검색을 위해 타이머 재셋팅 if (MK.length < 최대매수종목수) { Main.SetTimer(1,검색주기*1000); } else { //최대매수종목수를 채웠으면 검색 종료 Main.MessageList("최대종목수 도달 검색종료"); } } } } //차트 봉완성(다음봉시가수신) function Main_OnBarAppended(ChartEx, nData) { if (CT.length > 0) { for (var i = 0; i < CT.length; i++) { if (ChartEx.GetCode(1) == CT[i].GetCode(1) && B[i] == 1) { //GetIndicatorData(sIndicatorName, nPlotNum, nPlotIndex) 함수는 //지표값을 리턴하는데 nPlotIndex가 0이면 현재봉, 1이면 전봉, 2이면 전전봉입니다. //완성봉기준으로믄 1이 가장 최근 완성봉입니다. if (CT[i].GetIndicatorData("Stochastics",1,1) >= 80 && CT[i].GetIndicatorData("Stochastics",1,2) < 80) { Main.MessageList("봉완성 K80돌파",CT[i].GetIndicatorData("Stochastics",1,1)); B[i] = -1; Account1.SetBalance(CT[i].GetCode(1),0) if (Account1.Balance.count > 0) { Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,MK[i].Bid(1),0); Main.MessageList("매도주문",Account1.Balance.code,Account1.Balance.count,MK[i].Bid(1),0); } } } } } }
JavaScript
복사