커뮤니티

시스템 수식 문의드립니다.

프로필 이미지
깜피
2023-03-31 08:34:14.0
1237
글번호 225784
답변완료
안녕하세요. YL및 YS 게시판을 통해서 도움을 많이 주셔서 항상 감사합니다. 현재 YS로 거래 중인데 좀 더 정교하게 거래해 보고자 다시 도움을 청합니다. 저는 일봉 거래를 하는데 2회 분할 매수(각각 일봉 종가에 진입) 후 분할매도(장중 분할 매도 후 남은 물량은 종가 매도) 하는 형태로 진행이 되고 하루에 2~5종목 정도 매수하고 15~20일 정도 후 매도합니다. 보통 검색식으로 추출(일 50~100종목)된 종목 중 신호(정규/예비)가 발생한 종목을 관심종목1에 등록한 후 YS를 통해 확장차트를 띄운 후 매수/매도하고 처리가 안된 종목은 수동으로 거래를 합니다. 그런데 정규 신호로는 종가 거래를 할 수 없다 보니, 매수/매도 시에 익일 시가에 진입하게 되다 보니, 결국 시스템 진입가격과 가격 괴리가 발생하고, 수동으로 처리하는 부분이 많다보니 시뮬레이션 결과보다 수익이 떨어지는 결과를 초래합니다. 그래서 예비 신호를 이용하여 장 종가 부근에서 매수/매도를 진행하는 형태로 YS를 새로 만들고 싶습니다. YS 수식을 하나로 합칠 수 있으면 더할 나위 없이 좋겠지만 프로그래밍 능력의 한계 때문에 2개의 YS 시스템을 사용해서 1번 - 매수/분할매도(2번을 통해 예비신호로 매수되어 잔고에 있으니 실제로는 1번 식으로는 매수 미발생) 2번 - 매수/잔여물량매도 이런 형태로 운용 가능하지 않을까 생각하고 있고, 2번 수식을 작성하다가 도움을 구해봅니다. 가이드 수식을 주시면 큰 도움이 될 것 같습니다. 오늘도 좋은 하루 보내세요. 감사합니다. --------------------------------------------------------------------------- // 2번 수정/추가사항 // 1) 에비신호로는 일 5종목까지만 매수하고, 매수된 종목이 있으면 관심그룹2에 종목 추가한 후 확장차트 생성 // 2) 예비신호로 매도 시 잔여 보유 물량 일괄 청산(yesspot1번에서 분할매도하기 때문에 남은 물량만 당일 종가 부근에서 매도하면 됩니다) // 문의사항- 관심그룹 이름을 동적(이름+당일날짜)로 설정가능한지? //yesspot2번(예비신호) var d = new Date(); var HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds(); var cond; function Main_OnStart() { if (HHMMSS >= 90000) { Main.MessageList("start") Main.SetTimer(1,1000); } } function Main_OnTimer(nEventID) { if (HHMMSS >= 150000) { Main.KillTimer(1); Main.ReqPowerSearch("검색1"); } } function Main_OnRcvItemList(aItemList, nCount) { if (nCount > 0) { Main.SendInterests("관심그룹1", aItemList,false); } } function Main_OnTimer(nEventID) { if (nEventID == 1 && cond == false && HHMMSS >= 150000) { cond = true; var Incom = Chart1.GetIncompleteSignal(); if (Incom[0].signalKind == 1 && Account1.Balance.count == 0) { Account1.OrderBuy(Main.GetOrderCode(Incom[0].code), 1, 0,1); Main.MessageList("매수주문"); } if (Incom[0].signalKind == 2 && HHMMSS >= 151500) { Account1.OrderSell(Main.GetOrderCode(Incom[0].code), 1, 0,1); Main.MessageList("매도주문"); } } } // yesspot(1번) - 현재 사용 중 var ItemList; var Count; var ReqCount; var d; var H; function Main_OnStart() { Main.MessageLog("스팟시작"); d = new Date(); h=d.getDate(); //지정한 관심그룹의 종목수(관심그룹지정 필요) Count = Main.GetItemCountOfInterest("관심종목1"); Main.MessageList("지정관심그룹 종목수 : ", Count); ItemList = []; //관심그룹 종목코드를 ItemList로 옮김 for(var i = 0 ; i < Count ; i++) { //관심그룹지정 필요 ItemList.push(Main.GetItemCodeInInterest("관심종목1", i)); } ReqCount = 0; if (Count > 0) { Main.SetTimer(1, 500); } } function Main_OnTimer(nEventID) { if (nEventID == 1) { var TradeSet = new SystemTradeInfo(TRADE_FIXCAPITAL, 1, // 거래수량 100000000, // 자산 1, // 단위수량 0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료 0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지 PYRAMIDING_ENTRY, // 피라미딩 설정여부(다른진입신호만 허용) 100000, // 최대진입수량 20); // 최대진입횟수 var ChartSet = new ReqChartItem(ItemList[ReqCount],1,CHART_PERIOD_DAILY,1000,CHART_REQCOUNT_BAR,true,false); /////SystemInfo(name,kind,inputVar,tradeInfo,stopInfo) var SystemSet = new SystemInfo("YL_시스템(일봉)", YL_TYPE_NORMAL, null, TradeSet); Main.ReqChartEx(ChartSet,SystemSet); Main.MessageList("확장차트생성요청:",ItemList[ReqCount]); ReqCount = ReqCount+1; if (ReqCount == Count) { Main.KillTimer(1); Main.MessageList("종목객체생성완료"); } } } //신호발생 function Main_OnRiseSignal(ChartEx, Signal) { //신호발생 종목에 대해 잔고셋팅 Account1.SetBalance(Main.GetOrderCode(Signal.code),0); //매수신호이고 잔고가 없을때만 매수 if (Signal.signalKind == 1) ////// && Account1.Balance.count == 0) { Account1.OrderBuy(Main.GetOrderCode(Signal.code), Signal.count, Signal.price, 0); Main.MessageList("매수주문9"); } if (Signal.signalKind == 2) { //전체미체결주문 갯수 var num = Account1.GetTheNumberOfUnfills(); //전체 미체결수 만큼 루프를 돌면서 for (var i = 0; i < num; i++) { //미체결을 하나씩 셋팅하고 Account1.GetTotalAmount(nCategory, nTradeKind) Account1.SetUnfill(i); //미체결종목이 신호종목과 같고 미체결수량이 있으면 if (Account1.Unfill.code == Main.GetOrderCode(Signal.code) && Account1.Unfill.count > 0) { Account1.OrderCancel(Account1.Unfill.orderNum); } } //잔고수량만큼만 매도 if (Account1.Balance.count > 0) { Account1.OrderSell(Main.GetOrderCode(Signal.code), Signal.count, Signal.price, 0); Main.MessageList("매도주문"); } } }
답변 1
프로필 이미지

