커뮤니티

호가로 주문후 체결신호를 리턴받으면 다음 종목을 매수하는식과 간단한 오류 수정 부탁드립니다

프로필 이미지
자유를찾아
2015-09-23 13:32:30
2064
글번호 223660
답변완료
안녕하세요 예스 랭기지를 사용하다가 이번에 스팟을 배우게 되었습니다. 그런데 객체 지향 언어에 익숙 하지 않아서 그런지 좀 많이 어렵 습니다. 아래와 같이 간단히 두종목을 비교하여 매수 매도 하는 수식을 짰는데 돌아가지 않습니다. 먼저 제가 작성한 수식을 설명 드리면 Market_L과 Market_S의 값을 가져와 두값을 뺀 Spread_net_C가 현제의 값이 두값을 뺀값으로 20봉의 평균한 Spread_Avr값보다 작으면 커지는 쪽으로 두종목이 서로 반대 방향으로 진입을 한후 두 포지션을 입력하고 청산은 두값의 합이 입력해놓은 원하는 이익값 이상이 되었을&#46468; 일괄로 청산을 하는 프로그램 입니다. 제 질문을 알아보시기 편하게 아래와 같이 순번을 달아 설명 했습니다. Q1. 어느 부분이 문제인지 수정 부탁 드립니다. Q2. 진입과 청산 식에 호가가 상대적으로 작아 체결이 어려운 Market_L 을 현제 호가로 주문하고 진입이 되었다는 신호가 확인되면 Market_S을 시장가로 진입 시켜 두종목을 동시에 보유하고 청산시에도 Market_L을 호가로 청산하고 청산이 확인되면 Market_S를 청산 하는식을 만들고싶은데 어떻게 해야할지 모르 겠습니다. 어떻게 하면 가능할지 도와 주세요~ Q3. Market_L과 Market_S를 뺀값에 평균값을 구하는 Spread_Avr 함수에 예스랭기지로 작성한 plot 값을 받아와 구동하게 하였는데 이러한 방법말고 예스스팟에서 바로 작성하여 구동하고 싶습니다. 방법을 알려주세요? (랭귀지에서는 Spread_Avr = ma(Market_S-Market_L , 20) 이렇게 만들었었습니다.) Q4. 위 질문 Q3과 같이 구동할 경우 예스 랭기지로 작성된 수식은 봉의 완료시에만 작동 하는 것으로 알고 있는데 제가 알고있는 것이 맞다면 빠르게 실시간으로 수식을 처리 하는 예스 스팟의 시스템과 맞지 않아 문제가 있을수 있을것 같습니다. 이런경우 주의해야 하는 부분이 있다면 알려주세요. ======================================================================================== var Spread_Avr, return_N,Spread_net_C,SP_MEMO ; /* Spread_Avr: 두값을 뺀값의 평균값을 넣는 변수 return_N: 이동평균을 구할때 몇봉의 이동평균을 구할지를 결정하는 변수로 사용하려했으나 지표 이름"J007_이동평균 값"에 plot2를 받아 사용하도록 아래 식을 구현 하였기 때문에 아래에서는 사용하지 않는 함수 Spread_net_C: 현제 두값을 뺀 값을 넣는 변수 SP_MEMO : 진입 당시 두값의 차를 기역하고 있다가 현제가와 비교하여 이익을 낼수있는 청산 시점인지를 비교하는 변수 */ function Main_OnStart() // 수식을 시작합니다. { Main.MessageLog("시작"); // 시작 이라고 출력 Start=0; //스타트 0 을 입력하여 진입신호없이 청산신호가 나가는것을 방지 } function C1_OnRiseSignal(Signal) { /* Market_S & Market_L 현제 두 값을 뺀값 측정 */ Spread_net_C= Market_S.current - Market_L.current; /* Market_S & Market_L의 두 값을 뺀값의 평균값 결정 */ Spread_Avr = C1.GetIndicatorData("J007_이동평균 값", 2,0); } //여기서 부터 진입식 function Main_OnRiseSignal(ChartEx, Signal) { If (A1.GetTheNumberOfBalances ==0) // 한주문만 들어가도록 A1 계좌에 주문이 없을때는 진입식만 주문이 있을때는 청산 식만 지켜봄 { if (spread_net_C>0) // Market_L 이 Market_S 보다 작으면 { SP_MEMO = spread_net_C ; // 두값의 차를 청산때 비교하기 위해 저장해둠 if (spread_net_C < spread_Avr - (PriceScale*Profit_N) //지금두 값의 차가 "평균치 - 기대수익" 보다 낮을경우 평균치 가까이 갈것으로 //예상하고 커지는 방향으로 진입 "Profit_N"은 외부변수로 설정 /* 아래 진입식은 단순 동시 진입 식이지만 Market_L의경우 물량이 많지않아 지정가로 진입하고 진입되었다는 확인 신호를 받으면 Market_S를 시장가로 진입하여 두종목을 모두 보유하도록(Q2) 수정하고 싶습니다. 도와주세요 */ { A1.OrderBuy(Market_S.code, Market_S_lot,Market_S.Bid(2),1); A1.OrderSell(Market_L.code, Market_L_lot, Market_L.Ask(2),1); } } // 여기서 부터 청산식 else if (A1.GetTheNumberOfBalances != 0)// 포지션이 있는경우 청산식 진입 { if (spread_net_C >= SP_MEMO - (PriceScale*Profit_N)) // 스프레드 증가방향 진입이고 수익만큼 충분히 증가 되었다면 /* 아래 청산식은 단순 동시 진입 식이지만 Market_L의경우 물량이 많지않아 지정가로 진입하고 진입되었다는 확인 신호를 받으면 Market_S를 시장가로 진입하여 두종목을 모두 보유하도록(Q2) 수정하고 싶습니다. 도와주세요 */ { A1.OrderSell (Market_S.code, Market_S_lot,Market_S.Ask(2),1); A1.OrderBuy(Market_L.code, Market_L_lot, Market_L.Bid(2),1); } } 바쁘신 중에도 이렇게 도와주셔서 감사합니다.
답변 1
프로필 이미지

