커뮤니티

보유종목 수량 추가시 자동청산로직 추가부탁합니다.

프로필 이미지
영원한자유
2019-08-08 14:55:19
3211
글번호 224947
답변완료
안녕하세요? 하기의 로직은 신규 추가 종목에 대해서는 잘동작하지만, 기존 보유종목의 분할매수로 인해서 수량이 추가되는 변동이 있을때는 인식을 못하는 것 같습니다. 따라서, 보유종목의 수량 추가에 대해서도 자동으로 수량인식되어 올바르게 청산될수 있도록 수정부탁드립니다. 특히, 수량이 추가되었을때 평균매수가격에 오류가 납니다. ------------------------------------------------------------------- 4 var Nth = 0; var ItemCode = []; var ItemObject = []; var ItemHigh = []; var Bnum; function Main_OnStart() { Nth = 0; Bnum = Account1.GetTheNumberOfBalances() Main.MessageList("잔고종목수",Bnum); if (Bnum > 0) { //계좌의 잔고리스트에서 첫번째 잔고 셋팅 Account1.SetBalanceIndex(Nth);//잔고는 순번이 0부터 시작 //셋팅된 잔고의 수량이 0이상이면 if (Account1.Balance.count > 0) { Main.MessageList("보유종목 종목객체요청시작-------"); //1번째 종목객체 생성요청 Main.ReqMarketData(Account1.Balance.code, 0,0); //ItemCode의 [Nth]번째 방에 종목코드 저장 ItemCode[Nth] = Account1.Balance.code; Main.MessageList("종목객체요청",Account1.Balance.code); } } } //요청한 종목객체 수신되면 function Main_OnRcvMarketData(MarketData) { Main.MessageList("종목객체수신",MarketData.code); //수신받은 종목객체의 종목코드와 직전에 요청한 종목과 같은지 확인 후에 if (MarketData.code == ItemCode[Nth]) { ItemObject[Nth] = MarketData;//ItemObject의 [Nth]방에 수신받은 객체를 저장 ItemHigh[Nth] = 0; //ItemHigh의 [Nth]방의 값을 0으로 셋팅 (이후 최고값 계산해 저장할 변수) Main.MessageList(Nth,"번째","종목객체생성완료 : ",ItemObject[Nth].code); //순번은 1 증가 Nth = Nth+1; //종목객체 수신완료되면 다음 종목 종목객체 요청 if (Nth < Bnum) { //계좌의 잔고리스트에서 다음 순번 잔고 셋팅 Account1.SetBalanceIndex(Nth); //셋팅된 잔고의 수량이 0이상이면 if (Account1.Balance.count > 0) { //Nth번째 종목객체 생성요청 Main.ReqMarketData(Account1.Balance.code, 0,0); //ItemCode의 [Nth]번째 방에 종목코드 저장 ItemCode[Nth] = Account1.Balance.code; Main.MessageList("종목객체요청",Account1.Balance.code); } } else { Main.MessageList("보유종목 종목객체요청완료------"); } } } //잔고에 종목이 추가된다면 function Main_OnUp*dateAccount(sAccntNum, sItemCode, lUp*dateID) //*삭제 { if (sAccntNum == Account1.number && lUp*dateID == 30001) //*삭제 { Main.MessageList("신규편입종목 객체요청",sItemCode,Nth); //ItemCode의 [Nth]번째 방에 종목코드 저장 ItemCode[Nth] = sItemCode; //1번째 종목객체 생성요청 Main.ReqMarketData(ItemCode[Nth], 0,0); } } //종목객체 시세 업데이트 function Main_OnUp*dateMarket(sItemCode, lUp*dateID)// *제거 { //편입된 종목수 만킄만 수행 for (var i = 0; i < ItemObject.length; i++) { if (ItemObject[i].code == sItemCode && lUp*dateID == 20001)// *제거 { Main.MessageList("-----------------------------------------------"); Main.MessageList(ItemObject[i].code,"업데이트"); //잔고셋팅 Account1.SetBalanceItem(ItemObject[i].code,0); //종목편입 이후의 최고가 계산 if (ItemObject[i].current > ItemHigh[i]) { ItemHigh[i] = ItemObject[i].current; } //매수잔고 if (Account1.Balance.position == 2) { //현재가가 평균단가 대비 10%이상 상승하면 목표이익 매도 if (ItemObject[i].current >= Account1.Balance.avgUnitCost*1.10) { Account1.OrderSell(Account1.Balance.code,Account1.Balance.count, 0,1); //주문 후 해당 종목객체 삭제 Main.RemoveMarketData(ItemObject[i]); Main.MessageList("수익청산 : ",ItemObject[i].code,"종목객체삭제"); } // 현재가가 평균단가 대비 3%이상 하락하면 손절매도 if (ItemObject[i].current <= Account1.Balance.avgUnitCost*0.97) { Account1.OrderSell(Account1.Balance.code,Account1.Balance.count, 0,1); //주문 후 해당 종목객체 삭제 Main.RemoveMarketData(ItemObject[i]); Main.MessageList("손절청산 : ",ItemObject[i].code,"종목객체삭제"); } //현재가가 평균단가 대비 7% 이상 상승후 평균단가+5%까지 하락하면 매도주문 if (ItemHigh[i] >= Account1.Balance.avgUnitCost*1.07 && ItemObject[i].current <= Account1.Balance.avgUnitCost*1.05) { Account1.OrderSell(Account1.Balance.code,Account1.Balance.count, 0,1); //주문 후 해당 종목객체 삭제 Main.RemoveMarketData(ItemObject[i]); Main.MessageList("TR청산 : ",ItemObject[i].code,"종목객체삭제"); } } Main.MessageList("-----------------------------------------------"); Main.MessageList("종 목 : ",ItemObject[i].code); Main.MessageList("평균단가 : ",Account1.Balance.avgUnitCost); Main.MessageList("현 재 가 : ",ItemObject[i].current); Main.MessageList("진입최고 : ",ItemHigh[i]); } } }
답변 1
프로필 이미지

예스스탁 예스스탁 답변

2019-08-23 14:31:58

안녕하세요 예스스탁입니다. 해당 수식을 테스트해 보았지만 문제점을 찾지 못했습니다. 최초에 보유종목에 대해서난 종목객체를 요청해서 업데이트되는 시세로 조건만 체크하게 됩니다. 수량은 별도로 저장하지 않습니다 수식에서 별도의 게산으로 평단가나 보유수량을 계산하는 것은 아닙니다. 시세가 들어오면 매번 해당 종목에 대해 잔고가 셋팅되고 평단가와 보유수량을 가져와 사용하게 됩니다. 즐거운 하루되세요 > 영원한자유 님이 쓴 글입니다. > 제목 : 보유종목 수량 추가시 자동청산로직 추가부탁합니다. > 안녕하세요? 하기의 로직은 신규 추가 종목에 대해서는 잘동작하지만, 기존 보유종목의 분할매수로 인해서 수량이 추가되는 변동이 있을때는 인식을 못하는 것 같습니다. 따라서, 보유종목의 수량 추가에 대해서도 자동으로 수량인식되어 올바르게 청산될수 있도록 수정부탁드립니다. 특히, 수량이 추가되었을때 평균매수가격에 오류가 납니다. ------------------------------------------------------------------- 4 var Nth = 0; var ItemCode = []; var ItemObject = []; var ItemHigh = []; var Bnum; function Main_OnStart() { Nth = 0; Bnum = Account1.GetTheNumberOfBalances() Main.MessageList("잔고종목수",Bnum); if (Bnum > 0) { //계좌의 잔고리스트에서 첫번째 잔고 셋팅 Account1.SetBalanceIndex(Nth);//잔고는 순번이 0부터 시작 //셋팅된 잔고의 수량이 0이상이면 if (Account1.Balance.count > 0) { Main.MessageList("보유종목 종목객체요청시작-------"); //1번째 종목객체 생성요청 Main.ReqMarketData(Account1.Balance.code, 0,0); //ItemCode의 [Nth]번째 방에 종목코드 저장 ItemCode[Nth] = Account1.Balance.code; Main.MessageList("종목객체요청",Account1.Balance.code); } } } //요청한 종목객체 수신되면 function Main_OnRcvMarketData(MarketData) { Main.MessageList("종목객체수신",MarketData.code); //수신받은 종목객체의 종목코드와 직전에 요청한 종목과 같은지 확인 후에 if (MarketData.code == ItemCode[Nth]) { ItemObject[Nth] = MarketData;//ItemObject의 [Nth]방에 수신받은 객체를 저장 ItemHigh[Nth] = 0; //ItemHigh의 [Nth]방의 값을 0으로 셋팅 (이후 최고값 계산해 저장할 변수) Main.MessageList(Nth,"번째","종목객체생성완료 : ",ItemObject[Nth].code); //순번은 1 증가 Nth = Nth+1; //종목객체 수신완료되면 다음 종목 종목객체 요청 if (Nth < Bnum) { //계좌의 잔고리스트에서 다음 순번 잔고 셋팅 Account1.SetBalanceIndex(Nth); //셋팅된 잔고의 수량이 0이상이면 if (Account1.Balance.count > 0) { //Nth번째 종목객체 생성요청 Main.ReqMarketData(Account1.Balance.code, 0,0); //ItemCode의 [Nth]번째 방에 종목코드 저장 ItemCode[Nth] = Account1.Balance.code; Main.MessageList("종목객체요청",Account1.Balance.code); } } else { Main.MessageList("보유종목 종목객체요청완료------"); } } } //잔고에 종목이 추가된다면 function Main_OnUp*dateAccount(sAccntNum, sItemCode, lUp*dateID) //*삭제 { if (sAccntNum == Account1.number && lUp*dateID == 30001) //*삭제 { Main.MessageList("신규편입종목 객체요청",sItemCode,Nth); //ItemCode의 [Nth]번째 방에 종목코드 저장 ItemCode[Nth] = sItemCode; //1번째 종목객체 생성요청 Main.ReqMarketData(ItemCode[Nth], 0,0); } } //종목객체 시세 업데이트 function Main_OnUp*dateMarket(sItemCode, lUp*dateID)// *제거 { //편입된 종목수 만킄만 수행 for (var i = 0; i < ItemObject.length; i++) { if (ItemObject[i].code == sItemCode && lUp*dateID == 20001)// *제거 { Main.MessageList("-----------------------------------------------"); Main.MessageList(ItemObject[i].code,"업데이트"); //잔고셋팅 Account1.SetBalanceItem(ItemObject[i].code,0); //종목편입 이후의 최고가 계산 if (ItemObject[i].current > ItemHigh[i]) { ItemHigh[i] = ItemObject[i].current; } //매수잔고 if (Account1.Balance.position == 2) { //현재가가 평균단가 대비 10%이상 상승하면 목표이익 매도 if (ItemObject[i].current >= Account1.Balance.avgUnitCost*1.10) { Account1.OrderSell(Account1.Balance.code,Account1.Balance.count, 0,1); //주문 후 해당 종목객체 삭제 Main.RemoveMarketData(ItemObject[i]); Main.MessageList("수익청산 : ",ItemObject[i].code,"종목객체삭제"); } // 현재가가 평균단가 대비 3%이상 하락하면 손절매도 if (ItemObject[i].current <= Account1.Balance.avgUnitCost*0.97) { Account1.OrderSell(Account1.Balance.code,Account1.Balance.count, 0,1); //주문 후 해당 종목객체 삭제 Main.RemoveMarketData(ItemObject[i]); Main.MessageList("손절청산 : ",ItemObject[i].code,"종목객체삭제"); } //현재가가 평균단가 대비 7% 이상 상승후 평균단가+5%까지 하락하면 매도주문 if (ItemHigh[i] >= Account1.Balance.avgUnitCost*1.07 && ItemObject[i].current <= Account1.Balance.avgUnitCost*1.05) { Account1.OrderSell(Account1.Balance.code,Account1.Balance.count, 0,1); //주문 후 해당 종목객체 삭제 Main.RemoveMarketData(ItemObject[i]); Main.MessageList("TR청산 : ",ItemObject[i].code,"종목객체삭제"); } } Main.MessageList("-----------------------------------------------"); Main.MessageList("종 목 : ",ItemObject[i].code); Main.MessageList("평균단가 : ",Account1.Balance.avgUnitCost); Main.MessageList("현 재 가 : ",ItemObject[i].current); Main.MessageList("진입최고 : ",ItemHigh[i]); } } }