Search

예제검토1. 주문시 지정한 호가가 없을 때 존재하는 호가로 매수 주문

종목검색으로 고른 종목을 지정가로 매수할 때, 지정한 단계의 호가가 아직 없으면 존재하는 호가를 찾아 주문하는 예제입니다.
주문시 매도5호가 Ask(5)로 지정했는데 해당 호가가 없으면 0값이 반환됩니다. 이때 0 을 그대로 지정가 주문가격으로 쓰면 "주문단가가 하한가보다 낮습니다" 오류와 함께 원장에서 주문이 거부됩니다.
아래 내용은 기본가격을 현재가로 두고 매도5호가부터 매도1호가까지 내려가며 존재하는 첫 호가로 주문하는 방법입니다. 다른 지정가 주문에도 같은 규칙을 응용할 수 있습니다.
1.
전략내용
스팟을 실행하면 사용자검색조건으로 종목검색을 한 번 실행하고 검색된 종목마다 종목객체를 만든 뒤 종목당 매수금만큼 지정가로 매수합니다.
주문가격은 다음 순서로 정합니다. 기본가격은 현재가입니다. 매도5호가부터 매도1호가까지 차례로 확인해 0 보다 큰 첫 호가가 있으면 그 호가를 주문가격으로 씁니다. 어느 단계에도 호가가 없으면 현재가로 주문하고, 현재가마저 없으면 그 주문은 내지 않고 메시지를 남깁니다.
주문은 거래소를 SOR로 지정한 JSON 객체형 매수주문입니다.
2.
스크립트 객체화면 설정
계좌객체를 추가한 후 속성에서 객체명은 Account1 으로 지정하고 계좌번호를 지정합니다. 종목객체는 추가하지 않습니다. 수식 안에서 Main.ReqMarketData 로 만들어 씁니다.
3.
사용자검색조건 설정
스팟에서는 Main.ReqPowerSearch("사용자검색조건명"); 함수로 종목검색을 수행합니다. 이때 지정하는 사용자검색조건명은 예스랭귀지로 작성한 종목검색식의 이름이 아닙니다.
파워종목검색 화면 좌측의 리스트에서 작성한 종목검색식이나 시장검색 등을 선택해서 우측 조건리스트에 추가하고 주기 등 필요한 설정을 완료한 후에 조건저장 버튼을 클릭하면 이름을 지정해서 사용자검색조건으로 저장이 되고 스팟수식의 SearchName 변수에는 이렇게 저장한 사용자검색조건명을 지정해 주셔야 합니다.
4.
스팟수식
//동시호가 시간대처럼 지정한 단계의 호가가 아직 없을 때, 존재하는 호가를 찾아 지정가로 매수하는 예제 //게시판 문의: 08시 50분부터 09시 사이 동시호가 주문에서 매도5호가 Ask(5) 가 0 으로 돌아와 //지정가 0 원 주문이 나가면서 "주문단가가 하한가보다 낮습니다" 오류가 났다 //아래 세 값은 사용자가 바꿔 쓰는 값이라 코드 맨 위에 모아 둔다 var SearchName = "사용자검색조건명"; //파워종목검색 화면에서 조건저장으로 만든 사용자검색조건명 var BuyAmount = 1000000; //종목당 매수금 var Exchange = 1; //시세주문 거래소 - 1:시세(통합)/주문(SOR,스마트), 2: 시세(KRX)/주문(KRX) , 4 시세(NXT)/주문(NXT) var StockList = []; //검색된 종목의 종목코드 var Stock = {}; //종목객체를 종목코드로 찾기 위한 보관소 var rcv; //종목객체를 요청한 순번 //스팟 시작. 동시호가 시간대에 스팟을 실행하면 바로 검색을 한 번 실행한다 function Main_OnStart() { Main.MessageList("검색 시작", SearchName); Main.ReqPowerSearch(SearchName); } //타이머 동작. 2번 타이머는 종목객체 생성 제한에 걸렸을 때의 재요청용이다 function Main_OnTimer(nEventID) { if (nEventID == 2) { Main.KillTimer(2); Main.ReqMarketData({code:StockList[rcv], exchangeKind:Exchange}); } } //종목검색 완료. 검색된 종목의 종목객체를 첫 종목부터 차례로 요청한다 function Main_OnRcvItemList(aItemList, nCount, aValues) { Main.MessageList("검색된 종목수", nCount); if (nCount < 1) { return; } StockList = []; for (var a = 0; a < nCount; a++) { StockList.push(aItemList[a]); } rcv = 0; Main.ReqMarketData({code:StockList[rcv], exchangeKind:Exchange}); } //요청한 종목객체가 만들어지면 보관하고 매수한 뒤 다음 종목객체를 요청한다 function Main_OnRcvMarketData(MarketData) { if (MarketData.code != StockList[rcv]) { return; } Stock[MarketData.code] = MarketData; BuyWithExistingAsk(MarketData.code); rcv = rcv + 1; if (rcv < StockList.length) { var XX = Main.ReqMarketData({code:StockList[rcv], exchangeKind:Exchange}); //종목객체 생성 제한이면 15초 뒤에 다시 요청한다 if (XX == -1) { Main.SetTimer(2, 15000); } } else { Main.MessageList("종목객체 요청 끝"); } } //주문가격을 정해 매수한다 //기본가격은 현재가이고, 매도5호가부터 매도1호가까지 내려가며 0 보다 큰 첫 호가를 주문가격으로 쓴다 //동시호가 시간대에는 5호가까지 채워지지 않아 Ask(5) 가 0 으로 돌아올 수 있다 function BuyWithExistingAsk(codex) { var Price = Stock[codex].current; for (var i = 5; i >= 1; i--) { if (Stock[codex].Ask(i) > 0) { Price = Stock[codex].Ask(i); break; } } //호가도 현재가도 아직 없으면 0 원 지정가 주문이 나가지 않게 이번 주문은 내지 않는다 if (Price <= 0) { Main.MessageList("호가와 현재가가 아직 없어 주문을 내지 않음", codex); return; } var buyN = Math.floor(BuyAmount / Price); if (buyN > 0) { Account1.OrderBuy({exchangeKind:Exchange, code:codex, count:buyN, orderPrice:Price, priceKind:0}); Main.MessageList("매수주문", codex, "가격", Price, "수량", buyN); } else { Main.MessageList("매수금 부족", codex); } }
JavaScript
복사