커뮤니티

수식 추가 수정 부탁드립니다.

프로필 이미지
늘그렇게
2024-07-15 22:31:47.0
651
글번호 226040
답변완료
안녕하세요. 매번 예스스탁의 커뮤니티를 이용하여 많은 내용들을 배우고 또 질문에 성의 껏 답변해 주심에 감사드립니다. 질문하나 드립니다. 예스스팟에서 아래 스팟 수식을 이용하여 예스랭귀지로 만든 수식으로 파워종목을 만들어 자동 매수하고, 미리 일괄적으로 정해 둔 적절한 수익률과 손절률을 'STOP 주문설정' 창에 셋팅하여 자동 매도를 하고 있는데, 모든 종목의 스텐스가 달라 일정비율의 매도는 비효율적이어서 익과 손절을 적절히 못하고 있습니다. 그래서 파워종목으로 편집한 매도 조건을 포함하여 보유 종목을 대상으로 자동 매도를 하거나, 아니면 간단한 지표 몇가지를 스팟 수식에 추가 설정하여 자동 매도가 되게 만들고 싶습니다. 1. 매수한 보유종목 중 매도조건에 충족되면 자동 매도가 되도록 정하고 싶습니다. 예) 예스랭귀지로 매수[파일명 : MY_BB030]와 매도[파일명 : MY_SS123]의 조건을 편집해서 파워종목 식으로 자동 매수 매도되게 스팟수식을 만든다. 2. 몇 가지 지표들로 매도조건을 정하여 스팟 수식에 포함하여 자동매도 되도록 한다. 예) 특정 주기와 D값을 이용하여 그 볼린저밴드의 상단선을 상향돌파 또는 하향돌파하는 시점에 자동 매도 또는 종가가 5이평 하향돌파 시 자동 매도, 엔벨 상한선이 2일 연속 하락하고 종가가 시가보다 하락하면 자동 매도 등의 간단한 조건을 스팟 수식에 포함하여 자동매도한다. 3. 예스랭귀지와 파워종목 검색식으로 매도 조건의 수식을 만들어서 예스 스팟과 연동되게 하는 스팟에서 추가되는 부분에 대해서도 설명해주시면 고맙겠습니다. 4. 계좌별 보유종목에 적용하여 사용하고자 합니다. 위 1)번과 2)번 조건이 만족되면 자동 매도하는 것입니다. 부탁드립니다. 현재 사용하고 있는 예스스팟 매수매도 수식 -------------------- var M_Buy = 50000000;//종목당 1회 매수금액 var OPEN_T = 90000; var CLOSE_T = 120000; var SearchName = "MY_BB030"; //PowerSearch Name var timer = 10; //매수 매도 초(시간) 간격 var Earning_Rate = 1.12; //계좌평가금액이 스팟시작시 평가금액대비 12% 이상이면 전종목 전량매도 var Trailing_Stop = 0.8; // 전량 손절 var Earning_Sale = 1.12; // 전량 익절 var OrderList = []; var MKList = []; var req; function Main_OnStart() { //1번 타이머, "timer" 초 Main.SetTimer(1, timer*1000); // 오늘 매수한 종목 관리 배열 초기화 MKList = []; //스팟 시작시 잔고평가금액 V1 = Account1.GetBalanceETCinfo(100); } function Main_OnTimer(nEventID) { var d = new Date(); YYYYMMDD = d.getFullYear()*10000+(d.getMonth()+1)*100+d.getDate(); HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds(); if (nEventID == 1 && HHMMSS >= OPEN_T && HHMMSS < CLOSE_T) { //종목검색 수행 Main.ReqPowerSearch(SearchName) Main.MessageList("ReqPowerSearch1"); } if (nEventID == 1) { //계좌보유종수 var num = Account1.GetTheNumberOfBalances(); //9시~15시 15분 사이 if (HHMMSS >= 90000 && HHMMSS < 151500) { //보유종목이 1개 이상 if (num >= 1) { //계좌평가금액이 스팟시작시 평가금액대비 12% 이상이면 전종목 전량매도 if (Account1.GetBalanceETCinfo(100) >= V1*Earning_Rate) { //1번 타이머 종료 Main.KillTimer(1); //계좌리스트의 순서대로 for (var i = 0; i < num; i++) { //잔고를 셋팅 Account1.SetBalance(i); //수량이 있고 Earning_Rate(60%)수익이거나 손실이면 시장가 매도 if (Account1.Balance.count > 0) { Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1); } } } else //아니면 개별종목 30% Earning_Sale, -20% Trailing_Stop 체크 { //계좌리스트의 순서대로 for (var i = 0; i < num; i++) { //잔고를 셋팅 Account1.SetBalance(i); //수량이 있고 "Earning_Sale"수익이거나 "Trailing_Stop" 손실이면 시장가 매도 if (Account1.Balance.count > 0 && (Account1.Balance.current >= Account1.Balance.avgUnitCost*Earning_Sale || Account1.Balance.current <= Account1.Balance.avgUnitCost*Trailing_Stop)) { Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1); } } } } } /* 15시 15분 이후이면 계좌의 모든 잔량 시장가 매도 관련 시스템[시작] 15시 15분 이후이면 계좌의 모든 잔량 시장가 매도 관련 시스템[시작] if (HHMMSS >= 151500) { //1번 타이머 종료 Main.KillTimer(1); //계좌리스트의 순서대로 for (var i = 0; i < num; i++) { //잔고를 셋팅 Account1.SetBalance(i); //수량이 있고 5%수익이거나 5% 손실이면 시장가 매도 if (Account1.Balance.count > 0) { Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1); } } } 15시 15분 이후이면 계좌의 모든 잔량 시장가 매도 관련 시스템[시작] 15시 15분 이후이면 계좌의 모든 잔량 시장가 매도 관련 시스템[시작] */ } if (nEventID == 2) { Main.ReqMarketData(OrderList[req]); Main.MessageList("ReqMarketData:",OrderList[req]); ; } } function Main_OnRcvItemList(aItemList, nCount) { Main.KillTimer(1); Main.MessageList("aItemList:",aItemList); OrderList = []; if (nCount >= 1) { if (MKList.length == 0) { OrderList = aItemList; } else { for (var a = 0; a < nCount; a++) { var Add = true; for (var b = 0; b < MKList.length; b++) { if (aItemList[a] == MKList[b].code) { Add = false; } } if (Add == true && !IsStockInAccount(aItemList[a])) { OrderList.push(aItemList[a]); } } } } Main.MessageList("OrderList:",OrderList); if (OrderList.length == 0) { Main.SetTimer(1, timer*1000); } else { req = 0; Main.ReqMarketData(OrderList[req]); Main.MessageList("ReqMarketData:",OrderList[req]); ; } } function Main_OnRcvMarketData(MarketData) { if (MarketData.code == OrderList[req]) { MKList.push(MarketData); // 계좌에 같은 종목이 있는지 확인 if (!IsStockInAccount(MarketData.code)) { // 계좌에 없는 경우에만 매수 // Account1.OrderBuy(MarketData.code,1,0,1); Account1.OrderBuy(MarketData.code,Math.floor(M_Buy/MarketData.Ask(1)),0,1); // Account1.OrderBuy(MarketData.code,Math.floor(M_Buy/MarketData.Ask(1)),MarketData.Ask(1),0); //지정가로 주문하고자 하시면 주문함수 내용을 위와 같이 변경하시면 됩니다. Main.MessageList(MarketData.code + " 주식을 매수합니다."); } else { Main.MessageList( MarketData.code + " 주식은 이미 계좌에 있으므로 매수하지 않습니다."); } req = req+1; if (req < OrderList.length) { var aa = Main.ReqMarketData(OrderList[req]); Main.MessageList("ReqMarketData:",OrderList[req]); ; if (aa == -1) { Main.SetTimer(2, 15000); } } else { Main.SetTimer(1, timer*1000); } } } function IsStockInAccount(stockCode) { // 계좌에 해당 종목이 있는지 확인하는 함수 var numberOfBalances = Account1.GetTheNumberOfBalances(); for (var i = 0; i < numberOfBalances; i++) { Account1.SetBalance(i); if (stockCode == Account1.Balance.code) { return true; // 계좌에 같은 종목이 있으면 true 반환 } } return false; // 계좌에 같은 종목이 없으면 false 반환 } 감사합니다.
답변 2
프로필 이미지