예스스탁 예스스탁 답변

2023-05-04 16:48:04.0

안녕하세요 예스스탁입니다. 1 아래 내용 참고하시기 바랍니다. 15시25분이 되면 생성된 차트의 마지막봉의 미완성신호를 체크해서 매도신호가 발생한 종목이 있으면 전고수량 전량을 매도하게 작성해 드립니다. 2 하나 주의하실 부분은 신호는 onclose타입으로 작성이 되어 있어야 합니다. 또한 매도는 exitlong이어야 합니다. 주식에서 매도를 일반적으로 Sell로 사용하는 경우도 많은데 exitlong으로 되어 있어야 미완성신호가 발생합니다. Sell은 매도진입함수이고 반대포지션 상태에서 발생하면 반대포지션을 청산도 같이 하기때문에 청산신호는 발생하지만 주식에서 미완성신호는 발생하지 않습니다. 3 var ItemList; var Count; var ReqCount; var d; var H; var CT = []; function Main_OnStart() { Main.MessageLog("스팟시작"); d = new Date(); h = d.getDate(); //지정한 관심그룹의 종목수(관심그룹지정 필요) Count = Main.GetItemCountOfInterest("관심종목1"); Main.MessageList("지정관심그룹 종목수 : ", Count); ItemList = []; //관심그룹 종목코드를 ItemList로 옮김 for(var i = 0 ; i < Count ; i++) { //관심그룹지정 필요 ItemList.push(Main.GetItemCodeInInterest("관심종목1", i)); } //관심종목이 1개 이상이면 if (Count > 0) { //첫종목부터 요청시작 //요청갯수 카운트 변수는 초기값 0 ReqCount = 0; var TradeSet = new SystemTradeInfo(TRADE_FIXCAPITAL, 1, // 거래수량 100000000, // 자산 1, // 단위수량 0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료 0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지 PYRAMIDING_ENTRY, // 피라미딩 설정여부(다른진입신호만 허용) 100000, // 최대진입수량 20); // 최대진입횟수 var ChartSet = new ReqChartItem(ItemList[ReqCount],1,CHART_PERIOD_DAILY,1000,CHART_REQCOUNT_BAR,true,false); /////SystemInfo(name,kind,inputVar,tradeInfo,stopInfo) var SystemSet = new SystemInfo("YL_시스템(일봉)", YL_TYPE_NORMAL, null, TradeSet); //차트객체 요청 Main.ReqChartEx(ChartSet,SystemSet); Main.MessageList("확장차트생성요청:",ItemList[ReqCount]); //1벝 타이머 10초 세팅 Main.SetTimer(1, 10000); } } //차트객체 수신 function Main_OnRcvChartEx(ChartEx) { //방금 요청한 종목이 맞는지 확인 if (ChartEx.GetCode(1) == ItemList[ReqCount]) { Main.MessageList("확장차트생성완료:",ChartEx.GetCode(1)); //차트객체를 순차적으로 CT배열변수에 저장 CT.push(ChartEx); //요청갯수 1증가 ReqCount = ReqCount+1; //요청갯수가 Count 미만이면 if (ReqCount < Count) { //다음종목 요청 var TradeSet = new SystemTradeInfo(TRADE_FIXCAPITAL, 1, // 거래수량 100000000, // 자산 1, // 단위수량 0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료 0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지 PYRAMIDING_ENTRY, // 피라미딩 설정여부(다른진입신호만 허용) 100000, // 최대진입수량 20); // 최대진입횟수 var ChartSet = new ReqChartItem(ItemList[ReqCount],1,CHART_PERIOD_DAILY,1000,CHART_REQCOUNT_BAR,true,false); /////SystemInfo(name,kind,inputVar,tradeInfo,stopInfo) var SystemSet = new SystemInfo("YL_시스템(일봉)", YL_TYPE_NORMAL, null, TradeSet); Main.ReqChartEx(ChartSet,SystemSet); Main.MessageList("확장차트생성요청:",ItemList[ReqCount]); } else//아니면 { //종목객체생성 종료 Main.MessageList("종목객체생성완료"); } } } //타이머 동작 function Main_OnTimer(nEventID) { //1번 타이머 동작 if (nEventID == 1) { var d = new Date(); HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds(); //15시 25분이 되면 if (HHMMSS >= 152500) { //타이머종료 Main.KillTimer(1); //생성된 전체차트에서 미완성 매도신호 있는 것을 확인하고 //미완성매도신호가 있고 잔고에 보유수량이 있으면 전량 매도 for (var i = 0; i < CT.length; i++) { ///마지막봉의 미완성 신호 정보를 가져와 저장 var Incom = CT[i].GetIncompleteSignal(); //미완성 정보가 있고 매수청산 신호이면 if (Incom[0] != null && Incom[0].signalKind == 2) { Account1.SetBalance(Incom[0].code, 0) if (Account1.Balance.count > 0) { Account1.OrderSell(Incom[0].code, Account1.Balance.count, Incom[0].price, 0); } } } } } } //신호발생 function Main_OnRiseSignal(ChartEx, Signal) { //신호발생 종목에 대해 잔고셋팅 Account1.SetBalance(Main.GetOrderCode(Signal.code),0); //매수신호이고 잔고가 없을때만 매수 if (Signal.signalKind == 1) ////// && Account1.Balance.count == 0) { Account1.OrderBuy(Main.GetOrderCode(Signal.code), Signal.count, Signal.price, 0); Main.MessageList("매수주문9"); } if (Signal.signalKind == 2) { //전체미체결주문 갯수 var num = Account1.GetTheNumberOfUnfills(); //전체 미체결수 만큼 루프를 돌면서 for (var i = 0; i < num; i++) { //미체결을 하나씩 셋팅하고 Account1.GetTotalAmount(nCategory, nTradeKind) Account1.SetUnfill(i); //미체결종목이 신호종목과 같고 미체결수량이 있으면 if (Account1.Unfill.code == Main.GetOrderCode(Signal.code) && Account1.Unfill.count > 0) { Account1.OrderCancel(Account1.Unfill.orderNum); } } //잔고수량만큼만 매도 if (Account1.Balance.count > 0) { Account1.OrderSell(Main.GetOrderCode(Signal.code), Signal.count, Signal.price, 0); Main.MessageList("매도주문"); } } } 즐거운 하루되세요 > 깜피 님이 쓴 글입니다. > 제목 : 시스템 수식 문의드립니다. > 안녕하세요. YL및 YS 게시판을 통해서 도움을 많이 주셔서 항상 감사합니다. 현재 YS로 거래 중인데 좀 더 정교하게 거래해 보고자 다시 도움을 청합니다. 저는 일봉 거래를 하는데 2회 분할 매수(각각 일봉 종가에 진입) 후 분할매도(장중 분할 매도 후 남은 물량은 종가 매도) 하는 형태로 진행이 되고 하루에 2~5종목 정도 매수하고 15~20일 정도 후 매도합니다. 보통 검색식으로 추출(일 50~100종목)된 종목 중 신호(정규/예비)가 발생한 종목을 관심종목1에 등록한 후 YS를 통해 확장차트를 띄운 후 매수/매도하고 처리가 안된 종목은 수동으로 거래를 합니다. 그런데 정규 신호로는 종가 거래를 할 수 없다 보니, 매수/매도 시에 익일 시가에 진입하게 되다 보니, 결국 시스템 진입가격과 가격 괴리가 발생하고, 수동으로 처리하는 부분이 많다보니 시뮬레이션 결과보다 수익이 떨어지는 결과를 초래합니다. 그래서 예비 신호를 이용하여 장 종가 부근에서 매수/매도를 진행하는 형태로 YS를 새로 만들고 싶습니다. YS 수식을 하나로 합칠 수 있으면 더할 나위 없이 좋겠지만 프로그래밍 능력의 한계 때문에 2개의 YS 시스템을 사용해서 1번 - 매수/분할매도(2번을 통해 예비신호로 매수되어 잔고에 있으니 실제로는 1번 식으로는 매수 미발생) 2번 - 매수/잔여물량매도 이런 형태로 운용 가능하지 않을까 생각하고 있고, 2번 수식을 작성하다가 도움을 구해봅니다. 가이드 수식을 주시면 큰 도움이 될 것 같습니다. 오늘도 좋은 하루 보내세요. 감사합니다. --------------------------------------------------------------------------- // 2번 수정/추가사항 // 1) 에비신호로는 일 5종목까지만 매수하고, 매수된 종목이 있으면 관심그룹2에 종목 추가한 후 확장차트 생성 // 2) 예비신호로 매도 시 잔여 보유 물량 일괄 청산(yesspot1번에서 분할매도하기 때문에 남은 물량만 당일 종가 부근에서 매도하면 됩니다) // 문의사항- 관심그룹 이름을 동적(이름+당일날짜)로 설정가능한지? //yesspot2번(예비신호) var d = new Date(); var HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds(); var cond; function Main_OnStart() { if (HHMMSS >= 90000) { Main.MessageList("start") Main.SetTimer(1,1000); } } function Main_OnTimer(nEventID) { if (HHMMSS >= 150000) { Main.KillTimer(1); Main.ReqPowerSearch("검색1"); } } function Main_OnRcvItemList(aItemList, nCount) { if (nCount > 0) { Main.SendInterests("관심그룹1", aItemList,false); } } function Main_OnTimer(nEventID) { if (nEventID == 1 && cond == false && HHMMSS >= 150000) { cond = true; var Incom = Chart1.GetIncompleteSignal(); if (Incom[0].signalKind == 1 && Account1.Balance.count == 0) { Account1.OrderBuy(Main.GetOrderCode(Incom[0].code), 1, 0,1); Main.MessageList("매수주문"); } if (Incom[0].signalKind == 2 && HHMMSS >= 151500) { Account1.OrderSell(Main.GetOrderCode(Incom[0].code), 1, 0,1); Main.MessageList("매도주문"); } } } // yesspot(1번) - 현재 사용 중 var ItemList; var Count; var ReqCount; var d; var H; function Main_OnStart() { Main.MessageLog("스팟시작"); d = new Date(); h=d.getDate(); //지정한 관심그룹의 종목수(관심그룹지정 필요) Count = Main.GetItemCountOfInterest("관심종목1"); Main.MessageList("지정관심그룹 종목수 : ", Count); ItemList = []; //관심그룹 종목코드를 ItemList로 옮김 for(var i = 0 ; i < Count ; i++) { //관심그룹지정 필요 ItemList.push(Main.GetItemCodeInInterest("관심종목1", i)); } ReqCount = 0; if (Count > 0) { Main.SetTimer(1, 500); } } function Main_OnTimer(nEventID) { if (nEventID == 1) { var TradeSet = new SystemTradeInfo(TRADE_FIXCAPITAL, 1, // 거래수량 100000000, // 자산 1, // 단위수량 0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료 0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지 PYRAMIDING_ENTRY, // 피라미딩 설정여부(다른진입신호만 허용) 100000, // 최대진입수량 20); // 최대진입횟수 var ChartSet = new ReqChartItem(ItemList[ReqCount],1,CHART_PERIOD_DAILY,1000,CHART_REQCOUNT_BAR,true,false); /////SystemInfo(name,kind,inputVar,tradeInfo,stopInfo) var SystemSet = new SystemInfo("YL_시스템(일봉)", YL_TYPE_NORMAL, null, TradeSet); Main.ReqChartEx(ChartSet,SystemSet); Main.MessageList("확장차트생성요청:",ItemList[ReqCount]); ReqCount = ReqCount+1; if (ReqCount == Count) { Main.KillTimer(1); Main.MessageList("종목객체생성완료"); } } } //신호발생 function Main_OnRiseSignal(ChartEx, Signal) { //신호발생 종목에 대해 잔고셋팅 Account1.SetBalance(Main.GetOrderCode(Signal.code),0); //매수신호이고 잔고가 없을때만 매수 if (Signal.signalKind == 1) ////// && Account1.Balance.count == 0) { Account1.OrderBuy(Main.GetOrderCode(Signal.code), Signal.count, Signal.price, 0); Main.MessageList("매수주문9"); } if (Signal.signalKind == 2) { //전체미체결주문 갯수 var num = Account1.GetTheNumberOfUnfills(); //전체 미체결수 만큼 루프를 돌면서 for (var i = 0; i < num; i++) { //미체결을 하나씩 셋팅하고 Account1.GetTotalAmount(nCategory, nTradeKind) Account1.SetUnfill(i); //미체결종목이 신호종목과 같고 미체결수량이 있으면 if (Account1.Unfill.code == Main.GetOrderCode(Signal.code) && Account1.Unfill.count > 0) { Account1.OrderCancel(Account1.Unfill.orderNum); } } //잔고수량만큼만 매도 if (Account1.Balance.count > 0) { Account1.OrderSell(Main.GetOrderCode(Signal.code), Signal.count, Signal.price, 0); Main.MessageList("매도주문"); } } }