Search
📝

예제3. 시간정정주문

예제3에서는 주문후 일정 시간 경과 후에 정정주문을 구현하는 방법을 통해 주문응답이벤트, 타이머이벤트 등 몇 가지 이벤트에 대해 알아보도록 하겠습니다.
1.
전략내용
스팟전략이 실행되면 바로 삼성전자를 매수1호가에 1주 매수주문하고 60초 간격으로 미체결 상태이면 매도5호가로 정정주문을 발생합니다.
2.
스크립트 객체화면 설정
a.
종목객체
삼성전자에 주문을 발생해야 하므로 스크립트 객체화면에서 종목객체를 추가한 후 속성화면에서 종목은 삼성전자로 설정하고 객체명은 SSE로 지정합니다.
지수이므로 시세거래소는 KRX로 지정하고 일간데이터나 수급데이터는 불필요하므로 사용안함으로 설정합니다.
b.
계좌객체
주문을 발생해야 하므로 계좌객체를 추가한 후 계좌를 지정합니다. 객체명은 A1로 지정하고 주문 낼 계좌번호를 지정합니다.
3.
전략작성전략
a.
우선 스팟전략이 [예스스팟 모니터]에 적용되어 처음 실행될 때 매수주문을 발생해야 합니다.
Main객체의 OnStart 이벤트는 스팟전략이 처음 실행될 때를 호출되는 이벤트입니다. 스팟전략이 처음 실행될 때, 계산해야 할 값이 있거나 초기값을 지정해 주는 등 실행해야 할 내용이 있을 때 사용하는 이벤트입니다.
스팟에서 주문이 실행되면 모두 고유의 주문식별번호가 부여됩니다. 주문식별번호를 사용하기 위해서는 주문함수를 변수에 할당하면 자동으로 해당 주문 함수가 동작하면 주문식별번호가 변수에 저장이 됩니다. 주문식별번호는 내부적으로 미리 지정한 양식에 따라 부여되므로 항상 변수에 저장하고 사용해야 합니다. 주문식별번호를 이용하면 수신된 주문응답이 현재 전략에서 발생한 주문의 응답인지를 더 쉽게 파악할 수 있습니다. 주문식별번호를 저장한 ID변수는 다른 이벤트에서도 사용해야 하므로 전역변수로 선언합니다.
b.
정정주문을 하기 위해서는 주문번호가 필요합니다. 주문번호는 주문 후에 접수응답이 수신되어야 알 수 있습니다.
Main객체의 OnOrderResponse 이벤트는 주문응답이 발생하면 호출되는 이벤트입니다.
발생한 주문응답에 대한 정보는 주문응답객체(OrderResponse)로 확인합니다. 주문응답객체가 제공하는 정보는 아래와 같습니다.
스팟에서 발생된 주문에 대해 접수응답이 발생했을 때만 호출되는데 여러 주문응답 중에 현재 전략에서 발생한 주문에 대한 응답인지 일기 위해서는 주문식별번호를 이용해야 합니다. 주문응답이 발생하면 어떤 주문식별번호에 대한 응답인지는 OrderResponse.orderID로 확인 할 수 있습니다.
주문응답객체의 주문식별번호를 이용해 현재 수신된 주문응답의 주문식별번호가 현재 전략이 매수주문 시에 저장된 주문식별번호와 같은지 확인합니다. 주문식별번호가 동일하면 변수에 주문응답객체의 주문번호(OrderResponse.orderNum)를 저장하고 타이머를 실행합니다. ※ 주문번호를 저장하는 변수는 다른 이벤트에서도 사용되므로 전역변수로 선언합니다. ※ Main객체의 SetTimer는 타이머를 설정하는 함수입니다. 수식에서 여러 개의 타이머를 사용할 수 있으므로 타이머의 아이디를 지정하고 반복주기를 설정합니다. 타이머의 아이디는 1로 지정하고 반복주기는 60초로 지정합니다. 1000이 1초이므로 60000으로 지정하면 60초가 됩니다.
c.
주문응답 이벤트가 발생하면 타이머가 설정이 되고 지정한 60초가 경과 후에 아직 미체결이면 정정주문을 해야 합니다.
타이머 이벤트는 전략에서 설정한 타이머가 동작하면 발생하는 이벤트입니다. nEventID로 타이머 아이디를 리턴합니다.
실행된 타이머의 아이디가 1이면 저장한 주문번호로 미체결객체를 셋팅해서 미체결된 수량을 확인해서 미체결 수량이 남아 있느면 매도 5호가로 정정주문을 실행하고 미체결 수량이 없으면(전량체결) 타이머를 종료하게 됩니다. 정정주문함수는 가격만 변경하므로 가격정정주문함수를 이용합니다. 매개변수로 주문번호와 정정주문가격을 지정하시면 됩니다.
4.
스팟수식
var ID, Number; //스팟 시작 function Main_OnStart() { //매수주문하고 주문식별번호는 ID에 저장 ID = A1.OrderBuy(SSE.code, 1, SSE.Ask(2), 0); } //주문응답수신 function Main_OnOrderResponse(OrderResponse) { //수신된 주문응답의 주문식별번호가 ID에 저장된 값과 같으면 if (OrderResponse.orderID == ID) { //Number변수에 주문번호 저장 Number = OrderResponse.orderNum; //60초 타이머 실행 Main.SetTimer(1, 60000); } } //타이머 동작 function Main_OnTimer(nEventID) { //타이머아이디가 1이고 if (nEventID == 1) { //주문번호 지정해 미체결 객체 셋팅 A1.SetUnfill(Number); if (A1.Unfill.count > 0) { //매도 5호가로 정정주문 A1.OrderReplacePrice(Number,SSE.Ask(5)); } else { //미체결이 없으므로 타이머 종료 Main.KillTimer(1); } } }
JavaScript
복사