커뮤니티

질문입니다.

프로필 이미지
yanartas
2018-02-20 11:20:28
2808
글번호 224341
답변완료
현재 선물 1계약을 운용하고 있습니다. 예스트레이더로 시스템을 작성하였고, 예스스팟으로 주문을 컨트롤하고 있습니다. 간단히 설명을 드리면 다음과 같습니다. 예스스팟 구동시 현재의 계좌상황을 파악하게됩니다. 현재 포지션이 없는지 있는지, 있다면 롱포지션인지 숏포지션인지 판단합니다. 그리고 예스트레이더에서 신호가 발생하면, 예스스팟으로 실행합니다. 만약 체결되지 않는다면 5초마다 정정거래를 발생시킵니다. 여기까지 적성되어 있습니다. 질문입니다. 예스트레이더 선물거래시스템을 3계약으로 늘릴려고합니다. 피라미딩으로 말이죠. 예를들어 1계약 매수진입 후 추가조건을 만족하면 1계약추가진입하고(총2계약), 또다시 추가조건진입을 만족하면 1계약추가진입합니다(총3계약). 매도쪽도 마찬가지입니다. 예스트레이더 시스템은 완성하였습니다. 이를 예스스팟으로 신호를 컨트롤하고자 합니다. 예스스팟 로직은 다음과 같이 구성하고 싶습니다. 처음 예스스팟 구동 시 현재 포지션의 상황을 파악합니다. 포지션이 없는지 있는지, 있다면 롱포지션인지 숏포지션인지, 그리고 추가사항이 현재포지션에서 진입한 계약수가 몇개인지 파악하고 싶습니다. 그리고 피라미딩 진입도 예스스팟으로 컨트롤하고 싶습니다. 예를들어 매수1계약 진입을 "Long1"으로 명명한다면, 추가1계약진입 시 "Long2"로 명명하고, 여기서 추가1계약진입 시 "Long3"로 명명하고 싶습니다. 매수청산도 각각 "Exit Long1", "Exit Long2", "Exit Long3"으로 명명하고 싶습니다. 매도쪽도 마찬가지입니다. 피라미딩 진입도 초기1계약진입과 마찬가지로 정정주문을 5초마다 현재가를 갱신하며 정정하고 싶습니다. 현재사용하고 있는 예스스팟을 올립니다. 아직 예스스팟에 익숙치못해 그러니, 상세한 주석과 함께 부탁드립니다. 감사합니다. 예스스팟 //yT7 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); //"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); //"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); //"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); //"ExitShort" 출력 Main.MessageLog("ExigShort"); } } function Main_OnOrderResponse(OrderResponse) { //해당 주문응답이 Long신호에 대한 주문응답이라면, if (OrderResponse.orderID == BID) { //BNum에 주문응답객체의 주문번호를 저장하고, BNum = OrderResponse.orderNum; //1번 타이머 실행(5초 간격). Main.SetTimer(1, 5000); } //해당 주문응답이 ExitLong신호에 대한 주문응답이라면, if (OrderResponse.orderID == BXID) { //BXNum에 주문응답객체의 주문번호를 저장하고, BXNum = OrderResponse.orderNum; //2번 타이머 실행(5초 간격). Main.SetTimer(2, 5000); } //해당 주문응답이 Short신호에 대한 주문응답이라면, if (OrderResponse.orderID == SID) { //SNum에 주문응답객체의 주문번호를 저장하고, SNum = OrderResponse.orderNum; //3번 타이머 실행(5초 간격). Main.SetTimer(3, 5000); } //해당 주문응답이 ExitShort신호에 대한 주문응답이라면, if (OrderResponse.orderID == SXID) { //SXNum에 주문응답객체의 주문번호를 저장하고, SXNum = OrderResponse.orderNum; //4번 타이머 실행(5초 간격). Main.SetTimer(4, 5000); } } 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, 5000); } } //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, 5000); } } //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, 5000); } } //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("N.Long"); } } //BXNum 주문 체결되면, if (NotifyFill.orderNum == BXNum) { //2번 타이머 종료. Main.KillTimer(2); //BXNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(BXNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify ExitLong" 출력. Main.MessageLog("N.ExitLong"); } } //SNum 주문 체결되면, if (NotifyFill.orderNum == SNum) { //1번 타이머 종료. Main.KillTimer(3); //SNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify Short" 출력. Main.MessageLog("N.Short"); } } //SXNum 주문 체결되면, if (NotifyFill.orderNum == SXNum) { //4번 타이머 종료. Main.KillTimer(4); //SXNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SXNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify ExitShort" 출력. Main.MessageLog("N.ExitShort"); } } }
답변 1
프로필 이미지

