커뮤니티

수정 부탁드립니다.

프로필 이미지
주식남
2024-10-14 11:08:50.0
443
글번호 226139
답변완료
안녕하세요? 파워검색 종목이 발생하면 자동매수하고, 3분봉 기준 매수한 시점의 동일한 봉이 완성되는 시점에서 매도세가 매수세보다 크거나 음봉일 경우, 3분봉 완성 시점에서 전량 매도하는 로직입니다. 매수시점의 봉의 정보를 저장하는 부분부터 에러가 발생하는 것 같습니다. 아래 함수들을 참고해서 수정해 주시면 감사하겠습니다. 다른 로직은 표기하지 않고 관련 로직만 표기하였습니다. Main_OnRcvMarketData(MarketData): 매수시점의 봉의 정보를 저장하는 부분포함 isCandleClose(stockCode): 봉 마감 여부를 확인하는 함수 checkSellCondition(stockCode): 매수/매도 거래량 비교 및 매수 시점의 봉과 동일한 봉인지 확인하는 함수 getCandleTime(): 봉의 시작 시간을 반환하는 함수 var timer = 3; // 3초 var 매수금 = 500000; var 종목손절 = 0.97; // 종목 손절 % 조정 var 계좌익절 = 1.07; // 계좌 익절 % 조정 (7% 익절) var OrderList = []; var MKList = []; var req; var 매수시점봉 = {}; // 매수 시점의 봉 정보를 저장할 객체 var BuyVolume = 0; var SellVolume = 0; function Main_OnStart() { // 1번 타이머 Main.SetTimer(1, timer * 1000); // 오늘 매수한 종목 관리 배열 초기화 MKList = []; // 스팟 시작시 잔고 평가금액 V1 = Account1.GetBalanceETCinfo(100); Main.MessageList("Start"); } function Main_OnTimer(nEventID) { var d = new Date(); var YYYYMMDD = d.getFullYear() * 10000 + (d.getMonth() + 1) * 100 + d.getDate(); var HHMMSS = d.getHours() * 10000 + d.getMinutes() * 100 + d.getSeconds(); if (nEventID == 1 && HHMMSS >= 90000 && HHMMSS < 151500) // 9:00 ~ 15:15 { // 종목 검색 수정 Main.ReqPowerSearch("(분) 시가배팅_가격보조지표_통합"); // 파워 종목 검색 Main.MessageList("ReqPowerSearch"); } if (nEventID == 1) { // 계좌 보유 종목 수 var num = Account1.GetTheNumberOfBalances(); // 9:00 ~ 15:15 사이 if (HHMMSS >= 90000 && HHMMSS < 151500) { // 보유 종목이 1개 이상일 때 if (num >= 1) { for (var i = 0; i < num; i++) { // 잔고 설정 Account1.SetBalance(i); var stockCode = Account1.Balance.code; var currentPrice = Account1.Balance.current; var avgCost = Account1.Balance.avgUnitCost; var ratio = currentPrice / avgCost; // 매수 시점의 봉이 끝나는 시점에서만 매도 조건 확인 if (isCandleClose(stockCode) && checkSellCondition(stockCode)) { Account1.OrderSell(Account1.Balance.code, Account1.Balance.count, 0, 1); Main.MessageList("조건 충족, 전량 매도"); } } } } } if (nEventID == 2) { Main.ReqMarketData(OrderList[req]); } } function Main_OnRcvMarketData(MarketData) { if(MarketData.code==OrderList[req]) { MKList.push(MarketData); //계좌에 같은 종목이 있는지 확인 if(!IsStockInAccount(MarketData.code)) { //계좌에 없는 경우에만 매수 Account1.OrderBuy(MarketData.code,Math.floor(매수금/MarketData.Ask(1)),0,1); //매수금 시장가 주문 // 매수 시점의 봉 정보를 저장 매수시점봉[MarketData.code] = { time: getCandleTime(), // 매수 시점 봉의 시간 high: MarketData.high, low: MarketData.low, close: MarketData.current }; Main.MessageList(MarketData.code + "주식을 매수합니다"); } else { Main.MessageList(MarketData.code + "검색종목은 이미 계좌에 있으므로 매수하지 않습니다."); } req=req+1; if(req BuyVolume || MarketData.current < MarketData.open) { Main.MessageList("매도 조건 충족: 매도 거래량이 많거나 음봉"); return true; } return false; } // 봉의 시작 시간을 반환하는 함수 (3분봉 기준) function getCandleTime() { var now = new Date(); return now.getHours() * 100 + Math.floor(now.getMinutes() / 3) * 3; }
답변 1
프로필 이미지