예스스탁 예스스탁 답변

2015-09-30 17:51:17

안녕하세요 예스스탁입니다. 1. Spread_net_C와 Spread_Avr저장이 function C1_OnRiseSignal(Signal)이벤트에서 실행되고 있습니다. 실제 주문 실행코드는 function Main_OnRiseSignal(ChartEx, Signal) 확장차트이벤트에서 실행되는데 작성하신 의도가 C1차트에서 신호발생했을때 저장해서 사용하시는 경우가 맞다면 해당 코드 그대로 사용하시면 되고 확장차트 객체에서 신호발생시 그때의 차이값이면 function Main_OnRiseSignal(ChartEx, Signal) { /* Market_S & Market_L 현제 두 값을 뺀값 측정 */ Spread_net_C= Market_S.current - Market_L.current; /* Market_S & Market_L의 두 값을 뺀값의 평균값 결정 */ Spread_Avr = C1.GetIndicatorData("J007_이동평균 값", 2,0); 와 같이 확장차트 신호발생시 저장하게 하셔야 합니다. 2. Market_L이 체결될때 다른 하나를 주문넣게 하시면 됩니다. 아래의 내용으로 구현하시면 됩니다. 기존식에 지정가 주문이 매개변수가 1인것으로 판단해 해외선물용이신것 같습니다. 해외선물용으로 이해하고 주문함수의 주문구분값 지정했습니다. 국내는 지정가는 0, 시장가는 1입니다. 진입조건 만족시 Market_L 주문 --> 주문응답 이벤트에서 Market_L 주문응답 수신되면 주문번호 저장 --> 체결응답 이벤트에서 Market_L 체결응답 수신되면 Market_S 체결수량만큼 주문 var Spread_Avr, return_N,Spread_net_C,SP_MEMO ; /* Spread_Avr: 두값을 뺀값의 평균값을 넣는 변수 return_N: 이동평균을 구할때 몇봉의 이동평균을 구할지를 결정하는 변수로 사용하려했으나 지표 이름"J007_이동평균 값"에 plot2를 받아 사용하도록 아래 식을 구현 하였기 때문에 아래에서는 사용하지 않는 함수 Spread_net_C: 현제 두값을 뺀 값을 넣는 변수 SP_MEMO : 진입 당시 두값의 차를 기역하고 있다가 현제가와 비교하여 이익을 낼수있는 청산 시점인지를 비교하는 변수 */ function Main_OnStart() // 수식을 시작합니다. { Main.MessageLog("시작"); // 시작 이라고 출력 Start=0; //스타트 0 을 입력하여 진입신호없이 청산신호가 나가는것을 방지 } function C1_OnRiseSignal(Signal) { /* Market_S & Market_L 현제 두 값을 뺀값 측정 */ Spread_net_C= Market_S.current - Market_L.current; /* Market_S & Market_L의 두 값을 뺀값의 평균값 결정 */ Spread_Avr = C1.GetIndicatorData("J007_이동평균 값", 2,0); } function Main_OnRiseSignal(ChartEx, Signal) { If (A1.GetTheNumberOfBalances ==0) // 한주문만 들어가도록 A1 계좌에 주문이 없을때는 진입식만 주문이 있을때는 청산 식만 지켜봄 { if (spread_net_C>0) // Market_L 이 Market_S 보다 작으면 { SP_MEMO = spread_net_C ; // 두값의 차를 청산때 비교하기 위해 저장해둠 if (spread_net_C < spread_Avr - (PriceScale*Profit_N) { EntryID = A1.OrderSell(Market_L.code, Market_L_lot, Market_L.Ask(2),1); } } // 여기서 부터 청산식 else if (A1.GetTheNumberOfBalances != 0)// 포지션이 있는경우 청산식 진입 { if (spread_net_C >= SP_MEMO - (PriceScale*Profit_N)) { ExitID = A1.OrderBuy(Market_L.code, Market_L_lot, Market_L.Bid(2),1); } } } function Main_OnOrderResponse(OrderResponse) { if (OrderResponse.orderID == EntryID) { EntryNum = OrderResponse.orderNum; } if (OrderResponse.orderID == ExitID) { ExitNum = OrderResponse.orderNum; } } function Main_OnNotifyFill(NotifyFill) { if (NotifyFill.orderNum == EntryNum) { A1.OrderBuy(Market_S.code, NotifyFill.fillCount,0,2); } if (NotifyFill.orderNum == ExitNum) { A1.OrderSell(Market_S.code, NotifyFill.fillCount,0,2); } } 3. 봉단위로 판단되는 값은 차트에서 지표값으로만 받아오셔야 합니다. 스팟의 데이터는 실시간 틱으로 제공되므로 스팟에서 구현하시려면 일정시간 간격으로 값을 저장하셔야 하는데 스팟 적용이후부터 데이터가 제공되므로 이전일 데이터가 없고 사용하시는 차트주기로 계산하기는 복잡합니다. 이런이유로 일정시간 간격으로 값을 계산하는 경우에 지표로 간단히 가져올수 있게 기능이 제공되고 있습니다. 4. 예스랭귀지의 신호가 모두 봉완성시에만 발생되는 것은 아닙니다. 신호를 atstop이나 atlimit으로 작성하시면 봉미완성시 가격조건만 만족하면 신호가 미완성시에도 발생합니다. 수식에서 봉완성시는 if조건문을 말합니다. 신호타입이 onclose나 atmarket이면 봉완성시에만 확정신호가 발생합니다. 만약 예스랭귀지식을 onclose타입으로 작성하셨다면 미완성시에 if조건만족하면 예비신호가 발생합니다. OnRiseSignal은 완성신호가 발생할때 알려주는 이벤트이고 OnRiseIncompleteSignal이벤트가 미완성시 알려주는 이벤트입니다. 봉완성전에 처리하고자 하시면 미완성신호이벤트 사용을 고려해 보시면 됩니다. 다만 OnRiseIncompleteSignal 이벤트는 하나의 봉에서 많은 횟수가 발생하므로 시가수신후 첫번째 발생한 미완성신호만 이용하거나 혹은 특정시간이후에 첫번째 발생하는 미완성신호만 이용하는등 코딩에서 적절히 제어를 하셔야 합니다. 주문이 대량으로 반복적으로 나갈수 있습니다. 즐거운 하루되세요 > 자유를찾아 님이 쓴 글입니다. > 제목 : 호가로 주문후 체결신호를 리턴받으면 다음 종목을 매수하는식과 간단한 오류 수정 부탁드립니다 > 안녕하세요 예스 랭기지를 사용하다가 이번에 스팟을 배우게 되었습니다. 그런데 객체 지향 언어에 익숙 하지 않아서 그런지 좀 많이 어렵 습니다. 아래와 같이 간단히 두종목을 비교하여 매수 매도 하는 수식을 짰는데 돌아가지 않습니다. 먼저 제가 작성한 수식을 설명 드리면 Market_L과 Market_S의 값을 가져와 두값을 뺀 Spread_net_C가 현제의 값이 두값을 뺀값으로 20봉의 평균한 Spread_Avr값보다 작으면 커지는 쪽으로 두종목이 서로 반대 방향으로 진입을 한후 두 포지션을 입력하고 청산은 두값의 합이 입력해놓은 원하는 이익값 이상이 되었을&#46468; 일괄로 청산을 하는 프로그램 입니다. 제 질문을 알아보시기 편하게 아래와 같이 순번을 달아 설명 했습니다. Q1. 어느 부분이 문제인지 수정 부탁 드립니다. Q2. 진입과 청산 식에 호가가 상대적으로 작아 체결이 어려운 Market_L 을 현제 호가로 주문하고 진입이 되었다는 신호가 확인되면 Market_S을 시장가로 진입 시켜 두종목을 동시에 보유하고 청산시에도 Market_L을 호가로 청산하고 청산이 확인되면 Market_S를 청산 하는식을 만들고싶은데 어떻게 해야할지 모르 겠습니다. 어떻게 하면 가능할지 도와 주세요~ Q3. Market_L과 Market_S를 뺀값에 평균값을 구하는 Spread_Avr 함수에 예스랭기지로 작성한 plot 값을 받아와 구동하게 하였는데 이러한 방법말고 예스스팟에서 바로 작성하여 구동하고 싶습니다. 방법을 알려주세요? (랭귀지에서는 Spread_Avr = ma(Market_S-Market_L , 20) 이렇게 만들었었습니다.) Q4. 위 질문 Q3과 같이 구동할 경우 예스 랭기지로 작성된 수식은 봉의 완료시에만 작동 하는 것으로 알고 있는데 제가 알고있는 것이 맞다면 빠르게 실시간으로 수식을 처리 하는 예스 스팟의 시스템과 맞지 않아 문제가 있을수 있을것 같습니다. 이런경우 주의해야 하는 부분이 있다면 알려주세요. ======================================================================================== var Spread_Avr, return_N,Spread_net_C,SP_MEMO ; /* Spread_Avr: 두값을 뺀값의 평균값을 넣는 변수 return_N: 이동평균을 구할때 몇봉의 이동평균을 구할지를 결정하는 변수로 사용하려했으나 지표 이름"J007_이동평균 값"에 plot2를 받아 사용하도록 아래 식을 구현 하였기 때문에 아래에서는 사용하지 않는 함수 Spread_net_C: 현제 두값을 뺀 값을 넣는 변수 SP_MEMO : 진입 당시 두값의 차를 기역하고 있다가 현제가와 비교하여 이익을 낼수있는 청산 시점인지를 비교하는 변수 */ function Main_OnStart() // 수식을 시작합니다. { Main.MessageLog("시작"); // 시작 이라고 출력 Start=0; //스타트 0 을 입력하여 진입신호없이 청산신호가 나가는것을 방지 } function C1_OnRiseSignal(Signal) { /* Market_S & Market_L 현제 두 값을 뺀값 측정 */ Spread_net_C= Market_S.current - Market_L.current; /* Market_S & Market_L의 두 값을 뺀값의 평균값 결정 */ Spread_Avr = C1.GetIndicatorData("J007_이동평균 값", 2,0); } //여기서 부터 진입식 function Main_OnRiseSignal(ChartEx, Signal) { If (A1.GetTheNumberOfBalances ==0) // 한주문만 들어가도록 A1 계좌에 주문이 없을때는 진입식만 주문이 있을때는 청산 식만 지켜봄 { if (spread_net_C>0) // Market_L 이 Market_S 보다 작으면 { SP_MEMO = spread_net_C ; // 두값의 차를 청산때 비교하기 위해 저장해둠 if (spread_net_C < spread_Avr - (PriceScale*Profit_N) //지금두 값의 차가 "평균치 - 기대수익" 보다 낮을경우 평균치 가까이 갈것으로 //예상하고 커지는 방향으로 진입 "Profit_N"은 외부변수로 설정 /* 아래 진입식은 단순 동시 진입 식이지만 Market_L의경우 물량이 많지않아 지정가로 진입하고 진입되었다는 확인 신호를 받으면 Market_S를 시장가로 진입하여 두종목을 모두 보유하도록(Q2) 수정하고 싶습니다. 도와주세요 */ { A1.OrderBuy(Market_S.code, Market_S_lot,Market_S.Bid(2),1); A1.OrderSell(Market_L.code, Market_L_lot, Market_L.Ask(2),1); } } // 여기서 부터 청산식 else if (A1.GetTheNumberOfBalances != 0)// 포지션이 있는경우 청산식 진입 { if (spread_net_C >= SP_MEMO - (PriceScale*Profit_N)) // 스프레드 증가방향 진입이고 수익만큼 충분히 증가 되었다면 /* 아래 청산식은 단순 동시 진입 식이지만 Market_L의경우 물량이 많지않아 지정가로 진입하고 진입되었다는 확인 신호를 받으면 Market_S를 시장가로 진입하여 두종목을 모두 보유하도록(Q2) 수정하고 싶습니다. 도와주세요 */ { A1.OrderSell (Market_S.code, Market_S_lot,Market_S.Ask(2),1); A1.OrderBuy(Market_L.code, Market_L_lot, Market_L.Bid(2),1); } } 바쁘신 중에도 이렇게 도와주셔서 감사합니다.