커뮤니티

수정문의

프로필 이미지
ksks
2025-11-10 09:37:21
120
글번호 227800

아래 수식 중   당일 전량매도조건 부분을 2봉전 RSI(20)>60, 1봉전 RSI(20)<59.9, 0봉전 RSI(20)<59.9일때에만  매도하는 조건으로 수정 가능한지 문의드립니다. (15시15분에 전량매도 삭제)  또, 계좌잔고 수익이 +-5%일때 전량매도조건을 삭제하고 싶은데요.
그리고, 단봉(5분봉)으로 자동매매 실험하여(1주 매수매도) 장종료 후 5분봉차트에서 확인해보니 조건에 맞는 종목이 많이 매수가 안되는 현상이 있는데 이는 왜그런지요. 또 이를 피하려면 어떻게 해야 하나요?
 var timer5 = 5; //5초 var 매수금 = 100000; var 손절  = 0.95; var 익절  = 1.10; var OrderList = []; var MKList = []; var req; function Main_OnStart() {    //1번 타이머, 5초       Main.SetTimer(1, timer5*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 >= 90000 && HHMMSS < 151500)       {             //종목검색 수행             Main.ReqPowerSearch("ZLMA+RSI-5분봉")             }     if (nEventID == 1)       {             //계좌보유종수             var num = Account1.GetTheNumberOfBalances();                          //9시~15시 15분  사이             if (HHMMSS >= 90000 && HHMMSS < 151500)             {                   //보유종목이 1개 이상                   if (num >= 1)                   {                         //계좌평가금액이 스팟시작시 평가금액대비 5% 이상이면 전종목 전량매도                         if (Account1.GetBalanceETCinfo(100) >= V1*1.10)                         {                               //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);                                     }                               }                         }                                                       else //아니면 개별종목 5%익절, -5%손절 체크                         {                               //계좌리스트의 순서대로                               for (var i = 0; i < num; i++)                               {                                     //잔고를 셋팅                                     Account1.SetBalance(i);                                     //수량이 있고 5%수익이거나 5% 손실이면 시장가 매도                                     if (Account1.Balance.count > 0 &&                                            (Account1.Balance.current >= Account1.Balance.avgUnitCost*익절 ||                                                 Account1.Balance.current <= Account1.Balance.avgUnitCost*손절))                                     {                                           Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1);                                     }                               }                         }                   }             }             //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);                         }                   }             }       }       if (nEventID == 2)       {             Main.ReqMarketData(OrderList[req]);       } } function Main_OnRcvItemList(aItemList, nCount) {       Main.KillTimer(1);       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]);                               }                   }             }       }                    if (OrderList.length == 0)       {             Main.SetTimer(1, timer5*1000);             }       else       {             req = 0;             Main.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(매수금/MarketData.Ask(2)),0,1);   // Account1.OrderBuy(MarketData.code,Math.floor(매수금/MarketData.Ask(2)),MarketData.Ask(2),0);         //지정가로 주문하고자 하시면 주문함수 내용을 위와 같이 변경하시면 됩니다.                       Main.MessageList(MarketData.code + " 주식을 매수합니다.");       } else {          Main.MessageList( MarketData.code + " 주식은 이미 계좌에 있으므로 매수하지 않습니다.");       }                 req = req+1;                   if (req < OrderList.length)                         {                   var aa = Main.ReqMarketData(OrderList[req]);                   if (aa == -1)                   {                         Main.SetTimer(2, 15000);                         }             }                         else             {                   Main.SetTimer(1, timer5*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
프로필 이미지

예스스탁 예스스탁 답변

2025-11-19 16:53:17

안녕하세요 예스스탁입니다. 1 아래 내용 참고하시기 바랍니다. 현재 종목검색후 검색된 종목의 종목객체만 생성하는데 종목객체와 함께 차트객체도 생성해서 지표값 확인해서 매도하게 하시면 됩니다. 차트객체는 생성시 종목코드와 주기, 지표나 시스템을 적용시 이름을 지정해 설정합니다. var ChartSet = new ReqChartItem(OrderList[req],5,CHART_PERIOD_MINUTE,5000,CHART_REQCOUNT_BAR,false,false); var indSet = new Array(new IndicatorInfo("RSI20")); 차트객체의 주기는 5분봉 5000개로 설정했습니다. 수식 내용 보시고 변경하시면 됩니다. 기본제공되는 RSI는 식변형이 있을수 있으므로 스팟에서 사용하는 지표는 별도로 만들어서 사용하시는게 안전합니다 아래 내용을 RSI20이라는 이름의 지표로 작성먼저 하신후에 스팟식을 수행하셔야 합니다. 지표식명 : RSI20 Plot1(RSI(20));