예스스탁 예스스탁 답변

2024-11-22 15:01:37.0

안녕하세요 예스스탁입니다. 1 function checkSellCondition(stockCode) { //var balance = Account1.Balance; var 매수봉 = 매수시점봉[stockCode]; // 매수한 봉과 현재 봉이 동일해야 조건 체크 if (getCandleTime() !== 매수봉.time) { return false; // 매수한 봉과 현재 봉이 다르면 매도 조건 확인하지 않음 } // 거래량 계산 BuyVolume = (MarketData.high === MarketData.low) ? 0 : MarketData.volume * (MarketData.current - MarketData.low) / (MarketData.high - MarketData.low); SellVolume = (MarketData.high === MarketData.low) ? 0 : MarketData.volume * (MarketData.high - MarketData.current) / (MarketData.high - MarketData.low); // 조건: 매도 거래량이 매수 거래량보다 크거나, 봉이 음봉일 경우 if (SellVolume > BuyVolume || MarketData.current < MarketData.open) { Main.MessageList("매도 조건 충족: 매도 거래량이 많거나 음봉"); return true; } return false; } 위 함수에 MarketData과 같이 종목객체가 사용되었는데 객체명이 불명확합니다. 수식에서 종목객체는 MKList에 저장되는데 함수에서는 MarketData로만 지정되어 있습니다. stockCode로 종목코드를 받으므로 종목객체인 MKList에서 지정한 종목코드의 객체를 찾아 사용하게 변경해 드립니다. function checkSellCondition(stockCode) { //var balance = Account1.Balance; var 매수봉 = 매수시점봉[stockCode].time; // 매수한 봉과 현재 봉이 동일해야 조건 체크 if (getCandleTime() !== 매수봉.time) { return false; // 매수한 봉과 현재 봉이 다르면 매도 조건 확인하지 않음 } BuyVolume = 0; SellVolume = 0; for (var i = 0; i < MKList.length; i++) { if (MKList[i].code == stockCode) { // 거래량 계산 BuyVolume = (MKList[i].high == MKList[i].low) ? 0 : MKList[i].volume * (MKList[i].current - MKList[i].low) / (MKList[i].high - MKList[i].low); SellVolume = (MKList[i].high == MKList[i].low) ? 0 : MKList[i].volume * (MKList[i].high - MKList[i].current) / (MKList[i].high - MKList[i].low); } } // 조건: 매도 거래량이 매수 거래량보다 크거나, 봉이 음봉일 경우 if (SellVolume > BuyVolume || MarketData.current < MarketData.open) { Main.MessageList("매도 조건 충족: 매도 거래량이 많거나 음봉"); return true; } return false; } 2 if (nEventID == 2) { Main.ReqMarketData(OrderList[req]); } 종목객체 생성제한에 걸리면 15초 뒤에 다시 종목객체를 요청하게 되어 있는데 재요청시 2번 타이머를 종료되게 하셔야 합니다 if (nEventID == 2) { Main.KillTimer(2); Main.ReqMarketData(OrderList[req]); } 즐거운 하루되세요 > 주식남 님이 쓴 글입니다. > 제목 : 수정 부탁드립니다. > 안녕하세요? 파워검색 종목이 발생하면 자동매수하고, 3분봉 기준 매수한 시점의 동일한 봉이 완성되는 시점에서 매도세가 매수세보다 크거나 음봉일 경우, 3분봉 완성 시점에서 전량 매도하는 로직입니다. 매수시점의 봉의 정보를 저장하는 부분부터 에러가 발생하는 것 같습니다. 아래 함수들을 참고해서 수정해 주시면 감사하겠습니다. 다른 로직은 표기하지 않고 관련 로직만 표기하였습니다. Main_OnRcvMarketData(MarketData): 매수시점의 봉의 정보를 저장하는 부분포함 isCandleClose(stockCode): 봉 마감 여부를 확인하는 함수 checkSellCondition(stockCode): 매수/매도 거래량 비교 및 매수 시점의 봉과 동일한 봉인지 확인하는 함수 getCandleTime(): 봉의 시작 시간을 반환하는 함수 var timer = 3; // 3초 var 매수금 = 500000; var 종목손절 = 0.97; // 종목 손절 % 조정 var 계좌익절 = 1.07; // 계좌 익절 % 조정 (7% 익절) var OrderList = []; var MKList = []; var req; var 매수시점봉 = {}; // 매수 시점의 봉 정보를 저장할 객체 var BuyVolume = 0; var SellVolume = 0; function Main_OnStart() { // 1번 타이머 Main.SetTimer(1, timer * 1000); // 오늘 매수한 종목 관리 배열 초기화 MKList = []; // 스팟 시작시 잔고 평가금액 V1 = Account1.GetBalanceETCinfo(100); Main.MessageList("Start"); } function Main_OnTimer(nEventID) { var d = new Date(); var YYYYMMDD = d.getFullYear() * 10000 + (d.getMonth() + 1) * 100 + d.getDate(); var HHMMSS = d.getHours() * 10000 + d.getMinutes() * 100 + d.getSeconds(); if (nEventID == 1 && HHMMSS >= 90000 && HHMMSS < 151500) // 9:00 ~ 15:15 { // 종목 검색 수정 Main.ReqPowerSearch("(분) 시가배팅_가격보조지표_통합"); // 파워 종목 검색 Main.MessageList("ReqPowerSearch"); } if (nEventID == 1) { // 계좌 보유 종목 수 var num = Account1.GetTheNumberOfBalances(); // 9:00 ~ 15:15 사이 if (HHMMSS >= 90000 && HHMMSS < 151500) { // 보유 종목이 1개 이상일 때 if (num >= 1) { for (var i = 0; i < num; i++) { // 잔고 설정 Account1.SetBalance(i); var stockCode = Account1.Balance.code; var currentPrice = Account1.Balance.current; var avgCost = Account1.Balance.avgUnitCost; var ratio = currentPrice / avgCost; // 매수 시점의 봉이 끝나는 시점에서만 매도 조건 확인 if (isCandleClose(stockCode) && checkSellCondition(stockCode)) { Account1.OrderSell(Account1.Balance.code, Account1.Balance.count, 0, 1); Main.MessageList("조건 충족, 전량 매도"); } } } } } if (nEventID == 2) { Main.ReqMarketData(OrderList[req]); } } function Main_OnRcvMarketData(MarketData) { if(MarketData.code==OrderList[req]) { MKList.push(MarketData); //계좌에 같은 종목이 있는지 확인 if(!IsStockInAccount(MarketData.code)) { //계좌에 없는 경우에만 매수 Account1.OrderBuy(MarketData.code,Math.floor(매수금/MarketData.Ask(1)),0,1); //매수금 시장가 주문 // 매수 시점의 봉 정보를 저장 매수시점봉[MarketData.code] = { time: getCandleTime(), // 매수 시점 봉의 시간 high: MarketData.high, low: MarketData.low, close: MarketData.current }; Main.MessageList(MarketData.code + "주식을 매수합니다"); } else { Main.MessageList(MarketData.code + "검색종목은 이미 계좌에 있으므로 매수하지 않습니다."); } req=req+1; if(req BuyVolume || MarketData.current < MarketData.open) { Main.MessageList("매도 조건 충족: 매도 거래량이 많거나 음봉"); return true; } return false; } // 봉의 시작 시간을 반환하는 함수 (3분봉 기준) function getCandleTime() { var now = new Date(); return now.getHours() * 100 + Math.floor(now.getMinutes() / 3) * 3; }