커뮤니티

질문입니다.

프로필 이미지
yanartas
2017-12-13 18:46:42
2769
글번호 224262
답변완료
주가지수선물을 거래하기 위해서, 예스랭귀지로 시스템을 작성하였고,(1계약을 거래하는 시스템) 예스스팟으로 주문을 컨트롤 할려고 합니다. 질문1. 예스랭귀지에서 나온 신호를 채결시키되, 만약 채결이 이루어지지 않은 경우 10초 간격으로 채결이 이루어질때까지 현재가로 주문정정을 넣는 것입니다. 질문2. 만약, 현재 시스템의 시그널이 매수(혹은 매도)이고, 손매매로 매수(혹은 매도)로 진입해 주었다면, 다음 시그널인 매수청산(혹은 매도청산)부터 작동하도록 예스스팟을 구성하고, 만약, 현재 시스템의 시그널이 매수(혹은 매도)이지만, 실재로 포지션이 없다면 시스템의 다음 진입신호부터 작동하도록 예스스팟을 작성하고 싶습니다. 즉, 예스스팟 시작시 포지션에 진입해있다면 청산시그널부터 실행하고, 시작시 포지션이 없다면 다음 진입시그널부터 실행하도록 만들고 싶습니다. 질문1.과 질문2.를 요약하자면 다음과 같습니다. " 예스스팟 시작시 실제 포지션이 있다. -> 해당포지션의 청산부터 예스스팟 작동. 예스스팟 시작시 실제 포지션이 없다. -> 시스템의 다음 진입신호부터 예스스팟 작동. 미체결시에는 채결이 될때까지 10초마다 현재가로 주문을 정정한다. (단, 현재가가 10초전에 주문한가격과 다를때만 주문을 정정한다.) " 제가 스스로 만들고, 수정을 해본 코드입니다. 불편을 드려 죄송하지만, 제깐에는 간절하고 급해서 그럽니다. 살펴보시고 수정보완 부탁드립니다. 한가지 추가 요청사항은 체결이 완성된 경우, "매수(매도, 매수청산, 매도청산, 매수정정, 매도정정) 체결완료"라는 메세지를 띄우고 싶습니다. 부탁드립니다. 다시한번 감사합니다. var Position; var OrderCode; var BID; var BNum; var SID; var SNum; function Main_OnStart() { // 시작. "Start" 출력. Main.MessageLog("Start"); // 시스템을 연결선물에 적용. 따라서 주문용 종목코드를 리턴받아 OrderCode에 저장. OrderCode = Main.GetOrderCode(MarketData1.code); // 현재 포지션이 매도나 매수가 아니라면, if (Account1.Balance.position != 1 && Account1.Balance.position != 2) { // Position에 0 대입. Position = 0; // 포지션이 없으므로 "Current Zero" 출력. Main.MessageLog("Current Zero"); } // 현재 포지션이 매도라면, if (Account1.Balance.position == 1) { // Position에 -1 대입. Position = -1; // 포지션이 매도이므로 "Current Short" 출력. Main.MessageLog("Current Short"); } // 현재 포지션이 매수라면, if (Account1.Balance.position == 2) { // Position에 1 대입. Position = 1; // 포지션이 매수이므로 "Current Long" 출력. Main.MessageLog("Current Long"); } } function Chart1_OnRiseSignal(Signal) { // 완성된 시그널 출력. Main.MessageLog("Signal:"+Signal.signalKind); // 시그널 종류가 매수라면, if (Signal.signalKind == 1) { // Position에 1 대입. Position = 1; // 주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Buy 주문. // BID에 주문식별번호 저장. BID = Account1.OrderBuy(OrderCode, Signal.count, 0, 1); // 매수진입 "Long" 출력 Main.MessageLog("Long"); } // 시그널 종류가 매수청산이라면, if (Position == 1 && Signal.signalKind == 2) { // Position에 0 대입. Position = 0; // 주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Sell 주문. // SID에 주문식별번호 저장. SID = Account1.OrderSell(OrderCode, Signal.count, 0, 1); // 매수청산 "ExitLong" 출력 Main.MessageLog("ExitLong"); } // 시그널 종류가 매도라면, if (Signal.signalKind == 3) { // Position에 -1 대입. Position = -1; // 주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Sell 주문. // SID에 주문식별번호 저장. SID = Account1.OrderSell(OrderCode, Signal.count, 0, 1); // 매도진입 "Short" 출력 Main.MessageLog("Short"); } // 시그널 종류가 매도청산이라면, if (Position == -1 && Signal.signalKind == 4) { // Position에 0 대입 Position = 0; // 주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Buy 주문. // BID에 주문식별번호 저장. BID = Account1.OrderBuy(OrderCode, Signal.count, 0, 1); // 매도청산 "ExitShort" 출력 Main.MessageLog("ExigShort"); } } function Main_OnOrderResponse(OrderResponse) { // 해당 주문응답이 현재 전략에서 발생한 주문이라면, if (OrderResponse.orderID == BID) { // BNum에 주문응답객체의 주문번호를 저장하고, BNum = OrderResponse.orderID; // Timer1을 실행(10초 간격). Main.SetTimer(1, 10000); } // 해당 주문응답이 현재 전략에서 발생한 주문이라면, if (OrderResponse.orderID == SID) { // SNum에 주문응답객체의 주문번호를 저장하고, SNum = OrderResponse.orderID; // Timer2를 실행(10초 간격). Main.SetTimer(2, 10000); } } function Main_OnTimer(nEventID) { // 현재 실행된 Timer가 1이고, if (nEventID == 1) { // ??? Account1.SetUnfillOrderNumber(BNum); // 미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != MarketData1.current) { // 가격을 현재가로 정정하여 정정주문. BID = Account1.OrderReplacePrice(BNum, MarketData1.current); // Timer1 종료. Main.KillTimer(1); } } // 현재 실행된 Timer가 2이고, if (nEventID == 2) { // ??? Account1.SetUnfillOrderNumber(SNum); // 미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != MarketData1.current) { // 가격을 현재가로 정정하여 정정주문. SID = Account1.OrderReplacePrice(SNum, MarketData1.current); // Timer2 종료. Main.KillTimer(2); } } } function Main_OnNotifyFill(NotifyFill) { // 주문 체결되면, if (NotifyFill.orderNum == BNum) { // Timer1 종료. Main.KillTimer(1); // 미체결수량이 체결되면, "Long OrderReplacePrice" 출력 Main.MessageLog("Long OrderReplacePrice"); } // 추문 체결되면, if (NotifyFill.orderNum == SNum) { // Timer2 종료 Main.KillTimer(2); // 미체결수량이 체결되면, "Short OrderReplacePrice" 출력 Main.MessageLog("Short OrderReplacePrice"); } }
답변 3
프로필 이미지

예스스탁 예스스탁 답변

2017-12-15 13:43:48

안녕하세요 예스스탁입니다. 작성하신 식에서 OnStart이벤트에서 잔고를 셋팅하지 않고 잔고객체를 사용하고 있어 잔고셋팅을 추가했습니다. 주문이 현재가가 아닌 시장가로 되어 있어 현재가로 수정했습니다. OnStart시점에 저장된 Position값에 따라 영향을 받으므로 진입신호시에 Position == 0이라는 조건을 추가해야 합니다. 주문응답시 주문번호가 아닌 주문아이디를 주분번호를 저장할 변수에 저장하고 있어 수문번호를 저장하게 수정했습니다. 각 주문별로 변도 아이디와 주문번호가 저장되게 수정했습니다. 수정한 식입니다. 주석등 내용 참고하시기 바랍니다. var Position; var OrderCode; var BID,BXID,SID,SXID; var BNum,BXNum,SNum,SXNum; function Main_OnStart() { // 시작 "Start" 출력. Main.MessageLog("Start"); // 시스템을 연결선물에 적용. 따라서 주문용 종목코드를 리턴받아 OrderCode에 저장. OrderCode = Main.GetOrderCode(MarketData1.code); //OrderCode종목 잔고셋팅 Account1.SetBalance(OrderCode, 0); // 현재 포지션이 매도나 매수가 아니라면, if (Account1.Balance.position != 1 && Account1.Balance.position != 2) { // Position에 0 대입. Position = 0; // 포지션이 없으므로 "Current Zero" 출력. Main.MessageLog("Current Zero"); } // 현재 포지션이 매도라면, if (Account1.Balance.position == 1) { // Position에 -1 대입. Position = -1; // 포지션이 매도이므로 "Current Short" 출력. Main.MessageLog("Current Short"); } // 현재 포지션이 매수라면, if (Account1.Balance.position == 2) { // Position에 1 대입. Position = 1; // 포지션이 매수이므로 "Current Long" 출력. Main.MessageLog("Current Long"); } } function Chart1_OnRiseSignal(Signal) { // 완성된 시그널 출력. Main.MessageLog("Signal : "+Signal.signalKind); // Position가 0이고 시그널 종류가 매수라면, if (Position == 0 && Signal.signalKind == 1) { // Position에 1 대입. Position = 1; // 주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Buy 주문. // BID에 주문식별번호 저장. BID = Account1.OrderBuy(OrderCode, Signal.count, MarketData1.current, 0); // 매수진입 "Long" 출력 Main.MessageLog("Long"); } // Position이 1이고 시그널 종류가 매수청산이라면, if (Position == 1 && Signal.signalKind == 2) { // Position에 0 대입. Position = 0; // 주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Sell 주문. // SID에 주문식별번호 저장. BXID = Account1.OrderSell(OrderCode, Signal.count, MarketData1.current, 0); // 매수청산 "ExitLong" 출력 Main.MessageLog("ExitLong"); } // 시그널 종류가 매도라면, if (Position == 0 && Signal.signalKind == 3) { // Position에 -1 대입. Position = -1; // 주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Sell 주문. // SID에 주문식별번호 저장. SID = Account1.OrderSell(OrderCode, Signal.count, MarketData1.current, 0); // 매도진입 "Short" 출력 Main.MessageLog("Short"); } // 시그널 종류가 매도청산이라면, if (Position == -1 && Signal.signalKind == 4) { // Position에 0 대입 Position = 0; // 주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Buy 주문. // BID에 주문식별번호 저장. SXID = Account1.OrderBuy(OrderCode, Signal.count, MarketData1.current, 0); // 매도청산 "ExitShort" 출력 Main.MessageLog("ExigShort"); } } function Main_OnOrderResponse(OrderResponse) { // 해당 주문응답이 Buy신호에 대한 주문응답이라면, if (OrderResponse.orderID == BID) { // BNum에 주문응답객체의 주문번호를 저장하고, BNum = OrderResponse.orderNum; //1번 타이머 실행(10초 간격). Main.SetTimer(1, 10000); } // 해당 주문응답이 Exitlong신호에 대한 주문응답이라면, if (OrderResponse.orderID == BXID) { // BXNum에 주문응답객체의 주문번호를 저장하고, BXNum = OrderResponse.orderNum; //2번 타이머 실행(10초 간격). Main.SetTimer(2, 10000); } // 해당 주문응답이 Sell신호에 대한 주문응답이라면, if (OrderResponse.orderID == SID) { //SNum에 주문응답객체의 주문번호를 저장하고, BXNum = OrderResponse.orderNum; //3번 타이머 실행(10초 간격). Main.SetTimer(3, 10000); } // 해당 주문응답이 ExitShort신호에 대한 주문응답이라면, if (OrderResponse.orderID == SXID) { // BXNum에 주문응답객체의 주문번호를 저장하고, SXNum = OrderResponse.orderNum; //4번 타이머 실행(10초 간격). Main.SetTimer(4, 10000); } } function Main_OnTimer(nEventID) { // 아이디 1번 타이머 실행 if (nEventID == 1) { //1번 타이머 종료 Main.KillTimer(1); //BNum 주문번호의 미체결객체 셋팅 Account1.SetUnfillOrderNumber(BNum); //현재가 저장 var CC = MarketData1.current; // 미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { // 가격을 현재가로 정정하여 정정주문 // --> 정정주문후 주문응답시 BNum새로 갱신하고 타이머 재셋팅 BID = Account1.OrderReplacePrice(BNum, CC); } if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //현재가가 같아 정정주문이 없으므로 1번 타이머 재셋팅 Main.SetTimer(1, 10000); } } // 아이디 2번 타이머 실행 if (nEventID == 2) { //2번 타이머 종료 Main.KillTimer(2); //BXNum 주문번호의 미체결객체 셋팅 Account1.SetUnfillOrderNumber(BXNum); //현재가 저장 var CC = MarketData1.current; // 미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { // 가격을 현재가로 정정하여 정정주문 // --> 정정주문후 주문응답시 BXNum새로 갱신하고 타이머 재셋팅 BXID = Account1.OrderReplacePrice(BXNum, MarketData1.current); } if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //현재가가 같아 정정주문이 없으므로 2번 타이머 재셋팅 Main.SetTimer(2, 10000); } } // 아이디 3번 타이머 실행 if (nEventID == 3) { //3번 타이머 종료 Main.KillTimer(3); //SNum 주문번호의 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SNum); //현재가 저장 var CC = MarketData1.current; // 미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { //가격을 현재가로 정정하여 정정주문 //정정주문후 주문응답시 SNum새로 갱신하고 타이머 재셋팅 SID = Account1.OrderReplacePrice(SNum, MarketData1.current); } if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //현재가가 같아 정정주문이 없으므로 3번 타이머 재셋팅 Main.SetTimer(3, 10000); } } // 아이디 4번 타이머 실행 if (nEventID == 4) { //4번 타이머 종료 Main.KillTimer(4); //SXNum 주문번호의 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SXNum); //현재가 저장 var CC = MarketData1.current; // 미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { //가격을 현재가로 정정하여 정정주문 //정정주문후 주문응답시 SXNum새로 갱신하고 타이머 재셋팅 SXID = Account1.OrderReplacePrice(SXNum, MarketData1.current); } if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //현재가가 같아 정정주문이 없으므로 4번 타이머 재셋팅 Main.SetTimer(4, 10000); } } } function Main_OnNotifyFill(NotifyFill) { Main.MessageLog("체결이벤트"); //BNum 주문 체결되면, if (NotifyFill.orderNum == BNum) { //1번 타이머 종료. Main.KillTimer(1); //BNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(BNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { Main.MessageLog("매수진입 체결완료"); } } //BXNum 주문 체결되면, if (NotifyFill.orderNum == BXNum) { //2번 타이머 종료. Main.KillTimer(2); //BXNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(BXNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { Main.MessageLog("매수청산 체결완료"); } } //SNum 주문 체결되면, if (NotifyFill.orderNum == SNum) { //1번 타이머 종료. Main.KillTimer(3); //SNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { Main.MessageLog("매도진입 체결완료"); } } //SXNum 주문 체결되면, if (NotifyFill.orderNum == SXNum) { //4번 타이머 종료. Main.KillTimer(4); //SXNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SXNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { Main.MessageLog("매도청산 체결완료"); } } } 즐거운 하루되세요 > yanartas 님이 쓴 글입니다. > 제목 : 질문입니다. > 주가지수선물을 거래하기 위해서, 예스랭귀지로 시스템을 작성하였고,(1계약을 거래하는 시스템) 예스스팟으로 주문을 컨트롤 할려고 합니다. 질문1. 예스랭귀지에서 나온 신호를 채결시키되, 만약 채결이 이루어지지 않은 경우 10초 간격으로 채결이 이루어질때까지 현재가로 주문정정을 넣는 것입니다. 질문2. 만약, 현재 시스템의 시그널이 매수(혹은 매도)이고, 손매매로 매수(혹은 매도)로 진입해 주었다면, 다음 시그널인 매수청산(혹은 매도청산)부터 작동하도록 예스스팟을 구성하고, 만약, 현재 시스템의 시그널이 매수(혹은 매도)이지만, 실재로 포지션이 없다면 시스템의 다음 진입신호부터 작동하도록 예스스팟을 작성하고 싶습니다. 즉, 예스스팟 시작시 포지션에 진입해있다면 청산시그널부터 실행하고, 시작시 포지션이 없다면 다음 진입시그널부터 실행하도록 만들고 싶습니다. 질문1.과 질문2.를 요약하자면 다음과 같습니다. " 예스스팟 시작시 실제 포지션이 있다. -> 해당포지션의 청산부터 예스스팟 작동. 예스스팟 시작시 실제 포지션이 없다. -> 시스템의 다음 진입신호부터 예스스팟 작동. 미체결시에는 채결이 될때까지 10초마다 현재가로 주문을 정정한다. (단, 현재가가 10초전에 주문한가격과 다를때만 주문을 정정한다.) " 제가 스스로 만들고, 수정을 해본 코드입니다. 불편을 드려 죄송하지만, 제깐에는 간절하고 급해서 그럽니다. 살펴보시고 수정보완 부탁드립니다. 한가지 추가 요청사항은 체결이 완성된 경우, "매수(매도, 매수청산, 매도청산, 매수정정, 매도정정) 체결완료"라는 메세지를 띄우고 싶습니다. 부탁드립니다. 다시한번 감사합니다. var Position; var OrderCode; var BID; var BNum; var SID; var SNum; function Main_OnStart() { // 시작. "Start" 출력. Main.MessageLog("Start"); // 시스템을 연결선물에 적용. 따라서 주문용 종목코드를 리턴받아 OrderCode에 저장. OrderCode = Main.GetOrderCode(MarketData1.code); // 현재 포지션이 매도나 매수가 아니라면, if (Account1.Balance.position != 1 && Account1.Balance.position != 2) { // Position에 0 대입. Position = 0; // 포지션이 없으므로 "Current Zero" 출력. Main.MessageLog("Current Zero"); } // 현재 포지션이 매도라면, if (Account1.Balance.position == 1) { // Position에 -1 대입. Position = -1; // 포지션이 매도이므로 "Current Short" 출력. Main.MessageLog("Current Short"); } // 현재 포지션이 매수라면, if (Account1.Balance.position == 2) { // Position에 1 대입. Position = 1; // 포지션이 매수이므로 "Current Long" 출력. Main.MessageLog("Current Long"); } } function Chart1_OnRiseSignal(Signal) { // 완성된 시그널 출력. Main.MessageLog("Signal:"+Signal.signalKind); // 시그널 종류가 매수라면, if (Signal.signalKind == 1) { // Position에 1 대입. Position = 1; // 주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Buy 주문. // BID에 주문식별번호 저장. BID = Account1.OrderBuy(OrderCode, Signal.count, 0, 1); // 매수진입 "Long" 출력 Main.MessageLog("Long"); } // 시그널 종류가 매수청산이라면, if (Position == 1 && Signal.signalKind == 2) { // Position에 0 대입. Position = 0; // 주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Sell 주문. // SID에 주문식별번호 저장. SID = Account1.OrderSell(OrderCode, Signal.count, 0, 1); // 매수청산 "ExitLong" 출력 Main.MessageLog("ExitLong"); } // 시그널 종류가 매도라면, if (Signal.signalKind == 3) { // Position에 -1 대입. Position = -1; // 주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Sell 주문. // SID에 주문식별번호 저장. SID = Account1.OrderSell(OrderCode, Signal.count, 0, 1); // 매도진입 "Short" 출력 Main.MessageLog("Short"); } // 시그널 종류가 매도청산이라면, if (Position == -1 && Signal.signalKind == 4) { // Position에 0 대입 Position = 0; // 주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Buy 주문. // BID에 주문식별번호 저장. BID = Account1.OrderBuy(OrderCode, Signal.count, 0, 1); // 매도청산 "ExitShort" 출력 Main.MessageLog("ExigShort"); } } function Main_OnOrderResponse(OrderResponse) { // 해당 주문응답이 현재 전략에서 발생한 주문이라면, if (OrderResponse.orderID == BID) { // BNum에 주문응답객체의 주문번호를 저장하고, BNum = OrderResponse.orderID; // Timer1을 실행(10초 간격). Main.SetTimer(1, 10000); } // 해당 주문응답이 현재 전략에서 발생한 주문이라면, if (OrderResponse.orderID == SID) { // SNum에 주문응답객체의 주문번호를 저장하고, SNum = OrderResponse.orderID; // Timer2를 실행(10초 간격). Main.SetTimer(2, 10000); } } function Main_OnTimer(nEventID) { // 현재 실행된 Timer가 1이고, if (nEventID == 1) { // ??? Account1.SetUnfillOrderNumber(BNum); // 미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != MarketData1.current) { // 가격을 현재가로 정정하여 정정주문. BID = Account1.OrderReplacePrice(BNum, MarketData1.current); // Timer1 종료. Main.KillTimer(1); } } // 현재 실행된 Timer가 2이고, if (nEventID == 2) { // ??? Account1.SetUnfillOrderNumber(SNum); // 미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != MarketData1.current) { // 가격을 현재가로 정정하여 정정주문. SID = Account1.OrderReplacePrice(SNum, MarketData1.current); // Timer2 종료. Main.KillTimer(2); } } } function Main_OnNotifyFill(NotifyFill) { // 주문 체결되면, if (NotifyFill.orderNum == BNum) { // Timer1 종료. Main.KillTimer(1); // 미체결수량이 체결되면, "Long OrderReplacePrice" 출력 Main.MessageLog("Long OrderReplacePrice"); } // 추문 체결되면, if (NotifyFill.orderNum == SNum) { // Timer2 종료 Main.KillTimer(2); // 미체결수량이 체결되면, "Short OrderReplacePrice" 출력 Main.MessageLog("Short OrderReplacePrice"); } }
프로필 이미지

yanartas

2017-12-18 18:10:02

한가지 추가 질문을 드립니다. 주문을 현재가가 아닌 시장가로 하고싶고, 나머지 로직은 똑같이 가져가고 싶습니다. 즉, 예스스팟 시작시 현재 계좌의 포지션을 살피고, 포지션이 없으면 다음 진입신호부터 진입하고, 포지션이 있다면 해당 포지션의 청산부터 실행됩니다. 미체결이 발생했을 경우 10초간격으로 체크를 하여, 진입한 가격과 다들 경우만 가격을 현시점의 가격으로 정정하여 주문을 냅니다. 정정부분도 현재가를 사용하는 경우와 시장가를 사용하는 경우가 다른가요? 현재 코딩은 현재가로 되어있는데 그 당시의 시장가로 진입하게 만들고 싶습니다. 그런데 궁금한점이 봉이 완성된 시점에 시장가로 주문을 넣는 것과, 봉이 왼선된 시점에 현재가로 주문을 넣는 것이 어떤 차이가 있나요? 제가 작성한 프로그램은 다음과 같습니다. 확인부탁드리고, 수정할 부분이 있다면 고쳐주시기바랍니다. 감사합니다. var Position; var OrderCode; var BID, BXID, SID, SXID; var BNum, BXNum, SNum, SXNum; function Main_OnStart() { //"OnStart" 출력. //Main.MessageLog("Start"); //시스템을 연결선물에 적용. 따라서 주문용 종목코드를 리턴받아 OrderCode에 저장. OrderCode = Main.GetOrderCode(MarketData1.code); //OrderCode종목 잔고셋팅. Account1.SetBalance(OrderCode, 0); //현재 포지션이 매도나 매수가 아니라면, if (Account1.Balance.position != 1 && Account1.Balance.position != 2) { //Position에 0 대입. Position = 0; //"Current Zero" 출력. Main.MessageLog("Current Zero"); } //현재 포지션이 매도라면, if (Account1.Balance.position == 1) { //Position에 -1 대입. Position = -1; //"Current Short" 출력. Main.MessageLog("Current Short"); } //현재 포지션이 매수라면, if (Account1.Balance.position == 2) { //Position에 1 대입. Position = 1; //"Current Long" 출력. Main.MessageLog("Current Long"); } } function Chart1_OnRiseSignal(Signal) { //완성된 시그널 출력. //Main.MessageLog("Signal : "+Signal.signalKind); //Position가 0이고, 시그널 종류가 매수라면, if (Position == 0 && Signal.signalKind == 1) { //Position에 1 대입. Position = 1; //주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Buy 주문, BID에 주문식별번호 저장. //BID = Account1.OrderBuy(OrderCode, Signal.count, MarketData1.current, 0); //주문형 종목코드로, 시스템에서 지정한 수량만큼, 시장가로 Buy 주문, BID에 주문식별번호 저장. BID = Account1.OrderBuy(OrderCode, Signal.count, 0,1); //"Long" 출력 Main.MessageLog("Long"); } //Position이 1이고, 시그널 종류가 매수청산이라면, if (Position == 1 && Signal.signalKind == 2) { //Position에 0 대입. Position = 0; //주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Sell 주문, BXID에 주문식별번호 저장. //BXID = Account1.OrderSell(OrderCode, Signal.count, MarketData1.current, 0); //주문형 종목코드로, 시스템에서 지정한 수량만큼, 시장가로 Sell 주문, BXID에 주문식별번호 저장. BXID = Account1.OrderSell(OrderCode, Signal.count, 0, 1); //"ExitLong" 출력 Main.MessageLog("ExitLong"); } //Position이 0이고, 시그널 종류가 매도라면, if (Position == 0 && Signal.signalKind == 3) { //Position에 -1 대입. Position = -1; //주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Sell 주문, SID에 주문식별번호 저장. //SID = Account1.OrderSell(OrderCode, Signal.count, MarketData1.current, 0); //주문형 종목코드로, 시스템에서 지정한 수량만큼, 시장가로 Sell 주문, SID에 주문식별번호 저장. SID = Account1.OrderSell(OrderCode, Signal.count, 0, 1); //"Short" 출력 Main.MessageLog("Short"); } //Position이 -1이고, 시그널 종류가 매도청산이라면, if (Position == -1 && Signal.signalKind == 4) { //Position에 0 대입 Position = 0; //주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Buy 주문, SXID에 주문식별번호 저장. //SXID = Account1.OrderBuy(OrderCode, Signal.count, MarketData1.current, 0); //주문형 종목코드로, 시스템에서 지정한 수량만큼, 시장가로 Buy 주문, SXID에 주문식별번호 저장. SXID = Account1.OrderBuy(OrderCode, Signal.count, 0, 1); //"ExitShort" 출력 Main.MessageLog("ExigShort"); } } function Main_OnOrderResponse(OrderResponse) { //해당 주문응답이 Long신호에 대한 주문응답이라면, if (OrderResponse.orderID == BID) { //BNum에 주문응답객체의 주문번호를 저장하고, BNum = OrderResponse.orderNum; //1번 타이머 실행(10초 간격). Main.SetTimer(1, 10000); } //해당 주문응답이 ExitLong신호에 대한 주문응답이라면, if (OrderResponse.orderID == BXID) { //BXNum에 주문응답객체의 주문번호를 저장하고, BXNum = OrderResponse.orderNum; //2번 타이머 실행(10초 간격). Main.SetTimer(2, 10000); } //해당 주문응답이 Short신호에 대한 주문응답이라면, if (OrderResponse.orderID == SID) { //SNum에 주문응답객체의 주문번호를 저장하고, SNum = OrderResponse.orderNum; //3번 타이머 실행(10초 간격). Main.SetTimer(3, 10000); } //해당 주문응답이 ExitShort신호에 대한 주문응답이라면, if (OrderResponse.orderID == SXID) { //SXNum에 주문응답객체의 주문번호를 저장하고, SXNum = OrderResponse.orderNum; //4번 타이머 실행(10초 간격). Main.SetTimer(4, 10000); } } function Main_OnTimer(nEventID) { //1번 타이머 실행. if (nEventID == 1) { //1번 타이머 종료. Main.KillTimer(1); //BNum 주문번호의 미체결객체 셋팅. Account1.SetUnfillOrderNumber(BNum); //현재가 저장 var CC = MarketData1.current; //미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { //가격을 현재가로 정정하여 정정주문. 정정주문 후 주문응답시 BNum 새로 갱신하고 타이머 재셋팅. BID = Account1.OrderReplacePrice(BNum, CC); } //미체결수량이 존재하나, 미체결가격과 현재가격이 같다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //정정주문이 없으므로 1번 타이머 재셋팅. Main.SetTimer(1, 10000); } } //2번 타이머 실행. if (nEventID == 2) { //2번 타이머 종료. Main.KillTimer(2); //BXNum 주문번호의 미체결객체 셋팅 Account1.SetUnfillOrderNumber(BXNum); //현재가 저장 var CC = MarketData1.current; //미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { //가격을 현재가로 정정하여 정정주문. 정정주문 후 주문응답시 BXNum새로 갱신하고 타이머 재셋팅. BXID = Account1.OrderReplacePrice(BXNum, MarketData1.current); } //미체결수량이 존재하나, 미체결가격과 현재가격이 같다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //정정주문이 없으므로 2번 타이머 재셋팅. Main.SetTimer(2, 10000); } } //3번 타이머 실행 if (nEventID == 3) { //3번 타이머 종료 Main.KillTimer(3); //SNum 주문번호의 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SNum); //현재가 저장 var CC = MarketData1.current; //미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { //가격을 현재가로 정정하여 정정주문. 정정주문후 주문응답시 SNum새로 갱신하고 타이머 재셋팅. SID = Account1.OrderReplacePrice(SNum, MarketData1.current); } //미체결수량이 존재하나, 미체결가격과 현재가격이 같다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //정정주문이 없으므로 3번 타이머 재셋팅. Main.SetTimer(3, 10000); } } //4번 타이머 실행 if (nEventID == 4) { //4번 타이머 종료 Main.KillTimer(4); //SXNum 주문번호의 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SXNum); //현재가 저장 var CC = MarketData1.current; //미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { //가격을 현재가로 정정하여 정정주문. 정정주문 후 주문응답시 SXNum새로 갱신하고 타이머 재셋팅. SXID = Account1.OrderReplacePrice(SXNum, MarketData1.current); } //미체결수량이 존재하나, 미체결가격과 현재가격이 같다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //정정주문이 없으므로 4번 타이머 재셋팅. Main.SetTimer(4, 10000); } } } function Main_OnNotifyFill(NotifyFill) { //"NotifyFill" 출력. //Main.MessageLog("NotifyFill"); //BNum 주문 체결되면, if (NotifyFill.orderNum == BNum) { //1번 타이머 종료. Main.KillTimer(1); //BNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(BNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify Long" 출력. Main.MessageLog("Notify Long"); } } //BXNum 주문 체결되면, if (NotifyFill.orderNum == BXNum) { //2번 타이머 종료. Main.KillTimer(2); //BXNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(BXNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify ExitLong" 출력. Main.MessageLog("Notify ExitLong"); } } //SNum 주문 체결되면, if (NotifyFill.orderNum == SNum) { //1번 타이머 종료. Main.KillTimer(3); //SNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify Short" 출력. Main.MessageLog("Notify Short"); } } //SXNum 주문 체결되면, if (NotifyFill.orderNum == SXNum) { //4번 타이머 종료. Main.KillTimer(4); //SXNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SXNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify ExitShort" 출력. Main.MessageLog("Notify ExitShort"); } } }
프로필 이미지

예스스탁 예스스탁 답변

2017-12-19 17:15:29

안녕하세요 예스스탁입니다. 1 시장가로 변경하고자 하시면 주문함수의 3번째와 4번째 매개변수를 변경해 주시면 됩니다. 시장가이므로 주문가격은 0, 주문구분은 1로 변경해 주시면 됩니다. 2 시장가는 가격을 지정하지 않고 수량만 지정해 내는 주문입니다. 거의 상하한가 주문과 비슷하다고 보시면 됩니다. 지정가보다 증거금이 더 많이 필요하므로 증거금이 충분하지 않으면 주분거부될수 있습니다. 3 지정가 주문은 주문후 미체결시 가격정정등이 가능하지만 시장가는 주문정정이 가능하지 않습니다. 시장가 주문은 자체가 체결을 위해 최상의 우선순위를 가지게 하는 주문이기에 취소주문만 되고 정정주문이 가능하 주문이 아닙니다. 그러므로 수식상 정정 주문하는 코딩자체가 의미가 없습니다. 즐거운 하루되세요 > yanartas 님이 쓴 글입니다. > 제목 : 추가질문입니다. > 한가지 추가 질문을 드립니다. 주문을 현재가가 아닌 시장가로 하고싶고, 나머지 로직은 똑같이 가져가고 싶습니다. 즉, 예스스팟 시작시 현재 계좌의 포지션을 살피고, 포지션이 없으면 다음 진입신호부터 진입하고, 포지션이 있다면 해당 포지션의 청산부터 실행됩니다. 미체결이 발생했을 경우 10초간격으로 체크를 하여, 진입한 가격과 다들 경우만 가격을 현시점의 가격으로 정정하여 주문을 냅니다. 정정부분도 현재가를 사용하는 경우와 시장가를 사용하는 경우가 다른가요? 현재 코딩은 현재가로 되어있는데 그 당시의 시장가로 진입하게 만들고 싶습니다. 그런데 궁금한점이 봉이 완성된 시점에 시장가로 주문을 넣는 것과, 봉이 왼선된 시점에 현재가로 주문을 넣는 것이 어떤 차이가 있나요? 제가 작성한 프로그램은 다음과 같습니다. 확인부탁드리고, 수정할 부분이 있다면 고쳐주시기바랍니다. 감사합니다. var Position; var OrderCode; var BID, BXID, SID, SXID; var BNum, BXNum, SNum, SXNum; function Main_OnStart() { //"OnStart" 출력. //Main.MessageLog("Start"); //시스템을 연결선물에 적용. 따라서 주문용 종목코드를 리턴받아 OrderCode에 저장. OrderCode = Main.GetOrderCode(MarketData1.code); //OrderCode종목 잔고셋팅. Account1.SetBalance(OrderCode, 0); //현재 포지션이 매도나 매수가 아니라면, if (Account1.Balance.position != 1 && Account1.Balance.position != 2) { //Position에 0 대입. Position = 0; //"Current Zero" 출력. Main.MessageLog("Current Zero"); } //현재 포지션이 매도라면, if (Account1.Balance.position == 1) { //Position에 -1 대입. Position = -1; //"Current Short" 출력. Main.MessageLog("Current Short"); } //현재 포지션이 매수라면, if (Account1.Balance.position == 2) { //Position에 1 대입. Position = 1; //"Current Long" 출력. Main.MessageLog("Current Long"); } } function Chart1_OnRiseSignal(Signal) { //완성된 시그널 출력. //Main.MessageLog("Signal : "+Signal.signalKind); //Position가 0이고, 시그널 종류가 매수라면, if (Position == 0 && Signal.signalKind == 1) { //Position에 1 대입. Position = 1; //주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Buy 주문, BID에 주문식별번호 저장. //BID = Account1.OrderBuy(OrderCode, Signal.count, MarketData1.current, 0); //주문형 종목코드로, 시스템에서 지정한 수량만큼, 시장가로 Buy 주문, BID에 주문식별번호 저장. BID = Account1.OrderBuy(OrderCode, Signal.count, 0,1); //"Long" 출력 Main.MessageLog("Long"); } //Position이 1이고, 시그널 종류가 매수청산이라면, if (Position == 1 && Signal.signalKind == 2) { //Position에 0 대입. Position = 0; //주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Sell 주문, BXID에 주문식별번호 저장. //BXID = Account1.OrderSell(OrderCode, Signal.count, MarketData1.current, 0); //주문형 종목코드로, 시스템에서 지정한 수량만큼, 시장가로 Sell 주문, BXID에 주문식별번호 저장. BXID = Account1.OrderSell(OrderCode, Signal.count, 0, 1); //"ExitLong" 출력 Main.MessageLog("ExitLong"); } //Position이 0이고, 시그널 종류가 매도라면, if (Position == 0 && Signal.signalKind == 3) { //Position에 -1 대입. Position = -1; //주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Sell 주문, SID에 주문식별번호 저장. //SID = Account1.OrderSell(OrderCode, Signal.count, MarketData1.current, 0); //주문형 종목코드로, 시스템에서 지정한 수량만큼, 시장가로 Sell 주문, SID에 주문식별번호 저장. SID = Account1.OrderSell(OrderCode, Signal.count, 0, 1); //"Short" 출력 Main.MessageLog("Short"); } //Position이 -1이고, 시그널 종류가 매도청산이라면, if (Position == -1 && Signal.signalKind == 4) { //Position에 0 대입 Position = 0; //주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Buy 주문, SXID에 주문식별번호 저장. //SXID = Account1.OrderBuy(OrderCode, Signal.count, MarketData1.current, 0); //주문형 종목코드로, 시스템에서 지정한 수량만큼, 시장가로 Buy 주문, SXID에 주문식별번호 저장. SXID = Account1.OrderBuy(OrderCode, Signal.count, 0, 1); //"ExitShort" 출력 Main.MessageLog("ExigShort"); } } function Main_OnOrderResponse(OrderResponse) { //해당 주문응답이 Long신호에 대한 주문응답이라면, if (OrderResponse.orderID == BID) { //BNum에 주문응답객체의 주문번호를 저장하고, BNum = OrderResponse.orderNum; //1번 타이머 실행(10초 간격). Main.SetTimer(1, 10000); } //해당 주문응답이 ExitLong신호에 대한 주문응답이라면, if (OrderResponse.orderID == BXID) { //BXNum에 주문응답객체의 주문번호를 저장하고, BXNum = OrderResponse.orderNum; //2번 타이머 실행(10초 간격). Main.SetTimer(2, 10000); } //해당 주문응답이 Short신호에 대한 주문응답이라면, if (OrderResponse.orderID == SID) { //SNum에 주문응답객체의 주문번호를 저장하고, SNum = OrderResponse.orderNum; //3번 타이머 실행(10초 간격). Main.SetTimer(3, 10000); } //해당 주문응답이 ExitShort신호에 대한 주문응답이라면, if (OrderResponse.orderID == SXID) { //SXNum에 주문응답객체의 주문번호를 저장하고, SXNum = OrderResponse.orderNum; //4번 타이머 실행(10초 간격). Main.SetTimer(4, 10000); } } function Main_OnTimer(nEventID) { //1번 타이머 실행. if (nEventID == 1) { //1번 타이머 종료. Main.KillTimer(1); //BNum 주문번호의 미체결객체 셋팅. Account1.SetUnfillOrderNumber(BNum); //현재가 저장 var CC = MarketData1.current; //미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { //가격을 현재가로 정정하여 정정주문. 정정주문 후 주문응답시 BNum 새로 갱신하고 타이머 재셋팅. BID = Account1.OrderReplacePrice(BNum, CC); } //미체결수량이 존재하나, 미체결가격과 현재가격이 같다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //정정주문이 없으므로 1번 타이머 재셋팅. Main.SetTimer(1, 10000); } } //2번 타이머 실행. if (nEventID == 2) { //2번 타이머 종료. Main.KillTimer(2); //BXNum 주문번호의 미체결객체 셋팅 Account1.SetUnfillOrderNumber(BXNum); //현재가 저장 var CC = MarketData1.current; //미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { //가격을 현재가로 정정하여 정정주문. 정정주문 후 주문응답시 BXNum새로 갱신하고 타이머 재셋팅. BXID = Account1.OrderReplacePrice(BXNum, MarketData1.current); } //미체결수량이 존재하나, 미체결가격과 현재가격이 같다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //정정주문이 없으므로 2번 타이머 재셋팅. Main.SetTimer(2, 10000); } } //3번 타이머 실행 if (nEventID == 3) { //3번 타이머 종료 Main.KillTimer(3); //SNum 주문번호의 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SNum); //현재가 저장 var CC = MarketData1.current; //미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { //가격을 현재가로 정정하여 정정주문. 정정주문후 주문응답시 SNum새로 갱신하고 타이머 재셋팅. SID = Account1.OrderReplacePrice(SNum, MarketData1.current); } //미체결수량이 존재하나, 미체결가격과 현재가격이 같다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //정정주문이 없으므로 3번 타이머 재셋팅. Main.SetTimer(3, 10000); } } //4번 타이머 실행 if (nEventID == 4) { //4번 타이머 종료 Main.KillTimer(4); //SXNum 주문번호의 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SXNum); //현재가 저장 var CC = MarketData1.current; //미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { //가격을 현재가로 정정하여 정정주문. 정정주문 후 주문응답시 SXNum새로 갱신하고 타이머 재셋팅. SXID = Account1.OrderReplacePrice(SXNum, MarketData1.current); } //미체결수량이 존재하나, 미체결가격과 현재가격이 같다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //정정주문이 없으므로 4번 타이머 재셋팅. Main.SetTimer(4, 10000); } } } function Main_OnNotifyFill(NotifyFill) { //"NotifyFill" 출력. //Main.MessageLog("NotifyFill"); //BNum 주문 체결되면, if (NotifyFill.orderNum == BNum) { //1번 타이머 종료. Main.KillTimer(1); //BNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(BNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify Long" 출력. Main.MessageLog("Notify Long"); } } //BXNum 주문 체결되면, if (NotifyFill.orderNum == BXNum) { //2번 타이머 종료. Main.KillTimer(2); //BXNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(BXNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify ExitLong" 출력. Main.MessageLog("Notify ExitLong"); } } //SNum 주문 체결되면, if (NotifyFill.orderNum == SNum) { //1번 타이머 종료. Main.KillTimer(3); //SNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify Short" 출력. Main.MessageLog("Notify Short"); } } //SXNum 주문 체결되면, if (NotifyFill.orderNum == SXNum) { //4번 타이머 종료. Main.KillTimer(4); //SXNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SXNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify ExitShort" 출력. Main.MessageLog("Notify ExitShort"); } } }