커뮤니티

미완성 신호 거래 등에 대한 수식 수정 부탁드립니다.

프로필 이미지
깜피
2023-12-30 07:26:58.0
733
글번호 225915
답변완료
안녕하세요. 전에 작성해 주신 수식을 일부 수정하여 현재 반자동화된 거래를 진행하는데 너무 잘 활용하고 있습니다. 최근에 거래 로직을 수정하면서 조금 더 자동화된 형태로 거래하고 싶어서 재차 도움을 구합니다. 기존 사용하던 yesspot 수식을 재차 수정해서 올렸으니 가이드를 주시면 참고해서 다시 열심히 매매에 임하겠습니다. 거래에 큰 도움을 주셔서 항상 감사드립니다. 연말 마무리 잘 하시고 새해 복 많이 받으세요. --------------------------------------------------------------------------------------------- [거래순서] * yespot 실행 시 관심종목리스트에 있는 종목을 대상으로 차트객체 생성 * 장 중(시초거래 및 장 중 거래)에 매수/매도 진행(미체결된 경우 10초 단위로 현재가 +(-)한호가씩 변경하며 계약 체결) - 매수 신호가 b2일 경우에는 무조건 매수 - 매수 신호가 b2가 아닌 경우에는 계좌에 같은 종목이 없는 경우에만 매수 * 152000 파워종목검색 실행 * 검색된 종목 중 관심종목리스트에 없는 종목에 대해 차트객체 추가하고 관심종목리스트에 추가 * 관심종목리스트를 대상으로 동시호가에 완성신호 또는 미완성신호로 매수/매도 거래 (분할 매수(매도) 로직이 포함되어 있어서, 종가에 완성신호 및 미완성 신호가 발생합니다. 현재는 미완성신호 거래가 생각대로 잘안돼서 익일 시초가 매매로 돌려서 거래 중인데 동시호가 거래나 미체결 시 장후시간외 거래로 거래 방식을 수정하고 싶습니다) - 매수 신호가 b2일 경우에는 무조건 매수 - 매수 신호가 b2가 아닌 경우에는 계좌에 같은 종목이 없는 경우에만 매수 ---------------------------------------------------------------------------- var ItemList; var Count; var daycount; var daycount1=0; var daycount2=0; var YYYYMMDD; var ReqCount; var d; var H; var S_price; var ps; var value1 = 0; var HHMMSS; function Main_OnStart() { Main.MessageLog("스팟시작"); d = new Date(); h=d.getDate(); YYYYMMDD = d.getFullYear()*10000 +(d.getMonth()+1)*100+d.getDate(); if (Main.GetUserValue(YYYYMMDD) == "") { daycount = 0; } else { daycount = Main.GetUserValue(YYYYMMDD); } //지정한 관심그룹의 종목수(관심그룹지정 필요) 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, // 거래수량 500000, // 자산 1, // 단위수량 0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료 0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지 PYRAMIDING_ENTRY, // 피라미딩 설정여부(다른진입신호만 허용) 100000, // 최대진입수량 20); // 최대진입횟수 var ChartSet = new ReqChartItem(ItemList[ReqCount],1,CHART_PERIOD_DAILY,600,CHART_REQCOUNT_BAR,true,false); /////SystemInfo(name,kind,inputVar,tradeInfo,stopInfo) var SystemSet = new SystemInfo("거래(관심종목1)", YL_TYPE_NORMAL, null, TradeSet); Main.ReqChartEx(ChartSet,SystemSet); Main.MessageList("확장차트생성요청:",ItemList[ReqCount]); ReqCount = ReqCount+1; if (ReqCount == Count) { Main.KillTimer(1); Main.MessageList("종목객체생성완료"); } } HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds(); ///// if (HHMMSS > 152000) ///// { Main.MessageList("start(종목검색))"); Main.KillTimer(1);// Main.ReqPowerSearch("종목검색_일봉거래"); } } function Main_OnRcvItemList(aItemList, nCount) { Main.MessageList("종목검색 완료 nCount : ",nCount,MK.length); Main.MessageList("종목검색 완료 aItemList : ",aItemList); ////////////////////////////////////////// // 종목 검색 후 관심종목리스트에 없는 종목은 확장차트 생성 후, 관심종목에 등록. ////////////////////////////////////////// if (nCount > 0) { Main.SendInterests("관심종목1", aItemList,false); Main.MessageList("관심종목 등록"); } } //신호발생 function Main_OnRiseSignal(ChartEx, Signal) { //계좌 보유 종목 수 var num1 = Account1.GetTheNumberOfBalances(); //신호발생 종목에 대해 잔고셋팅 Account1.SetBalance(Main.GetOrderCode(Signal.code),0); if (Signal.price < 1000) { ps = 1; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 1000 && Signal.price < 5000) { ps = 5; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 5000 && Signal.price < 10000) { ps = 10; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 10000 && Signal.price < 50000) { ps = 50; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 50000 && Signal.price < 100000) { ps = 100; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 100000) { ps = 1000; S_price = Math.floor(Signal.price/ps)*ps; } //매수신호이고 잔고가 없을때만 매수 수정 if (Signal.signalKind == 1) ////// && Account1.Balance.count == 0) { if (Signal.name != "b2" && num1<=50 && Account1.Balance.count == 0 && daycount1 < 5) // 매수신호가 b2가 아닌 경우 기존 잔고가 없는 경우에만 매수하고, 일 5종목까지만 매수 { Account1.OrderBuy(Main.GetOrderCode(Signal.code), 1, S_price + ps*2, 0); Account1.OrderBuy(Main.GetOrderCode(Signal.code), Signal.count-1, S_price + ps*2, 0); daycount1 = daycount1+1; Main.MessageList("매수주문8"); Main.MessageLog("1차매수 후 매도 "+S_price); } if (Signal.name == "b2" && num1<=50 && daycount2 < 5)//매수신호가 b2인 경우에는 기매수되지 않았더라도 일 5종목까지 매수 { Account1.OrderBuy(Main.GetOrderCode(Signal.code), 2, S_price + ps*2, 0); Account1.OrderBuy(Main.GetOrderCode(Signal.code), Signal.count-2, S_price + ps*2, 0); daycount2 = daycount2+1; Main.MessageList("매수주문9"); Main.MessageLog("2차매수 후 매도 "+S_price); } } 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); } ////////------------->미체결 또는 부분체결 시 10초 단위로 현재가 +(-)1호가씩 변경하며 거래체결하는 로식 삽입 } if (Account1.Balance.count > 0) { Account1.OrderSell(Main.GetOrderCode(Signal.code), 1, S_price - ps*2, 0); Account1.OrderSell(Main.GetOrderCode(Signal.code), Signal.count-1, S_price - ps*2, 0); Main.MessageList("매도주문"); ///////------------>미체결 또는 부분체결된 경우 잔여 물량에 대해 장후 시간외 거래하는 로직 추가 } } } //신호발생 function Main_OnRiseIncompleteSignal(ChartEx, IncompleteSignal) { if (HHMMSS > 152000) ///// { //계좌 보유 종목 수 var num1 = Account1.GetTheNumberOfBalances(); //신호발생 종목에 대해 잔고셋팅 Account1.SetBalance(Main.GetOrderCode(IncompleteSignal.code),0); if (IncompleteSignal.price < 1000) { ps = 1; S_price = Math.floor(IncompleteSignal.price/ps)*ps; } if (IncompleteSignal.price >= 1000 && IncompleteSignal.price < 5000) { ps = 5; S_price = Math.floor(IncompleteSignal.price/ps)*ps; } if (IncompleteSignal.price >= 5000 && IncompleteSignal.price < 10000) { ps = 10; S_price = Math.floor(IncompleteSignal.price/ps)*ps; } if (IncompleteSignal.price >= 10000 && IncompleteSignal.price < 50000) { ps = 50; S_price = Math.floor(Signal.price/ps)*ps; } if (IncompleteSignal.price >= 50000 && IncompleteSignal.price < 100000) { ps = 100; S_price = Math.floor(IncompleteSignal.price/ps)*ps; } if (IncompleteSignal.price >= 100000) { ps = 1000; S_price = Math.floor(IncompleteSignal.price/ps)*ps; } if (IncompleteSignal.signalKind == 1) { if (IncompleteSignal.name != "b2" && num1<=50 && Account1.Balance.count == 0 && daycount1 < 5) // 매수신호가 b2가 아닌 경우 기존 잔고가 없는 경우에만 매수하고, 일 5종목까지만 매수 { Account1.OrderBuy(Main.GetOrderCode(IncompleteSignal.code), 2, S_price + ps*2, 0); Account1.OrderBuy(Main.GetOrderCode(IncompleteSignal.code),Signal.count-2, S_price + ps*2, 0); daycount1 = daycount1+1; Main.MessageList("매수주문10"); Main.MessageLog("1차매수 후 매도 "+S_price); ///////------------>미체결 또는 부분체결된 경우 잔여 물량에 대해 장후 시간외 거래하는 로직 추가 } if (IncompleteSignal.name == "b2" && num1<=50 && daycount2 < 5)// 매수신호가 b2인 경우에는 기매수되지 않았더라도 일 5종목까지 매수 { Account1.OrderBuy(Main.GetOrderCode(IncompleteSignal.code), 2, S_price + ps*2, 0); // 2호가 위 매수 Account1.OrderBuy(Main.GetOrderCode(IncompleteSignal.code), IncompleteSignal.count-2, S_price + ps*2, 0); daycount2 = daycount2+1; Main.MessageList("매수주문10"); Main.MessageLog("2차매수 후 매도 "+S_price); ///////------------>미체결 또는 부분체결된 경우 잔여 물량에 대해 장후 시간외 거래하는 로직 추가 } if (Account1.Balance.count > 0) { Account1.OrderSell(Main.GetOrderCode(IncompleteSignal.code), 1, S_price - ps*2, 0); Account1.OrderSell(Main.GetOrderCode(IncompleteSignal.code), IncompleteSignal.count-1, S_price - ps*2, 0); ///////------------>미체결 또는 부분체결된 경우 잔여 물량에 대해 장후 시간외 거래하는 로직 추가 } } } }
답변 2
프로필 이미지

예스스탁 예스스탁 답변

2024-02-14 15:12:56.0

> 깜피 님이 쓴 글입니다. > 제목 : 미완성 신호 거래 등에 대한 수식 수정 부탁드립니다. > 안녕하세요. 전에 작성해 주신 수식을 일부 수정하여 현재 반자동화된 거래를 진행하는데 너무 잘 활용하고 있습니다. 최근에 거래 로직을 수정하면서 조금 더 자동화된 형태로 거래하고 싶어서 재차 도움을 구합니다. 기존 사용하던 yesspot 수식을 재차 수정해서 올렸으니 가이드를 주시면 참고해서 다시 열심히 매매에 임하겠습니다. 거래에 큰 도움을 주셔서 항상 감사드립니다. 연말 마무리 잘 하시고 새해 복 많이 받으세요. --------------------------------------------------------------------------------------------- [거래순서] * yespot 실행 시 관심종목리스트에 있는 종목을 대상으로 차트객체 생성 * 장 중(시초거래 및 장 중 거래)에 매수/매도 진행(미체결된 경우 10초 단위로 현재가 +(-)한호가씩 변경하며 계약 체결) - 매수 신호가 b2일 경우에는 무조건 매수 - 매수 신호가 b2가 아닌 경우에는 계좌에 같은 종목이 없는 경우에만 매수 * 152000 파워종목검색 실행 * 검색된 종목 중 관심종목리스트에 없는 종목에 대해 차트객체 추가하고 관심종목리스트에 추가 * 관심종목리스트를 대상으로 동시호가에 완성신호 또는 미완성신호로 매수/매도 거래 (분할 매수(매도) 로직이 포함되어 있어서, 종가에 완성신호 및 미완성 신호가 발생합니다. 현재는 미완성신호 거래가 생각대로 잘안돼서 익일 시초가 매매로 돌려서 거래 중인데 동시호가 거래나 미체결 시 장후시간외 거래로 거래 방식을 수정하고 싶습니다) - 매수 신호가 b2일 경우에는 무조건 매수 - 매수 신호가 b2가 아닌 경우에는 계좌에 같은 종목이 없는 경우에만 매수 ---------------------------------------------------------------------------- var ItemList; var Count; var daycount; var daycount1=0; var daycount2=0; var YYYYMMDD; var ReqCount; var d; var H; var S_price; var ps; var value1 = 0; var HHMMSS; function Main_OnStart() { Main.MessageLog("스팟시작"); d = new Date(); h=d.getDate(); YYYYMMDD = d.getFullYear()*10000 +(d.getMonth()+1)*100+d.getDate(); if (Main.GetUserValue(YYYYMMDD) == "") { daycount = 0; } else { daycount = Main.GetUserValue(YYYYMMDD); } //지정한 관심그룹의 종목수(관심그룹지정 필요) 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, // 거래수량 500000, // 자산 1, // 단위수량 0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료 0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지 PYRAMIDING_ENTRY, // 피라미딩 설정여부(다른진입신호만 허용) 100000, // 최대진입수량 20); // 최대진입횟수 var ChartSet = new ReqChartItem(ItemList[ReqCount],1,CHART_PERIOD_DAILY,600,CHART_REQCOUNT_BAR,true,false); /////SystemInfo(name,kind,inputVar,tradeInfo,stopInfo) var SystemSet = new SystemInfo("거래(관심종목1)", YL_TYPE_NORMAL, null, TradeSet); Main.ReqChartEx(ChartSet,SystemSet); Main.MessageList("확장차트생성요청:",ItemList[ReqCount]); ReqCount = ReqCount+1; if (ReqCount == Count) { Main.KillTimer(1); Main.MessageList("종목객체생성완료"); } } HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds(); ///// if (HHMMSS > 152000) ///// { Main.MessageList("start(종목검색))"); Main.KillTimer(1);// Main.ReqPowerSearch("종목검색_일봉거래"); } } function Main_OnRcvItemList(aItemList, nCount) { Main.MessageList("종목검색 완료 nCount : ",nCount,MK.length); Main.MessageList("종목검색 완료 aItemList : ",aItemList); ////////////////////////////////////////// // 종목 검색 후 관심종목리스트에 없는 종목은 확장차트 생성 후, 관심종목에 등록. ////////////////////////////////////////// if (nCount > 0) { Main.SendInterests("관심종목1", aItemList,false); Main.MessageList("관심종목 등록"); } } //신호발생 function Main_OnRiseSignal(ChartEx, Signal) { //계좌 보유 종목 수 var num1 = Account1.GetTheNumberOfBalances(); //신호발생 종목에 대해 잔고셋팅 Account1.SetBalance(Main.GetOrderCode(Signal.code),0); if (Signal.price < 1000) { ps = 1; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 1000 && Signal.price < 5000) { ps = 5; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 5000 && Signal.price < 10000) { ps = 10; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 10000 && Signal.price < 50000) { ps = 50; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 50000 && Signal.price < 100000) { ps = 100; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 100000) { ps = 1000; S_price = Math.floor(Signal.price/ps)*ps; } //매수신호이고 잔고가 없을때만 매수 수정 if (Signal.signalKind == 1) ////// && Account1.Balance.count == 0) { if (Signal.name != "b2" && num1<=50 && Account1.Balance.count == 0 && daycount1 < 5) // 매수신호가 b2가 아닌 경우 기존 잔고가 없는 경우에만 매수하고, 일 5종목까지만 매수 { Account1.OrderBuy(Main.GetOrderCode(Signal.code), 1, S_price + ps*2, 0); Account1.OrderBuy(Main.GetOrderCode(Signal.code), Signal.count-1, S_price + ps*2, 0); daycount1 = daycount1+1; Main.MessageList("매수주문8"); Main.MessageLog("1차매수 후 매도 "+S_price); } if (Signal.name == "b2" && num1<=50 && daycount2 < 5)//매수신호가 b2인 경우에는 기매수되지 않았더라도 일 5종목까지 매수 { Account1.OrderBuy(Main.GetOrderCode(Signal.code), 2, S_price + ps*2, 0); Account1.OrderBuy(Main.GetOrderCode(Signal.code), Signal.count-2, S_price + ps*2, 0); daycount2 = daycount2+1; Main.MessageList("매수주문9"); Main.MessageLog("2차매수 후 매도 "+S_price); } } 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); } ////////------------->미체결 또는 부분체결 시 10초 단위로 현재가 +(-)1호가씩 변경하며 거래체결하는 로식 삽입 } if (Account1.Balance.count > 0) { Account1.OrderSell(Main.GetOrderCode(Signal.code), 1, S_price - ps*2, 0); Account1.OrderSell(Main.GetOrderCode(Signal.code), Signal.count-1, S_price - ps*2, 0); Main.MessageList("매도주문"); ///////------------>미체결 또는 부분체결된 경우 잔여 물량에 대해 장후 시간외 거래하는 로직 추가 } } } //신호발생 function Main_OnRiseIncompleteSignal(ChartEx, IncompleteSignal) { if (HHMMSS > 152000) ///// { //계좌 보유 종목 수 var num1 = Account1.GetTheNumberOfBalances(); //신호발생 종목에 대해 잔고셋팅 Account1.SetBalance(Main.GetOrderCode(IncompleteSignal.code),0); if (IncompleteSignal.price < 1000) { ps = 1; S_price = Math.floor(IncompleteSignal.price/ps)*ps; } if (IncompleteSignal.price >= 1000 && IncompleteSignal.price < 5000) { ps = 5; S_price = Math.floor(IncompleteSignal.price/ps)*ps; } if (IncompleteSignal.price >= 5000 && IncompleteSignal.price < 10000) { ps = 10; S_price = Math.floor(IncompleteSignal.price/ps)*ps; } if (IncompleteSignal.price >= 10000 && IncompleteSignal.price < 50000) { ps = 50; S_price = Math.floor(Signal.price/ps)*ps; } if (IncompleteSignal.price >= 50000 && IncompleteSignal.price < 100000) { ps = 100; S_price = Math.floor(IncompleteSignal.price/ps)*ps; } if (IncompleteSignal.price >= 100000) { ps = 1000; S_price = Math.floor(IncompleteSignal.price/ps)*ps; } if (IncompleteSignal.signalKind == 1) { if (IncompleteSignal.name != "b2" && num1<=50 && Account1.Balance.count == 0 && daycount1 < 5) // 매수신호가 b2가 아닌 경우 기존 잔고가 없는 경우에만 매수하고, 일 5종목까지만 매수 { Account1.OrderBuy(Main.GetOrderCode(IncompleteSignal.code), 2, S_price + ps*2, 0); Account1.OrderBuy(Main.GetOrderCode(IncompleteSignal.code),Signal.count-2, S_price + ps*2, 0); daycount1 = daycount1+1; Main.MessageList("매수주문10"); Main.MessageLog("1차매수 후 매도 "+S_price); ///////------------>미체결 또는 부분체결된 경우 잔여 물량에 대해 장후 시간외 거래하는 로직 추가 } if (IncompleteSignal.name == "b2" && num1<=50 && daycount2 < 5)// 매수신호가 b2인 경우에는 기매수되지 않았더라도 일 5종목까지 매수 { Account1.OrderBuy(Main.GetOrderCode(IncompleteSignal.code), 2, S_price + ps*2, 0); // 2호가 위 매수 Account1.OrderBuy(Main.GetOrderCode(IncompleteSignal.code), IncompleteSignal.count-2, S_price + ps*2, 0); daycount2 = daycount2+1; Main.MessageList("매수주문10"); Main.MessageLog("2차매수 후 매도 "+S_price); ///////------------>미체결 또는 부분체결된 경우 잔여 물량에 대해 장후 시간외 거래하는 로직 추가 } if (Account1.Balance.count > 0) { Account1.OrderSell(Main.GetOrderCode(IncompleteSignal.code), 1, S_price - ps*2, 0); Account1.OrderSell(Main.GetOrderCode(IncompleteSignal.code), IncompleteSignal.count-1, S_price - ps*2, 0); ///////------------>미체결 또는 부분체결된 경우 잔여 물량에 대해 장후 시간외 거래하는 로직 추가 } } } }
프로필 이미지

예스스탁 예스스탁 답변

2024-03-14 16:48:38.0

안녕하세요 예스스탁입니다. 1 아래 내용 참고하시기 바랍니다. 스팟이 시작하면 지정한 관심그룹을 부르고 제외종목관심그룹 안에 없는 종목만 리스트하여 시스템을 적용한 확장차트를 열고 신호에 따라 주문을 하며 15시20분이 되면 종목검색 후에 제외종목리스트에 없는 종목만 분류하여 추가로 차트를 생성하고 전체 차트에서 마지막봉 미완성봉에 대한 정보를 가져와 매수면 1주 매수, 매도면 1주 매고하게 됩니다. 2 차트의 마지막봉의 미완성신호 정보는 차트객체의 GetIncompleteSignal()함수가 리턴을 해주지만 수량 정보는 리턴을 하지 못해서 1주로 지정을 했습니다. 수량자체는 별도로 지정하셔야 할 것 같습니다. 3 var ItemList = [];//스팟시작시 지정한 관심그룹의 종목리스트 저장할 배열변수 var ExList = [];//스팟시작시 지정한 재외종목관심그룹의 종목리스트 저장할 배열변수 var CT = []; //생성할 차트객체를 저장할 배열변수 var AddList = []; //장후 동시호가 시간에 종목검색 후 추가할 종목리스트를 저장할 배열변수 var Count; var daycount; var daycount1=0; var daycount2=0; var YYYYMMDD; var ReqCount; var d; var H; var S_price; var ps; var value1 = 0; var HHMMSS; var ReqCount; var AfterMarket; function Main_OnStart() { Main.MessageLog("스팟시작"); d = new Date(); h = d.getDate(); YYYYMMDD = d.getFullYear()*10000 +(d.getMonth()+1)*100+d.getDate(); if (Main.GetUserValue(YYYYMMDD) == "") daycount = 0; else daycount = Main.GetUserValue(YYYYMMDD); //제외종을 리스트 만들기 var Ex = Main.GetItemCountOfInterest("제외종목관심그룹명"); Main.MessageList("제외종목관심그룹 종목수 : ", EX); if (EX > 0) { ExList = []; for(var i = 0 ; i < EX ; i++) { ExList.push(Main.GetItemCodeInInterest("제외종목관심그룹명", i)); } } //관심그룹 종목코드들 중 제외종목리스트에 없는 종목만 ItemList로 옮김 Count = Main.GetItemCountOfInterest("관심종목1"); Main.MessageList("지정관심그룹 종목수 : ", Count); ItemList = []; for(var i = 0 ; i < Count ; i++) { var Add = true; //제외종목리스트에 지정한 종목이 있을 경우 추가는 false for(var x = 0 ; x < Count ; x++) { if (Main.GetItemCodeInInterest("관심종목1", i) == ExList[x]) { Add = false; } } //추가가 true일때만 ItemList에 삽입 if (Add == true) { ItemList.push(Main.GetItemCodeInInterest("관심종목1", i)); } } if (Count > 0) { ReqCount = 0; var TradeSet = new SystemTradeInfo(TRADE_FIXCAPITAL, 1, // 거래수량 500000, // 자산 1, // 단위수량 0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료 0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지 PYRAMIDING_ENTRY, // 피라미딩 설정여부(다른진입신호만 허용) 100000, // 최대진입수량 20); // 최대진입횟수 var ChartSet = new ReqChartItem(ItemList[ReqCount],1,CHART_PERIOD_DAILY,600,CHART_REQCOUNT_BAR,true,false); /////SystemInfo(name,kind,inputVar,tradeInfo,stopInfo) var SystemSet = new SystemInfo("거래(관심종목1)", YL_TYPE_NORMAL, null, TradeSet); Main.ReqChartEx(ChartSet,SystemSet); Main.MessageList("확장차트생성요청:",ItemList[ReqCount]); } //정규장 후 구분 변수 AfterMarket = false; Main.SetTimer(1, 60000); } function Main_OnRcvChartEx(ChartEx) { if (AfterMarket == false && ChartEx.GetCode(1) == ItemList[ReqCount]) { CT.push(ChartEx); ReqCount = ReqCount+1; if (ReqCount < Count) { var TradeSet = new SystemTradeInfo(TRADE_FIXCAPITAL, 1, // 거래수량 500000, // 자산 1, // 단위수량 0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료 0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지 PYRAMIDING_ENTRY, // 피라미딩 설정여부(다른진입신호만 허용) 100000, // 최대진입수량 20); // 최대진입횟수 var ChartSet = new ReqChartItem(ItemList[ReqCount],1,CHART_PERIOD_DAILY,600,CHART_REQCOUNT_BAR,true,false); /////SystemInfo(name,kind,inputVar,tradeInfo,stopInfo) var SystemSet = new SystemInfo("거래(관심종목1)", YL_TYPE_NORMAL, null, TradeSet); Main.ReqChartEx(ChartSet,SystemSet); Main.MessageList("확장차트생성요청:",ItemList[ReqCount]); } else { Main.MessageList("확장차트생성완료"); } } if (AfterMarket == true && ChartEx.GetCode(1) == AddList[ReqCount]) { CT.push(ChartEx); ReqCount = ReqCount+1; if (ReqCount < Count) { var TradeSet = new SystemTradeInfo(TRADE_FIXCAPITAL, 1, // 거래수량 500000, // 자산 1, // 단위수량 0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료 0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지 PYRAMIDING_ENTRY, // 피라미딩 설정여부(다른진입신호만 허용) 100000, // 최대진입수량 20); // 최대진입횟수 var ChartSet = new ReqChartItem(AddList[ReqCount],1,CHART_PERIOD_DAILY,600,CHART_REQCOUNT_BAR,true,false); /////SystemInfo(name,kind,inputVar,tradeInfo,stopInfo) var SystemSet = new SystemInfo("거래(관심종목1)", YL_TYPE_NORMAL, null, TradeSet); Main.ReqChartEx(ChartSet,SystemSet); Main.MessageList("확장차트생성요청:",ItemList[ReqCount]); } else { Main.MessageList("추가확장차트생성완료"); Main.MessageList("모든차트 최종 미완성 신호 확인 : 최종 차트 갯수 : ",CT.length); if (CT.length > 0) { //생성된 전체차트에서 미완성 수신호 있는 것을 확인 for (var i = 0; i < CT.length; i++) { ///마지막봉의 미완성 신호 정보를 가져와 저장 var Incom = CT[i].GetIncompleteSignal(); //미완성 정보가 있고 매수 신호이면 if (Incom[0] != null) { if (Incom[0].price < 1000) { ps = 1; S_price = Math.floor(Incom[0].price/ps)*ps; } if (Incom[0].price >= 1000 && Incom[0].price < 5000) { ps = 5; S_price = Math.floor(Incom[0].price/ps)*ps; } if (Incom[0].price >= 5000 && Incom[0].price < 10000) { ps = 10; S_price = Math.floor(Incom[0].price/ps)*ps; } if (Incom[0].price >= 10000 && Incom[0].price < 50000) { ps = 50; S_price = Math.floor(Incom[0].price/ps)*ps; } if (Incom[0].price >= 50000 && Incom[0].price < 100000) { ps = 100; S_price = Math.floor(Incom[0].price/ps)*ps; } if (Incom[0].price >= 100000) { ps = 1000; S_price = Math.floor(Incom[0].price/ps)*ps; } if (Incom[0].signalKind == 1) { Account1.OrderBuy(Incom[0].code, 1, S_price + ps*2, 0); } if Incom[0].signalKind == 2) { Account1.OrderSell(Incom[0].code, 1, S_price - ps*2, 0); } } } } } } } function Main_OnTimer(nEventID) { d = new Date(); HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds(); if (HHMMSS > 152000) { Main.MessageList("start(종목검색))"); Main.KillTimer(1);// Main.ReqPowerSearch("종목검색_일봉거래"); AfterMarket = true; } } function Main_OnRcvItemList(aItemList, nCount) { Main.MessageList("종목검색 완료 nCount : ",nCount); Main.MessageList("종목검색 완료 aItemList : ",aItemList); if (nCount > 0) { AddList = []; for (var x = 0; x < nCount; x++ ) { var add = true; //기존 관심그룹에 있는 종목이면 추가 false for (var y = 0; y < ItemList.length; y++ ) { if (aItemList[x] == ItemList[y] ) { add = false; } } //제외종목관심그룹에 있는 종목이면 추가 false for (var z = 0; z < ExList.length; z++ ) { if (aItemList[x] == ExList[z] ) { add = false; } } //최종 true이면 추가리스트에 추가 if (add == true) { AddList.push(aItemList[x])); Main.SendInterests("관심종목1",aItemList[x],true); } } if (AddList.length > 0) { ReqCount = 0; var TradeSet = new SystemTradeInfo(TRADE_FIXCAPITAL, 1, // 거래수량 500000, // 자산 1, // 단위수량 0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료 0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지 PYRAMIDING_ENTRY, // 피라미딩 설정여부(다른진입신호만 허용) 100000, // 최대진입수량 20); // 최대진입횟수 var ChartSet = new ReqChartItem(ItemList[ReqCount],1,CHART_PERIOD_DAILY,600,CHART_REQCOUNT_BAR,true,false); /////SystemInfo(name,kind,inputVar,tradeInfo,stopInfo) var SystemSet = new SystemInfo("거래(관심종목1)", YL_TYPE_NORMAL, null, TradeSet); Main.ReqChartEx(ChartSet,SystemSet); Main.MessageList("확장차트생성요청:",AddList[ReqCount]); } } } //신호발생 function Main_OnRiseSignal(ChartEx, Signal) { //계좌 보유 종목 수 var num1 = Account1.GetTheNumberOfBalances(); //신호발생 종목에 대해 잔고셋팅 Account1.SetBalance(Main.GetOrderCode(Signal.code),0); if (Signal.price < 1000) { ps = 1; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 1000 && Signal.price < 5000) { ps = 5; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 5000 && Signal.price < 10000) { ps = 10; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 10000 && Signal.price < 50000) { ps = 50; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 50000 && Signal.price < 100000) { ps = 100; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 100000) { ps = 1000; S_price = Math.floor(Signal.price/ps)*ps; } //매수신호이고 잔고가 없을때만 매수 수정 if (Signal.signalKind == 1) ////// && Account1.Balance.count == 0) { if (Signal.name != "b2" && num1<=50 && Account1.Balance.count == 0 && daycount1 < 5) // 매수신호가 b2가 아닌 경우 기존 잔고가 없는 경우에만 매수하고, 일 5종목까지만 매수 { Account1.OrderBuy(Main.GetOrderCode(Signal.code), 1, S_price + ps*2, 0); Account1.OrderBuy(Main.GetOrderCode(Signal.code), Signal.count-1, S_price + ps*2, 0); daycount1 = daycount1+1; Main.MessageList("매수주문8"); Main.MessageLog("1차매수 후 매도 "+S_price); } if (Signal.name == "b2" && num1<=50 && daycount2 < 5)//매수신호가 b2인 경우에는 기매수되지 않았더라도 일 5종목까지 매수 { Account1.OrderBuy(Main.GetOrderCode(Signal.code), 2, S_price + ps*2, 0); Account1.OrderBuy(Main.GetOrderCode(Signal.code), Signal.count-2, S_price + ps*2, 0); daycount2 = daycount2+1; Main.MessageList("매수주문9"); Main.MessageLog("2차매수 후 매도 "+S_price); } } 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), 1, S_price - ps*2, 0); Account1.OrderSell(Main.GetOrderCode(Signal.code), Signal.count-1, S_price - ps*2, 0); Main.MessageList("매도주문"); } } } 즐거운 하루되세요 > 예스스탁 님이 쓴 글입니다. > 제목 : Re : 02-3453-1060으로 전화주시기 바랍니다. > > 깜피 님이 쓴 글입니다. > 제목 : 미완성 신호 거래 등에 대한 수식 수정 부탁드립니다. > 안녕하세요. 전에 작성해 주신 수식을 일부 수정하여 현재 반자동화된 거래를 진행하는데 너무 잘 활용하고 있습니다. 최근에 거래 로직을 수정하면서 조금 더 자동화된 형태로 거래하고 싶어서 재차 도움을 구합니다. 기존 사용하던 yesspot 수식을 재차 수정해서 올렸으니 가이드를 주시면 참고해서 다시 열심히 매매에 임하겠습니다. 거래에 큰 도움을 주셔서 항상 감사드립니다. 연말 마무리 잘 하시고 새해 복 많이 받으세요. --------------------------------------------------------------------------------------------- [거래순서] * yespot 실행 시 관심종목리스트에 있는 종목을 대상으로 차트객체 생성 * 장 중(시초거래 및 장 중 거래)에 매수/매도 진행(미체결된 경우 10초 단위로 현재가 +(-)한호가씩 변경하며 계약 체결) - 매수 신호가 b2일 경우에는 무조건 매수 - 매수 신호가 b2가 아닌 경우에는 계좌에 같은 종목이 없는 경우에만 매수 * 152000 파워종목검색 실행 * 검색된 종목 중 관심종목리스트에 없는 종목에 대해 차트객체 추가하고 관심종목리스트에 추가 * 관심종목리스트를 대상으로 동시호가에 완성신호 또는 미완성신호로 매수/매도 거래 (분할 매수(매도) 로직이 포함되어 있어서, 종가에 완성신호 및 미완성 신호가 발생합니다. 현재는 미완성신호 거래가 생각대로 잘안돼서 익일 시초가 매매로 돌려서 거래 중인데 동시호가 거래나 미체결 시 장후시간외 거래로 거래 방식을 수정하고 싶습니다) - 매수 신호가 b2일 경우에는 무조건 매수 - 매수 신호가 b2가 아닌 경우에는 계좌에 같은 종목이 없는 경우에만 매수 ---------------------------------------------------------------------------- var ItemList; var Count; var daycount; var daycount1=0; var daycount2=0; var YYYYMMDD; var ReqCount; var d; var H; var S_price; var ps; var value1 = 0; var HHMMSS; function Main_OnStart() { Main.MessageLog("스팟시작"); d = new Date(); h=d.getDate(); YYYYMMDD = d.getFullYear()*10000 +(d.getMonth()+1)*100+d.getDate(); if (Main.GetUserValue(YYYYMMDD) == "") { daycount = 0; } else { daycount = Main.GetUserValue(YYYYMMDD); } //지정한 관심그룹의 종목수(관심그룹지정 필요) 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, // 거래수량 500000, // 자산 1, // 단위수량 0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료 0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지 PYRAMIDING_ENTRY, // 피라미딩 설정여부(다른진입신호만 허용) 100000, // 최대진입수량 20); // 최대진입횟수 var ChartSet = new ReqChartItem(ItemList[ReqCount],1,CHART_PERIOD_DAILY,600,CHART_REQCOUNT_BAR,true,false); /////SystemInfo(name,kind,inputVar,tradeInfo,stopInfo) var SystemSet = new SystemInfo("거래(관심종목1)", YL_TYPE_NORMAL, null, TradeSet); Main.ReqChartEx(ChartSet,SystemSet); Main.MessageList("확장차트생성요청:",ItemList[ReqCount]); ReqCount = ReqCount+1; if (ReqCount == Count) { Main.KillTimer(1); Main.MessageList("종목객체생성완료"); } } HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds(); ///// if (HHMMSS > 152000) ///// { Main.MessageList("start(종목검색))"); Main.KillTimer(1);// Main.ReqPowerSearch("종목검색_일봉거래"); } } function Main_OnRcvItemList(aItemList, nCount) { Main.MessageList("종목검색 완료 nCount : ",nCount,MK.length); Main.MessageList("종목검색 완료 aItemList : ",aItemList); ////////////////////////////////////////// // 종목 검색 후 관심종목리스트에 없는 종목은 확장차트 생성 후, 관심종목에 등록. ////////////////////////////////////////// if (nCount > 0) { Main.SendInterests("관심종목1", aItemList,false); Main.MessageList("관심종목 등록"); } } //신호발생 function Main_OnRiseSignal(ChartEx, Signal) { //계좌 보유 종목 수 var num1 = Account1.GetTheNumberOfBalances(); //신호발생 종목에 대해 잔고셋팅 Account1.SetBalance(Main.GetOrderCode(Signal.code),0); if (Signal.price < 1000) { ps = 1; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 1000 && Signal.price < 5000) { ps = 5; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 5000 && Signal.price < 10000) { ps = 10; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 10000 && Signal.price < 50000) { ps = 50; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 50000 && Signal.price < 100000) { ps = 100; S_price = Math.floor(Signal.price/ps)*ps; } if (Signal.price >= 100000) { ps = 1000; S_price = Math.floor(Signal.price/ps)*ps; } //매수신호이고 잔고가 없을때만 매수 수정 if (Signal.signalKind == 1) ////// && Account1.Balance.count == 0) { if (Signal.name != "b2" && num1<=50 && Account1.Balance.count == 0 && daycount1 < 5) // 매수신호가 b2가 아닌 경우 기존 잔고가 없는 경우에만 매수하고, 일 5종목까지만 매수 { Account1.OrderBuy(Main.GetOrderCode(Signal.code), 1, S_price + ps*2, 0); Account1.OrderBuy(Main.GetOrderCode(Signal.code), Signal.count-1, S_price + ps*2, 0); daycount1 = daycount1+1; Main.MessageList("매수주문8"); Main.MessageLog("1차매수 후 매도 "+S_price); } if (Signal.name == "b2" && num1<=50 && daycount2 < 5)//매수신호가 b2인 경우에는 기매수되지 않았더라도 일 5종목까지 매수 { Account1.OrderBuy(Main.GetOrderCode(Signal.code), 2, S_price + ps*2, 0); Account1.OrderBuy(Main.GetOrderCode(Signal.code), Signal.count-2, S_price + ps*2, 0); daycount2 = daycount2+1; Main.MessageList("매수주문9"); Main.MessageLog("2차매수 후 매도 "+S_price); } } 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); } ////////------------->미체결 또는 부분체결 시 10초 단위로 현재가 +(-)1호가씩 변경하며 거래체결하는 로식 삽입 } if (Account1.Balance.count > 0) { Account1.OrderSell(Main.GetOrderCode(Signal.code), 1, S_price - ps*2, 0); Account1.OrderSell(Main.GetOrderCode(Signal.code), Signal.count-1, S_price - ps*2, 0); Main.MessageList("매도주문"); ///////------------>미체결 또는 부분체결된 경우 잔여 물량에 대해 장후 시간외 거래하는 로직 추가 } } } //신호발생 function Main_OnRiseIncompleteSignal(ChartEx, IncompleteSignal) { if (HHMMSS > 152000) ///// { //계좌 보유 종목 수 var num1 = Account1.GetTheNumberOfBalances(); //신호발생 종목에 대해 잔고셋팅 Account1.SetBalance(Main.GetOrderCode(IncompleteSignal.code),0); if (IncompleteSignal.price < 1000) { ps = 1; S_price = Math.floor(IncompleteSignal.price/ps)*ps; } if (IncompleteSignal.price >= 1000 && IncompleteSignal.price < 5000) { ps = 5; S_price = Math.floor(IncompleteSignal.price/ps)*ps; } if (IncompleteSignal.price >= 5000 && IncompleteSignal.price < 10000) { ps = 10; S_price = Math.floor(IncompleteSignal.price/ps)*ps; } if (IncompleteSignal.price >= 10000 && IncompleteSignal.price < 50000) { ps = 50; S_price = Math.floor(Signal.price/ps)*ps; } if (IncompleteSignal.price >= 50000 && IncompleteSignal.price < 100000) { ps = 100; S_price = Math.floor(IncompleteSignal.price/ps)*ps; } if (IncompleteSignal.price >= 100000) { ps = 1000; S_price = Math.floor(IncompleteSignal.price/ps)*ps; } if (IncompleteSignal.signalKind == 1) { if (IncompleteSignal.name != "b2" && num1<=50 && Account1.Balance.count == 0 && daycount1 < 5) // 매수신호가 b2가 아닌 경우 기존 잔고가 없는 경우에만 매수하고, 일 5종목까지만 매수 { Account1.OrderBuy(Main.GetOrderCode(IncompleteSignal.code), 2, S_price + ps*2, 0); Account1.OrderBuy(Main.GetOrderCode(IncompleteSignal.code),Signal.count-2, S_price + ps*2, 0); daycount1 = daycount1+1; Main.MessageList("매수주문10"); Main.MessageLog("1차매수 후 매도 "+S_price); ///////------------>미체결 또는 부분체결된 경우 잔여 물량에 대해 장후 시간외 거래하는 로직 추가 } if (IncompleteSignal.name == "b2" && num1<=50 && daycount2 < 5)// 매수신호가 b2인 경우에는 기매수되지 않았더라도 일 5종목까지 매수 { Account1.OrderBuy(Main.GetOrderCode(IncompleteSignal.code), 2, S_price + ps*2, 0); // 2호가 위 매수 Account1.OrderBuy(Main.GetOrderCode(IncompleteSignal.code), IncompleteSignal.count-2, S_price + ps*2, 0); daycount2 = daycount2+1; Main.MessageList("매수주문10"); Main.MessageLog("2차매수 후 매도 "+S_price); ///////------------>미체결 또는 부분체결된 경우 잔여 물량에 대해 장후 시간외 거래하는 로직 추가 } if (Account1.Balance.count > 0) { Account1.OrderSell(Main.GetOrderCode(IncompleteSignal.code), 1, S_price - ps*2, 0); Account1.OrderSell(Main.GetOrderCode(IncompleteSignal.code), IncompleteSignal.count-1, S_price - ps*2, 0); ///////------------>미체결 또는 부분체결된 경우 잔여 물량에 대해 장후 시간외 거래하는 로직 추가 } } } }