2
종목검색은 지정한 타이머가 동작하면 해당시점 기준으로 종목을 검색합니다.
종목검색창에서 검색버튼을 클릭하는 것과 같습니다. 봉완성기준으로 검색이 되는 부분이 아닙니다. 분봉에서 실시간 현재기준이 아닌 최근 완성기준으로 검색을 하고자 하시면 종목검색식을 전봉기준으로 조건만족한 것을 찾게 작성하셔야 합니다. 3 var timer5 = 5; //5초 var 매수금 = 100000; var 손절 = 0.95; var 익절 = 1.10; var OrderList = []; var MKList = []; var CHList = []; var OD = []; var req; function Main_OnStart() { //1번 타이머, 5초 Main.SetTimer(1, timer5 * 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 >= 90000 && HHMMSS < 151500) { // 종목검색 수행 Main.ReqPowerSearch("ZLMA+RSI-5분봉") } if (nEventID == 1) { // 계좌보유종수 var num = Account1.GetTheNumberOfBalances(); // 9시~15시 15분 사이 if (HHMMSS >= 90000 && HHMMSS < 151500) { // 보유종목이 1개 이상 if (num >= 1) { // 계좌평가금액이 스팟시작시 평가금액대비 5% 이상이면 전종목 전량매도 if (Account1.GetBalanceETCinfo(100) >= V1 * 1.10) { // 1번 타이머 종료 Main.KillTimer(1); // 계좌리스트의 순서대로 for (var i = 0; i < num; i++) { // 잔고를 셋팅 Account1.SetBalance(i); if (Account1.Balance.count > 0) { Account1.OrderSell(Account1.Balance.code, Account1.Balance.count, 0, 1); } } } } } } if (nEventID == 2) { Main.ReqMarketData(OrderList[req]); } } function Main_OnRcvItemList(aItemList, nCount) { Main.KillTimer(1); 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]); } } } } if (OrderList.length == 0) { Main.SetTimer(1, timer5 * 1000); } else { req = 0; var ChartSet = new ReqChartItem(OrderList[req],5,CHART_PERIOD_MINUTE,5000,CHART_REQCOUNT_BAR,false,false); var indSet = new Array(new IndicatorInfo("RSI20")); Main.MessageList(req,"차트객체요청 : ",OrderList[req]); Main.ReqChartEx(ChartSet,null,indSet); } } function Main_OnRcvChartEx(ChartEx) { if (ChartEx.GetCode(1) == OrderList[req]) { CHList.push(ChartEx); var aa = Main.ReqMarketData(OrderList[req]); if (aa == -1) { Main.SetTimer(2, 15000); } } } function Main_OnRcvMarketData(MarketData) { if (MarketData.code == OrderList[req]) { MKList.push(MarketData); OD.push(1); // 계좌에 같은 종목이 있는지 확인 if (!IsStockInAccount(MarketData.code)) { // 계좌에 없는 경우에만 매수 Account1.OrderBuy(MarketData.code, 1, 0, 1); // Account1.OrderBuy(MarketData.code, Math.floor(매수금 / MarketData.Ask(2)), 0, 1); // Account1.OrderBuy(MarketData.code, Math.floor(매수금 / MarketData.Ask(2)), MarketData.Ask(2), 0); // 지정가로 주문하고자 하시면 주문함수 내용을 위와 같이 변경하시면 됩니다. Main.MessageList(MarketData.code + " 주식을 매수합니다."); } else { Main.MessageList(MarketData.code + " 주식은 이미 계좌에 있으므로 매수하지 않습니다."); } req = req + 1; if (req < OrderList.length) { var ChartSet = new ReqChartItem(OrderList[req],5,CHART_PERIOD_MINUTE,5000,CHART_REQCOUNT_BAR,false,false); var indSet = new Array(new IndicatorInfo("RSI20")); Main.MessageList(req,"차트객체요청 : ",OrderList[req]); Main.ReqChartEx(ChartSet,null,indSet); } else { Main.SetTimer(1, timer5 * 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 반환 } //차트 봉완성(다음봉시가수신) function Main_OnBarAppended(ChartEx, nData) { //2봉전 RSI(20)>60, 1봉전 RSI(20)<59.9, 0봉전 RSI(20)<59.9 if (ChartEx.GetIndicatorData("RSI20",1,3)>60 && //전전봉 ChartEx.GetIndicatorData("RSI20",1,2)<59.9 && //전봉 ChartEx.GetIndicatorData("RSI20",1,1)<59.9) //최근완성봉 { for (var i = 0; i < MKList.length; i++) { if (ChartEx.GetCode(1) == MKList[i].code && OD[i] == 1) { OD[i] = -1; // 잔고를 셋팅 Account1.SetBalance(ChartEx.GetCode(1)); if (Account1.Balance.count > 0) { Account1.OrderSell(Account1.Balance.code, Account1.Balance.count, 0, 1); } } } } } 즐거운 하루되세요

프로필 이미지

ksks

2025-11-20 12:42:39

답변 감사드립니다.

아래 사항을 확인하고 실행코자 하오니 한번만 더 봐주세요.
===============================================================================
1.  당일 +-10% 익절/손절조건을 ---> 2봉전 RSI(20)>60, 1봉전 RSI(20)<59.9, 0봉전 RSI(20)<59.9일때에만  매도하는 조건으로 변경.
2. 15시15분에 전량매도 ---> 삭제
3. 계좌잔고 수익이 +-5%일때 전량매도조건 ---> 삭제