예스스탁 예스스탁 답변

2024-08-05 17:49:21.0

> 늘그렇게 님이 쓴 글입니다. > 제목 : 수식 추가 수정 부탁드립니다. > 안녕하세요. 매번 예스스탁의 커뮤니티를 이용하여 많은 내용들을 배우고 또 질문에 성의 껏 답변해 주심에 감사드립니다. 질문하나 드립니다. 예스스팟에서 아래 스팟 수식을 이용하여 예스랭귀지로 만든 수식으로 파워종목을 만들어 자동 매수하고, 미리 일괄적으로 정해 둔 적절한 수익률과 손절률을 'STOP 주문설정' 창에 셋팅하여 자동 매도를 하고 있는데, 모든 종목의 스텐스가 달라 일정비율의 매도는 비효율적이어서 익과 손절을 적절히 못하고 있습니다. 그래서 파워종목으로 편집한 매도 조건을 포함하여 보유 종목을 대상으로 자동 매도를 하거나, 아니면 간단한 지표 몇가지를 스팟 수식에 추가 설정하여 자동 매도가 되게 만들고 싶습니다. 1. 매수한 보유종목 중 매도조건에 충족되면 자동 매도가 되도록 정하고 싶습니다. 예) 예스랭귀지로 매수[파일명 : MY_BB030]와 매도[파일명 : MY_SS123]의 조건을 편집해서 파워종목 식으로 자동 매수 매도되게 스팟수식을 만든다. 2. 몇 가지 지표들로 매도조건을 정하여 스팟 수식에 포함하여 자동매도 되도록 한다. 예) 특정 주기와 D값을 이용하여 그 볼린저밴드의 상단선을 상향돌파 또는 하향돌파하는 시점에 자동 매도 또는 종가가 5이평 하향돌파 시 자동 매도, 엔벨 상한선이 2일 연속 하락하고 종가가 시가보다 하락하면 자동 매도 등의 간단한 조건을 스팟 수식에 포함하여 자동매도한다. 3. 예스랭귀지와 파워종목 검색식으로 매도 조건의 수식을 만들어서 예스 스팟과 연동되게 하는 스팟에서 추가되는 부분에 대해서도 설명해주시면 고맙겠습니다. 4. 계좌별 보유종목에 적용하여 사용하고자 합니다. 위 1)번과 2)번 조건이 만족되면 자동 매도하는 것입니다. 부탁드립니다. 현재 사용하고 있는 예스스팟 매수매도 수식 -------------------- var M_Buy = 50000000;//종목당 1회 매수금액 var OPEN_T = 90000; var CLOSE_T = 120000; var SearchName = "MY_BB030"; //PowerSearch Name var timer = 10; //매수 매도 초(시간) 간격 var Earning_Rate = 1.12; //계좌평가금액이 스팟시작시 평가금액대비 12% 이상이면 전종목 전량매도 var Trailing_Stop = 0.8; // 전량 손절 var Earning_Sale = 1.12; // 전량 익절 var OrderList = []; var MKList = []; var req; function Main_OnStart() { //1번 타이머, "timer" 초 Main.SetTimer(1, timer*1000); // 오늘 매수한 종목 관리 배열 초기화 MKList = []; //스팟 시작시 잔고평가금액 V1 = Account1.GetBalanceETCinfo(100); } function Main_OnTimer(nEventID) { var d = new Date(); YYYYMMDD = d.getFullYear()*10000+(d.getMonth()+1)*100+d.getDate(); HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds(); if (nEventID == 1 && HHMMSS >= OPEN_T && HHMMSS < CLOSE_T) { //종목검색 수행 Main.ReqPowerSearch(SearchName) Main.MessageList("ReqPowerSearch1"); } if (nEventID == 1) { //계좌보유종수 var num = Account1.GetTheNumberOfBalances(); //9시~15시 15분 사이 if (HHMMSS >= 90000 && HHMMSS < 151500) { //보유종목이 1개 이상 if (num >= 1) { //계좌평가금액이 스팟시작시 평가금액대비 12% 이상이면 전종목 전량매도 if (Account1.GetBalanceETCinfo(100) >= V1*Earning_Rate) { //1번 타이머 종료 Main.KillTimer(1); //계좌리스트의 순서대로 for (var i = 0; i < num; i++) { //잔고를 셋팅 Account1.SetBalance(i); //수량이 있고 Earning_Rate(60%)수익이거나 손실이면 시장가 매도 if (Account1.Balance.count > 0) { Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1); } } } else //아니면 개별종목 30% Earning_Sale, -20% Trailing_Stop 체크 { //계좌리스트의 순서대로 for (var i = 0; i < num; i++) { //잔고를 셋팅 Account1.SetBalance(i); //수량이 있고 "Earning_Sale"수익이거나 "Trailing_Stop" 손실이면 시장가 매도 if (Account1.Balance.count > 0 && (Account1.Balance.current >= Account1.Balance.avgUnitCost*Earning_Sale || Account1.Balance.current <= Account1.Balance.avgUnitCost*Trailing_Stop)) { Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1); } } } } } /* 15시 15분 이후이면 계좌의 모든 잔량 시장가 매도 관련 시스템[시작] 15시 15분 이후이면 계좌의 모든 잔량 시장가 매도 관련 시스템[시작] if (HHMMSS >= 151500) { //1번 타이머 종료 Main.KillTimer(1); //계좌리스트의 순서대로 for (var i = 0; i < num; i++) { //잔고를 셋팅 Account1.SetBalance(i); //수량이 있고 5%수익이거나 5% 손실이면 시장가 매도 if (Account1.Balance.count > 0) { Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1); } } } 15시 15분 이후이면 계좌의 모든 잔량 시장가 매도 관련 시스템[시작] 15시 15분 이후이면 계좌의 모든 잔량 시장가 매도 관련 시스템[시작] */ } if (nEventID == 2) { Main.ReqMarketData(OrderList[req]); Main.MessageList("ReqMarketData:",OrderList[req]); ; } } function Main_OnRcvItemList(aItemList, nCount) { Main.KillTimer(1); Main.MessageList("aItemList:",aItemList); OrderList = []; if (nCount >= 1) { if (MKList.length == 0) { OrderList = aItemList; } else { for (var a = 0; a < nCount; a++) { var Add = true; for (var b = 0; b < MKList.length; b++) { if (aItemList[a] == MKList[b].code) { Add = false; } } if (Add == true && !IsStockInAccount(aItemList[a])) { OrderList.push(aItemList[a]); } } } } Main.MessageList("OrderList:",OrderList); if (OrderList.length == 0) { Main.SetTimer(1, timer*1000); } else { req = 0; Main.ReqMarketData(OrderList[req]); Main.MessageList("ReqMarketData:",OrderList[req]); ; } } function Main_OnRcvMarketData(MarketData) { if (MarketData.code == OrderList[req]) { MKList.push(MarketData); // 계좌에 같은 종목이 있는지 확인 if (!IsStockInAccount(MarketData.code)) { // 계좌에 없는 경우에만 매수 // Account1.OrderBuy(MarketData.code,1,0,1); Account1.OrderBuy(MarketData.code,Math.floor(M_Buy/MarketData.Ask(1)),0,1); // Account1.OrderBuy(MarketData.code,Math.floor(M_Buy/MarketData.Ask(1)),MarketData.Ask(1),0); //지정가로 주문하고자 하시면 주문함수 내용을 위와 같이 변경하시면 됩니다. Main.MessageList(MarketData.code + " 주식을 매수합니다."); } else { Main.MessageList( MarketData.code + " 주식은 이미 계좌에 있으므로 매수하지 않습니다."); } req = req+1; if (req < OrderList.length) { var aa = Main.ReqMarketData(OrderList[req]); Main.MessageList("ReqMarketData:",OrderList[req]); ; if (aa == -1) { Main.SetTimer(2, 15000); } } else { Main.SetTimer(1, timer*1000); } } } function IsStockInAccount(stockCode) { // 계좌에 해당 종목이 있는지 확인하는 함수 var numberOfBalances = Account1.GetTheNumberOfBalances(); for (var i = 0; i < numberOfBalances; i++) { Account1.SetBalance(i); if (stockCode == Account1.Balance.code) { return true; // 계좌에 같은 종목이 있으면 true 반환 } } return false; // 계좌에 같은 종목이 없으면 false 반환 } 감사합니다.
프로필 이미지

늘그렇게

2024-08-08 20:47:25.0

> 예스스탁 님이 쓴 글입니다. > 제목 : Re : 전화주시기 바랍니다.(02-3453-1060) > 안녕하세요. 오늘 프로그램 수식 관련해서 오후 귀한 시간에 친절히 그리고 오랜 시간 동안 수식 수정을 위해 많이 수고해주셔서 감사드립니다. 말씀하신대로 랭귀지를 조금 더 공부해서 스스로 해결할 수 있어야 하는데, 참~ 어렵네요. 오늘 너무 수고해주시고 또 잘 해결해주셔서 감사하다는 말씀 꼭 전하고 싶었습니다. 염치 없지만 다음에 또 막히는 부분이 있으면 말씀해주신 방법으로 시도해보고 잘 안되는 부분의 핵심만 잘 간추려 질문하도록 하겠습니다. 그리고 수식이나 프로그램 수식에 관한 질문도 이곳(예스스팟 Q&A")이 아닌 '수식작성 Q&A'를 통해서~^^ 거듭 감사드립니다~^^