커뮤니티

가이드라인 좀 부탁드립니다

프로필 이미지
왕밥빵
2023-08-22 23:22:14.0
831
글번호 225828
답변완료
파워종목검색에서 검색된 종목을 1분에 한번씩 새로고침하며 검색이 된종목 매수조건 갖췄을 때 2차매수까지는 하되 매도했을시에는 재진입 안하고 5분봉에서 2봉전 rsi(14)가 30 이상이고 1봉전 rsi(14)가 30밑으로 떨어졌을때 5분봉 1봉전 종가 +1호가로 1차매수, 미체결시 15분뒤 취소주문, 보유종목중에서 1차매수보다 1퍼센트 이상 하락하고 마찬가지로 5분봉 2봉전 rsi(14)가 30이상이고 1봉전 rsi(14)가 30밑으로 떨어졌을때 5분봉 1봉전 종가 +1호가로 2차매수,미체결시 15분뒤 취소주문, 매도는 5분봉 1봉전 rsi(14)가 70 이상일때 5분봉 1봉전 종가에 매도, 미체결시 10분뒤 시장가매도
답변 1
프로필 이미지

예스스탁 예스스탁 답변

2023-09-26 19:17:12.0

안녕하세요 예스스탁입니다. 1 아래 가이드 참고하셔서 수정보완해 사용하시기 바랍니다. 수식의 전반적인 흐름은 1분 간격으로 종목검색을 하고 검색된 종목이 있으면 지정한 지표를 적용한 상태로 차트객체를 만들게 됩니다. 이때 기존에 만들어진 차트가 있는 종목은 제외하고 새로 검색된 종목들만 만들게 됩니다. 차트객체가 만들어지면 배열변수에 만들어진 순서로 0번방부터 객체가 저장됩니다. 이때 각 차트별로 주문과 주문추적에 필요한 값들을 저장하는 배열변수도 동일방번호에 초기값을 가지게 됩니다. 예를 들면 1번방의 차트에서 조건이 충족해 주문을 낼때 주문아이디나 주문번호를 저장하는 배열변수도 동일한 1번방에 값이 저장되게 작성을 해서 각 배열변수의 방번호로 제어를 하게 됩니다. 만들어진 차트객체에서 봉완성시마다 RSI값을 체크해서 잔고에 보유수량이 없고 2봉전 rsi(14)가 30 이상이고 1봉전 rsi(14)가 30밑이면 1봉전 종가+1틱으로 1차 매수를 하게 됩니다.(수량에 대한 정의가 없어 매수는 10주로 지정했습니다) 잔고에 보유수량이 있으면 현재가가 평단가 대비 -1%이고 2봉전 rsi(14)가 30 이상이고 1봉전 rsi(14)가 30밑이면 1봉전 종가+1틱으로 2차 매수를 하게 됩니다.(수량에 대한 정의가 없어 추가매수도 10주로 지정했습니다) 매수는 2차까지만 하게 됩니다. 모두 15분 뒤 미체결이 있으면 취소하게 됩니다. 잔고에 보유수량이 있으면 rsi(14)가 70 이상이면 전량 매도하게 되고 10분뒤 취소하고 시장가로 전량 매도주문합니다. 2 전략에서 RSI가 필요하므로 차트객체를 만들때 RSI지표가 적용되어야 사용이 가능합니다. 기본으로 제공하는 RSI는 수정이나 내용변경의 여지가 있으므로 RSI와 틱값에 대한 지표를 별도로 만들어 적용하셔야 합니다. 아래 2개 지표식을 만들어 놓으시면 됩니다. 2-1. 지표명 #RSI Plot1(RSI(14)); 2-2. 지표명 #틱 Plot1(PriceScale); 3 스크립트 객체화면 설정 계좌객체 추가 --> 속성에서 객체명은 Account1, 주문낼 계좌번호 지정 var reqList = []; //종목검색후 차트객체 요청할 종목코드 저장할 배열변수 var CT = []; //생성된 차트객체 저장할 배열변수 var PST = []; //각 차트별 주문흐름을 기록할 배열변수 var BID = []; //각 차트별 매수주문아이디를 기록할 배열변수 var BNUM = []; //각 차트별 매수주문번호를 기록할 배열변수 var SID = []; //각 차트별 매도주문 아이디를 기록할 배열변수 var SNUM = []; //각 차트별 매도주문 아이디를 기록할 배열변수 var CID = []; //각 차트별 매도취소주문 아이디를 기록할 배열변수 var TimerID = []; //각 차트별 타이머 아이디 저장할 배열변수 var req,CTcnt; function Main_OnStart() { Main.MessageList("Start"); Main.SetTimer(999, 10000);//60초 타이머(1초가 1000) CTcnt = 0; } //타이머 동작 function Main_OnTimer(nEventID) { var d = new Date(); HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds(); Main.MessageList("Main_OnTimer:",nEventID); //1번 타이머이고 9시 이후 if (nEventID == 999) { if (HHMMSS >= 90000) { Main.ReqPowerSearch("사용자검색조건명"); //Main.KillTimer(999); } } else { Main.KillTimer(nEventID); Account1.SetUnfill(BNUM[nEventID]) //매수주문 취소 if (Account1.Unfill.count > 0 && orderKind == 2) { Account1.OrderCancel(BNUM[nEventID]) BID[nEventID] = null; BNUM[nEventID] = null; } Account1.SetUnfill(SNUM[nEventID]) //매도주문 취소 if (Account1.Unfill.count > 0 && orderKind == 1) { CID[nEventID] = Account1.OrderCancel(SNUM[nEventID]); SID[nEventID] = null; SNUM[nEventID] = null; } } } //종목검색 완료 function Main_OnRcvItemList(aItemList, nCount) { if (nCount > 0 ) { reqList = []; //차트객체가 없다면(기존검색된 종목없음) if (CT.length == 0) { //검색된 모든 종목을 저장해 차트객체 요청 for (var a = 0; a < nCount; a++ ) { reqList.push(aItemList[a]); } } else //차트객체가 1개라도 있으면(검색된 종목있음) { //차트객체가 만들어져 있는 종목은 제외하고 저장해서 차트객체 요청 for (var a = 0; a < nCount; a++ ) { var add = true; for (var b = 0; b < CT.length; b++ ) { if (aItemList[a] == CT[b].GetCode(1)) { add = false; } } if (add == true) { reqList.push(aItemList[a]); } } } if (reqList.length > 0) { Main.MessageList("요청할 종목들:",reqList); req = 0; //5분 주기 1000개봉 var SetChartItem = new ReqChartItem(reqList[req],5,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false); //적용 지표 var SetIndicator = new Array(new IndicatorInfo("#RSI"),new IndicatorInfo("#틱")); //차트객체 요청 Main.ReqChartEx(SetChartItem, null, SetIndicator); } } } //차트객체 생성 function Main_OnRcvChartEx(ChartEx) { //요청한 종목의 차트가 만들어지면 if (ChartEx.GetCode(1) == reqList[req]) { //CT배열에 차트객체 순서대로 저장 0번방부터 만들어진 순서로 저장 CT.push(ChartEx); //각값은 초기값을 null로 해서 0번방버투 만들어진 순서로 저장 PST[CTcnt] = null; BID[CTcnt] = null; BNUM[CTcnt] = null; SID[CTcnt] = null; SNUM[CTcnt] = null; CID[CTcnt] = null; //각 차트의 타이머 아이디는 만들어진 순서 TimerID[CTcnt] = CTcnt; //차트객체 만들어진 순서 1씩 증가 CTcnt = CTcnt+1; //요청종목갯수 1증가 req = req+1; //요청갯수가 리스트갯수보다 작으면 다음종목 요청 if (req < reqList.length) { //5분 주기 1000개봉 var SetChartItem = new ReqChartItem(reqList[req],5,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false); //적용 지표 var SetIndicator = new Array(new IndicatorInfo("#RSI"),new IndicatorInfo("#틱")); //차트객체 요청 Main.ReqChartEx(SetChartItem, null, SetIndicator); } else { Main.MessageList("차트객체 요청완료"); } } } //차트객체들 중에서 봉완성 발생 function Main_OnBarAppended(ChartEx, nData) { if (CT.length > 0 && nData == 1) { for (var i = 0; i < CT.length; i++ ) { //차트객체들 중에서 봉완성이 발생한 차트 찾아서 if (CT[i].GetCode(1) == ChartEx.GetCode(1)) { //잔고셋팅 Account1.SetBalance(CT[i].GetCode(1),0); //보유수량이 없으면 if (Account1.Balance.count == 0) { //2봉전 rsi(14)가 30 이상이고 1봉전 rsi(14)가 30밑이면 if (PST[i] == 0 && CT[i].GetIndicatorData("#RSI",1,1) < 30 && CT[i].GetIndicatorData("#RSI",1,2) > 30) { //매수 BID[i] = Account1.OrderBuy(CT[i].GetCode(1), 10,CT[i].GetClose(1,1)-CT[i].GetIndicatorData("#틱",1,0),0); //해당종목 주문흐름은 첫매수이므로 1 PST[i] = 1; //취소주문 타이머 셋팅 15분(900초)타이머 Main.SetTimer(TimerID, 900*1000); } } else //보유수량이 있다면 { //주문흐름은 1이고(첫매수만한 상태) //2봉전 rsi(14)가 30 이상이고 1봉전 rsi(14)가 30밑이고 //평단가보다 1%이상 하락하고 if (PST[i] == 1 && Account1.Balance.current <= Account1.Balance.avgUnitCost*0.99 && CT[i].GetIndicatorData("#RSI",1,1) < 30 && CT[i].GetIndicatorData("#RSI",1,2) > 30) { //추가매수 BID[i] = Account1.OrderBuy(CT[i].GetCode(1), 10,CT[i].GetClose(1,1)-CT[i].GetIndicatorData("#틱",1,0),0) //해당종목 주문흐름은 두번째 매수이므로 2 PST[i] = 2; //취소주문 타이머 셋팅 15분(900초)타이머 Main.SetTimer(TimerID, 900*1000); } //RSI가 70보다 크면 전량 매도 if (PST[i] >= 1 && CT[i].GetIndicatorData("#RSI",1,1) > 70) { //전량 매도주문 SID[i] = Account1.OrderSell(Account1.Balance.code, Account1.Balance.count,CT[i].GetClose(1,1),0); //취소주문 타이머 셋팅 10분(900초)타이머 Main.SetTimer(TimerID, 600*1000); } } } } } } //주문응답 수신되면 function Main_OnOrderResponse(OrderResponse) { for (var i = 0; i < BID.length; i++ ) { //매수주문에 대한 응답이면 if (OrderResponse.orderID == BID[i]) { //동일 방번호의 매수주문번호 적는 배열에 저장 BNUM[i] = OrderResponse.orderNum; } } for (var i = 0; i < SID.length; i++ ) { //매도주문에 대한 응답이면 if (OrderResponse.orderID == SID[i]) { //동일 방번호의 매도주문번호 적는 배열에 저장 SNUM[i] = OrderResponse.orderNum; } } for (var i = 0; i < CID.length; i++ ) { //매도주문 취소에 대한 응답이면 if (OrderResponse.orderID == CID[i]) { CID[nEventID] = null; //잔고셋팅하고 Account1.SetBalance(OrderResponse.code,0); //전량 시장가 매도 if (Account1.Balance.count > 0) { Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0, 1); } } } } 즐거운 명절되세요