예스스탁 예스스탁 답변

2018-03-12 16:33:36

안녕하세요 예스스탁입니다. 아래 내용 참고하셔서 수정보완해 사용하시기 바랍니다. var Position; var OrderCode; var BID1,BID2,BID3,BXID, SID1,SID2,SID3, SXID; var BNum1,BNum2,BBum3,BXNum, SNum1,SNum2,SNum3,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에 -(잔수수량) 대입. Position = -(Account1.Balance.count); //"Current Short" 출력. Main.MessageLog("Current Short"+Position); } //현재 포지션이 매수라면, if (Account1.Balance.position == 2) { //Position에 잔고수량 대입. Position = Account1.Balance.count; //"Current Long" 출력. Main.MessageLog("Current Long"+Position); } } function Chart1_OnRiseSignal(Signal) { //완성된 시그널 출력. //Main.MessageLog("Signal : "+Signal.signalKind); //Position가 0이고, 시그널 종류가 매수라면, if (Position >= 0 && Position < 3 && Signal.signalKind == 1) { //Position에 1 대입. Position = Position+1; if (Position == 1) { //주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Buy 주문, BID에 주문식별번호 저장. BID1 = Account1.OrderBuy(OrderCode, Signal.count, MarketData1.current, 0); //"Long" 출력 Main.MessageLog("Long1"); } if (Position == 2) { //주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Buy 주문, BID에 주문식별번호 저장. BID2 = Account1.OrderBuy(OrderCode, Signal.count, MarketData1.current, 0); //"Long" 출력 Main.MessageLog("Long2"); } if (Position == 3) { //주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Buy 주문, BID에 주문식별번호 저장. BID3 = Account1.OrderBuy(OrderCode, Signal.count, MarketData1.current, 0); //"Long" 출력 Main.MessageLog("Long3"); } } //Position이 1이고, 시그널 종류가 매수청산이라면, if (Position >= 1 && Signal.signalKind == 2) { //Position에 0 대입. Position = 0; //주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Sell 주문, BXID에 주문식별번호 저장. BXID = Account1.OrderSell(OrderCode, Signal.count, MarketData1.current, 0); //"ExitLong" 출력 Main.MessageLog("ExitLong"); } //Position이 0이고, 시그널 종류가 매도라면, if (Position <= 0 && Position > -3 && Signal.signalKind == 3) { //Position에 -1 대입. Position = Position -1; if (Position == -1) { //주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Sell 주문, SID에 주문식별번호 저장. SID1 = Account1.OrderSell(OrderCode, Signal.count, MarketData1.current, 0); //"Short" 출력 Main.MessageLog("Short1"); } if (Position == -2) { //주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Sell 주문, SID에 주문식별번호 저장. SID2 = Account1.OrderSell(OrderCode, Signal.count, MarketData1.current, 0); //"Short" 출력 Main.MessageLog("Short2"); } if (Position == -3) { //주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Sell 주문, SID에 주문식별번호 저장. SID3 = Account1.OrderSell(OrderCode, Signal.count, MarketData1.current, 0); //"Short" 출력 Main.MessageLog("Short3"); } } //Position이 -1이고, 시그널 종류가 매도청산이라면, if (Position == -1 && Signal.signalKind == 4) { //Position에 0 대입 Position = 0; //주문형 종목코드로, 시스템에서 지정한 수량만큼, 현재가로 Buy 주문, SXID에 주문식별번호 저장. SXID = Account1.OrderBuy(OrderCode, Signal.count, MarketData1.current, 0); //"ExitShort" 출력 Main.MessageLog("ExigShort"); } } function Main_OnOrderResponse(OrderResponse) { //해당 주문응답이 Long신호에 대한 주문응답이라면, if (OrderResponse.orderID == BID1) { //BNum1에 주문응답객체의 주문번호를 저장하고, BNum1 = OrderResponse.orderNum; //11번 타이머 실행(5초 간격). Main.SetTimer(11, 5000); } //해당 주문응답이 Long신호에 대한 주문응답이라면, if (OrderResponse.orderID == BID2) { //BNum2에 주문응답객체의 주문번호를 저장하고, BNum2 = OrderResponse.orderNum; //12번 타이머 실행(5초 간격). Main.SetTimer(12, 5000); } //해당 주문응답이 Long신호에 대한 주문응답이라면, if (OrderResponse.orderID == BID3) { //BNum3에 주문응답객체의 주문번호를 저장하고, BNum3 = OrderResponse.orderNum; //13번 타이머 실행(5초 간격). Main.SetTimer(13, 5000); } //해당 주문응답이 ExitLong신호에 대한 주문응답이라면, if (OrderResponse.orderID == BXID) { //BXNum에 주문응답객체의 주문번호를 저장하고, BXNum = OrderResponse.orderNum; //2번 타이머 실행(5초 간격). Main.SetTimer(2, 5000); } //해당 주문응답이 Short신호에 대한 주문응답이라면, if (OrderResponse.orderID == SID1) { //SNum1에 주문응답객체의 주문번호를 저장하고, SNum1 = OrderResponse.orderNum; //31번 타이머 실행(5초 간격). Main.SetTimer(31, 5000); } if (OrderResponse.orderID == SID2) { //SNum2에 주문응답객체의 주문번호를 저장하고, SNum2 = OrderResponse.orderNum; //32번 타이머 실행(5초 간격). Main.SetTimer(32, 5000); } if (OrderResponse.orderID == SID3) { //SNum3에 주문응답객체의 주문번호를 저장하고, SNum3 = OrderResponse.orderNum; //33번 타이머 실행(5초 간격). Main.SetTimer(33, 5000); } //해당 주문응답이 ExitShort신호에 대한 주문응답이라면, if (OrderResponse.orderID == SXID) { //SXNum에 주문응답객체의 주문번호를 저장하고, SXNum = OrderResponse.orderNum; //4번 타이머 실행(5초 간격). Main.SetTimer(4, 5000); } } function Main_OnTimer(nEventID) { //11번 타이머 실행. if (nEventID == 1) { //11번 타이머 종료. Main.KillTimer(11); //BNum1 주문번호의 미체결객체 셋팅. Account1.SetUnfillOrderNumber(BNum1); //현재가 저장 var CC = MarketData1.current; //미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { //가격을 현재가로 정정하여 정정주문. 정정주문 후 주문응답시 BNum1 새로 갱신하고 타이머 재셋팅. BID1 = Account1.OrderReplacePrice(BNum1, CC); } //미체결수량이 존재하나, 미체결가격과 현재가격이 같다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //정정주문이 없으므로 1번 타이머 재셋팅. Main.SetTimer(11, 5000); } } //12번 타이머 실행. if (nEventID == 12) { //12번 타이머 종료. Main.KillTimer(12); //BNum2 주문번호의 미체결객체 셋팅. Account1.SetUnfillOrderNumber(BNum2); //현재가 저장 var CC = MarketData1.current; //미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { //가격을 현재가로 정정하여 정정주문. 정정주문 후 주문응답시 BNum2 새로 갱신하고 타이머 재셋팅. BID2 = Account1.OrderReplacePrice(BNum2, CC); } //미체결수량이 존재하나, 미체결가격과 현재가격이 같다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //정정주문이 없으므로 12번 타이머 재셋팅. Main.SetTimer(12, 5000); } } //13번 타이머 실행. if (nEventID == 13) { //13번 타이머 종료. Main.KillTimer(13); //BNum2 주문번호의 미체결객체 셋팅. Account1.SetUnfillOrderNumber(BNum3); //현재가 저장 var CC = MarketData1.current; //미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { //가격을 현재가로 정정하여 정정주문. 정정주문 후 주문응답시 BNum3 새로 갱신하고 타이머 재셋팅. BID3 = Account1.OrderReplacePrice(BNum3, CC); } //미체결수량이 존재하나, 미체결가격과 현재가격이 같다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //정정주문이 없으므로 13번 타이머 재셋팅. Main.SetTimer(13, 5000); } } //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, 5000); } } //31번 타이머 실행 if (nEventID == 31) { //31번 타이머 종료 Main.KillTimer(31); //SNum 주문번호의 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SNum1); //현재가 저장 var CC = MarketData1.current; //미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { //가격을 현재가로 정정하여 정정주문. 정정주문후 주문응답시 SNum1새로 갱신하고 타이머 재셋팅. SID1 = Account1.OrderReplacePrice(SNum1, MarketData1.current); } //미체결수량이 존재하나, 미체결가격과 현재가격이 같다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //정정주문이 없으므로 31번 타이머 재셋팅. Main.SetTimer(31, 5000); } } //32번 타이머 실행 if (nEventID == 32) { //32번 타이머 종료 Main.KillTimer(32); //SNum 주문번호의 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SNum2); //현재가 저장 var CC = MarketData1.current; //미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { //가격을 현재가로 정정하여 정정주문. 정정주문후 주문응답시 SNum2새로 갱신하고 타이머 재셋팅. SID2 = Account1.OrderReplacePrice(SNum2, MarketData1.current); } //미체결수량이 존재하나, 미체결가격과 현재가격이 같다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //정정주문이 없으므로 32번 타이머 재셋팅. Main.SetTimer(32, 5000); } } //33번 타이머 실행 if (nEventID == 33) { //33번 타이머 종료 Main.KillTimer(33); //SNum 주문번호의 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SNum3); //현재가 저장 var CC = MarketData1.current; //미체결수량이 존재하고, 미체결가격이 현재가와 다르다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price != CC) { //가격을 현재가로 정정하여 정정주문. 정정주문후 주문응답시 SNum3새로 갱신하고 타이머 재셋팅. SID3 = Account1.OrderReplacePrice(SNum3, MarketData1.current); } //미체결수량이 존재하나, 미체결가격과 현재가격이 같다면, if (Account1.Unfill.count > 0 && Account1.Unfill.price == CC) { //정정주문이 없으므로 33번 타이머 재셋팅. Main.SetTimer(33, 5000); } } //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"); //BNum1 주문 체결되면, if (NotifyFill.orderNum == BNum1) { //11번 타이머 종료. Main.KillTimer(11); //BNum1 미체결객체 셋팅 Account1.SetUnfillOrderNumber(BNum1); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify Long" 출력. Main.MessageLog("N.Long1"); } } //BNum2 주문 체결되면, if (NotifyFill.orderNum == BNum2) { //12번 타이머 종료. Main.KillTimer(12); //BNum2 미체결객체 셋팅 Account1.SetUnfillOrderNumber(BNum2); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify Long" 출력. Main.MessageLog("N.Long2"); } } //BNum3 주문 체결되면, if (NotifyFill.orderNum == BNum3) { //13번 타이머 종료. Main.KillTimer(13); //BNum3 미체결객체 셋팅 Account1.SetUnfillOrderNumber(BNum3); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify Long" 출력. Main.MessageLog("N.Long3"); } } //BXNum 주문 체결되면, if (NotifyFill.orderNum == BXNum) { //2번 타이머 종료. Main.KillTimer(2); //BXNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(BXNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify ExitLong" 출력. Main.MessageLog("N.ExitLong"); } } //SNum1 주문 체결되면, if (NotifyFill.orderNum == SNum1) { //31번 타이머 종료. Main.KillTimer(31); //SNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SNum1); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify Short1" 출력. Main.MessageLog("N.Short1"); } } //SNum2 주문 체결되면, if (NotifyFill.orderNum == SNum2) { //32번 타이머 종료. Main.KillTimer(32); //SNum2 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SNum2); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify Short2" 출력. Main.MessageLog("N.Short2"); } } //SNum3 주문 체결되면, if (NotifyFill.orderNum == SNum3) { //33번 타이머 종료. Main.KillTimer(33); //SNum3 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SNum3); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify Short3" 출력. Main.MessageLog("N.Short3"); } } //SXNum 주문 체결되면, if (NotifyFill.orderNum == SXNum) { //4번 타이머 종료. Main.KillTimer(4); //SXNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SXNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify ExitShort" 출력. Main.MessageLog("N.ExitShort"); } } } 즐거운 하루되세요 > yanartas 님이 쓴 글입니다. > 제목 : 질문입니다. > 현재 선물 1계약을 운용하고 있습니다. 예스트레이더로 시스템을 작성하였고, 예스스팟으로 주문을 컨트롤하고 있습니다. 간단히 설명을 드리면 다음과 같습니다. 예스스팟 구동시 현재의 계좌상황을 파악하게됩니다. 현재 포지션이 없는지 있는지, 있다면 롱포지션인지 숏포지션인지 판단합니다. 그리고 예스트레이더에서 신호가 발생하면, 예스스팟으로 실행합니다. 만약 체결되지 않는다면 5초마다 정정거래를 발생시킵니다. 여기까지 적성되어 있습니다. 질문입니다. 예스트레이더 선물거래시스템을 3계약으로 늘릴려고합니다. 피라미딩으로 말이죠. 예를들어 1계약 매수진입 후 추가조건을 만족하면 1계약추가진입하고(총2계약), 또다시 추가조건진입을 만족하면 1계약추가진입합니다(총3계약). 매도쪽도 마찬가지입니다. 예스트레이더 시스템은 완성하였습니다. 이를 예스스팟으로 신호를 컨트롤하고자 합니다. 예스스팟 로직은 다음과 같이 구성하고 싶습니다. 처음 예스스팟 구동 시 현재 포지션의 상황을 파악합니다. 포지션이 없는지 있는지, 있다면 롱포지션인지 숏포지션인지, 그리고 추가사항이 현재포지션에서 진입한 계약수가 몇개인지 파악하고 싶습니다. 그리고 피라미딩 진입도 예스스팟으로 컨트롤하고 싶습니다. 예를들어 매수1계약 진입을 "Long1"으로 명명한다면, 추가1계약진입 시 "Long2"로 명명하고, 여기서 추가1계약진입 시 "Long3"로 명명하고 싶습니다. 매수청산도 각각 "Exit Long1", "Exit Long2", "Exit Long3"으로 명명하고 싶습니다. 매도쪽도 마찬가지입니다. 피라미딩 진입도 초기1계약진입과 마찬가지로 정정주문을 5초마다 현재가를 갱신하며 정정하고 싶습니다. 현재사용하고 있는 예스스팟을 올립니다. 아직 예스스팟에 익숙치못해 그러니, 상세한 주석과 함께 부탁드립니다. 감사합니다. 예스스팟 //yT7 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); //"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); //"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); //"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); //"ExitShort" 출력 Main.MessageLog("ExigShort"); } } function Main_OnOrderResponse(OrderResponse) { //해당 주문응답이 Long신호에 대한 주문응답이라면, if (OrderResponse.orderID == BID) { //BNum에 주문응답객체의 주문번호를 저장하고, BNum = OrderResponse.orderNum; //1번 타이머 실행(5초 간격). Main.SetTimer(1, 5000); } //해당 주문응답이 ExitLong신호에 대한 주문응답이라면, if (OrderResponse.orderID == BXID) { //BXNum에 주문응답객체의 주문번호를 저장하고, BXNum = OrderResponse.orderNum; //2번 타이머 실행(5초 간격). Main.SetTimer(2, 5000); } //해당 주문응답이 Short신호에 대한 주문응답이라면, if (OrderResponse.orderID == SID) { //SNum에 주문응답객체의 주문번호를 저장하고, SNum = OrderResponse.orderNum; //3번 타이머 실행(5초 간격). Main.SetTimer(3, 5000); } //해당 주문응답이 ExitShort신호에 대한 주문응답이라면, if (OrderResponse.orderID == SXID) { //SXNum에 주문응답객체의 주문번호를 저장하고, SXNum = OrderResponse.orderNum; //4번 타이머 실행(5초 간격). Main.SetTimer(4, 5000); } } 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, 5000); } } //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, 5000); } } //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, 5000); } } //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("N.Long"); } } //BXNum 주문 체결되면, if (NotifyFill.orderNum == BXNum) { //2번 타이머 종료. Main.KillTimer(2); //BXNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(BXNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify ExitLong" 출력. Main.MessageLog("N.ExitLong"); } } //SNum 주문 체결되면, if (NotifyFill.orderNum == SNum) { //1번 타이머 종료. Main.KillTimer(3); //SNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify Short" 출력. Main.MessageLog("N.Short"); } } //SXNum 주문 체결되면, if (NotifyFill.orderNum == SXNum) { //4번 타이머 종료. Main.KillTimer(4); //SXNum 미체결객체 셋팅 Account1.SetUnfillOrderNumber(SXNum); //미체결 수량이 없으면 if (Account1.Unfill.count == 0) { //"Notify ExitShort" 출력. Main.MessageLog("N.ExitShort"); } } }