커뮤니티

2759

프로필 이미지
ksks
2025-10-01 11:17:55.0
67
글번호 226415
답변완료
2759번좀 봐주세요.
답변 3
프로필 이미지

예스스탁 예스스탁 답변

2025-10-02 17:26:23.0

안녕하세요 예스스탁입니다. 수량변수에 문제가 있어 수정해 드립니다. 기존에 올리신 수식을 동작해 보면 function CheckStopLossTakeProfit() 만들어 사용하는 위 함수에서 에러가 있습니다. 해당 부분은 직접 작성하신 부분이고 내용파악이 안되 저희가 수정해 드리기 어렵습니다. 기존수식에 시작시간, 종료시간 조건 추가, 매수시 1주 매수로 변경, 종로시간(10시)에 보유종목 시장가로 청산만 추가된 식입니다. var timer5 = 2; // 2초 var 매수수량 = 1; var 손절 = -10; var 익절 = 20; var starttime = 90000; var endtime = 100000; var OrderList = []; var MKList = []; var req; var 종목제한수 = 10; function Main_OnStart() { // 1번 타이머, 2초 Main.SetTimer(1, timer5 * 1000); // 오늘 매수한 종목 관리 배열 초기화 MKList = []; // 손절/익절 체크를 위한 타이머 시작 (10초마다 확인) Main.SetTimer(3, 10000); } function Main_OnTimer(nEventID) { var d = new Date(); var HHMMSS = d.getHours() * 10000 + d.getMinutes() * 100 + d.getSeconds(); if (nEventID == 1 && HHMMSS >= starttime && HHMMSS < endtime) { // 종목검색 수행 Main.ReqPowerSearch("변동성 돌파전략"); } else if (nEventID == 1 && HHMMSS >= endtime) { // 10:00 이후 모든 보유 종목 매도 for (var i = 0; i < MKList.length; i++) { Account1.OrderSell(MKList[i].code, MKList[i].quantity, 0, 1); Main.MessageList(MKList[i].code + " 시간 종료로 매도"); } MKList = []; Main.KillTimer(1); // 타이머 종료 } if (nEventID == 2) { Main.ReqMarketData(OrderList[req]); } // 손절/익절 확인 (타이머 3번으로 주기적 실행) if (nEventID == 3) { if (MKList.length > 0) { CheckStopLossTakeProfit(); } } } function Main_OnRcvItemList(aItemList, nCount) { Main.KillTimer(1); OrderList = []; if (nCount >= 1) { if (MKList.length == 0) { OrderList = aItemList.slice(0, Math.min(nCount, 종목제한수)); } 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 && !IsStockInAccount(aItemList[a]) && OrderList.length < 종목제한수 - MKList.length) { OrderList.push(aItemList[a]); } } } Main.MessageList("OrderList: " + JSON.stringify(OrderList)); if (OrderList.length == 0) { Main.SetTimer(1, timer5 * 1000); } else { req = 0; Main.ReqMarketData(OrderList[req]); } } } function Main_OnRcvMarketData(MarketData) { var d = new Date(); var HHMMSS = d.getHours() * 10000 + d.getMinutes() * 100 + d.getSeconds(); if (MarketData.code == OrderList[req]) { if (HHMMSS >= endtime) { Main.MessageList("매수 시간(09:00~10:00) 종료로 매수 중지"); Main.SetTimer(1, timer5 * 1000); return; } if (MKList.length >= 종목제한수) { Main.MessageList("종목 제한 수 초과로 매수 중지"); Main.SetTimer(1, timer5 * 1000); return; } if (!IsStockInAccount(MarketData.code)) { //var quantity = Math.floor(매수금 / MarketData.Ask(1)); quantity = 매수수량; if (quantity > 0) { // 계좌에 없는 경우에만 매수 Account1.OrderBuy(MarketData.code, quantity, 0, 1); //Account1.OrderBuy(MarketData.code, 1, 0, 1); // 고정 1주 매수 //Account1.OrderBuy(MarketData.code, Math.floor(매수금 / MarketData.Ask(1)), MarketData.Ask(1), 0); // 지정가 매수 // 지정가로 주문하고자 하시면 주문함수 내용을 위와 같이 변경하시면 됩니다. MKList.push({code: MarketData.code,buyPrice: MarketData.Ask(1),quantity: quantity}); Main.MessageList(MarketData.code + " 주식을 " + quantity + "주 매수, 매수가: " + MarketData.Ask(1)); } else { Main.MessageList(MarketData.code + " 매수 수량 0, 매수 실패"); } } 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 CheckStopLossTakeProfit() { for (var i = 0; i < MKList.length; i++) { var stock = MKList[i]; var marketData = Main.GetMarketData(stock.code); if (!marketData) continue; var currentPrice = marketData.currentPrice; if (currentPrice <= stock.buyPrice *(1+손절/100)) { Account1.OrderSell(stock.code, stock.quantity, 0, 1); Main.MessageList(stock.code + " 손절(-5%)로 " + stock.quantity + "주 매도, 현재가: " + currentPrice); MKList.splice(i, 1); i--; } else if (currentPrice >= stock.buyPrice * (1+익절/100)) { Account1.OrderSell(stock.code, stock.quantity, 0, 1); Main.MessageList(stock.code + " 익절(+5%)로 " + stock.quantity + "주 매도, 현재가: " + currentPrice); MKList.splice(i, 1); i--; } } } function IsStockInAccount(stockCode) { var numberOfBalances = Account1.GetTheNumberOfBalances(); for (var i = 0; i < numberOfBalances; i++) { Account1.SetBalance(i); if (stockCode == Account1.Balance.code) { return true; } } return false; } 즐거운 명절 되시기 바랍니다. > ksks 님이 쓴 글입니다. > 제목 : 2759 > 2759번좀 봐주세요.
프로필 이미지

ksks

2025-10-02 21:43:11.0

답변 감사합니다. 이해에 차이가 있어 다시 요청드립니다. 수정요청드린 것은 -1주를 시장가에 -장 시간 내 모두 작동 -스윙거래목적; 손절/익절되지 않은 종목은 시장가매도 않음.(끌고감) 조건입니다. 수량변수문제도 피할 수 있는 수식으로 부탁드립니다. 다시한번 수정요청드립니다. > 예스스탁 님이 쓴 글입니다. > 제목 : Re : 2759 > 안녕하세요 예스스탁입니다. 수량변수에 문제가 있어 수정해 드립니다. 기존에 올리신 수식을 동작해 보면 function CheckStopLossTakeProfit() 만들어 사용하는 위 함수에서 에러가 있습니다. 해당 부분은 직접 작성하신 부분이고 내용파악이 안되 저희가 수정해 드리기 어렵습니다. 기존수식에 시작시간, 종료시간 조건 추가, 매수시 1주 매수로 변경, 종로시간(10시)에 보유종목 시장가로 청산만 추가된 식입니다. var timer5 = 2; // 2초 var 매수수량 = 1; var 손절 = -10; var 익절 = 20; var starttime = 90000; var endtime = 100000; var OrderList = []; var MKList = []; var req; var 종목제한수 = 10; function Main_OnStart() { // 1번 타이머, 2초 Main.SetTimer(1, timer5 * 1000); // 오늘 매수한 종목 관리 배열 초기화 MKList = []; // 손절/익절 체크를 위한 타이머 시작 (10초마다 확인) Main.SetTimer(3, 10000); } function Main_OnTimer(nEventID) { var d = new Date(); var HHMMSS = d.getHours() * 10000 + d.getMinutes() * 100 + d.getSeconds(); if (nEventID == 1 && HHMMSS >= starttime && HHMMSS < endtime) { // 종목검색 수행 Main.ReqPowerSearch("변동성 돌파전략"); } else if (nEventID == 1 && HHMMSS >= endtime) { // 10:00 이후 모든 보유 종목 매도 for (var i = 0; i < MKList.length; i++) { Account1.OrderSell(MKList[i].code, MKList[i].quantity, 0, 1); Main.MessageList(MKList[i].code + " 시간 종료로 매도"); } MKList = []; Main.KillTimer(1); // 타이머 종료 } if (nEventID == 2) { Main.ReqMarketData(OrderList[req]); } // 손절/익절 확인 (타이머 3번으로 주기적 실행) if (nEventID == 3) { if (MKList.length > 0) { CheckStopLossTakeProfit(); } } } function Main_OnRcvItemList(aItemList, nCount) { Main.KillTimer(1); OrderList = []; if (nCount >= 1) { if (MKList.length == 0) { OrderList = aItemList.slice(0, Math.min(nCount, 종목제한수)); } 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 && !IsStockInAccount(aItemList[a]) && OrderList.length < 종목제한수 - MKList.length) { OrderList.push(aItemList[a]); } } } Main.MessageList("OrderList: " + JSON.stringify(OrderList)); if (OrderList.length == 0) { Main.SetTimer(1, timer5 * 1000); } else { req = 0; Main.ReqMarketData(OrderList[req]); } } } function Main_OnRcvMarketData(MarketData) { var d = new Date(); var HHMMSS = d.getHours() * 10000 + d.getMinutes() * 100 + d.getSeconds(); if (MarketData.code == OrderList[req]) { if (HHMMSS >= endtime) { Main.MessageList("매수 시간(09:00~10:00) 종료로 매수 중지"); Main.SetTimer(1, timer5 * 1000); return; } if (MKList.length >= 종목제한수) { Main.MessageList("종목 제한 수 초과로 매수 중지"); Main.SetTimer(1, timer5 * 1000); return; } if (!IsStockInAccount(MarketData.code)) { //var quantity = Math.floor(매수금 / MarketData.Ask(1)); quantity = 매수수량; if (quantity > 0) { // 계좌에 없는 경우에만 매수 Account1.OrderBuy(MarketData.code, quantity, 0, 1); //Account1.OrderBuy(MarketData.code, 1, 0, 1); // 고정 1주 매수 //Account1.OrderBuy(MarketData.code, Math.floor(매수금 / MarketData.Ask(1)), MarketData.Ask(1), 0); // 지정가 매수 // 지정가로 주문하고자 하시면 주문함수 내용을 위와 같이 변경하시면 됩니다. MKList.push({code: MarketData.code,buyPrice: MarketData.Ask(1),quantity: quantity}); Main.MessageList(MarketData.code + " 주식을 " + quantity + "주 매수, 매수가: " + MarketData.Ask(1)); } else { Main.MessageList(MarketData.code + " 매수 수량 0, 매수 실패"); } } 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 CheckStopLossTakeProfit() { for (var i = 0; i < MKList.length; i++) { var stock = MKList[i]; var marketData = Main.GetMarketData(stock.code); if (!marketData) continue; var currentPrice = marketData.currentPrice; if (currentPrice <= stock.buyPrice *(1+손절/100)) { Account1.OrderSell(stock.code, stock.quantity, 0, 1); Main.MessageList(stock.code + " 손절(-5%)로 " + stock.quantity + "주 매도, 현재가: " + currentPrice); MKList.splice(i, 1); i--; } else if (currentPrice >= stock.buyPrice * (1+익절/100)) { Account1.OrderSell(stock.code, stock.quantity, 0, 1); Main.MessageList(stock.code + " 익절(+5%)로 " + stock.quantity + "주 매도, 현재가: " + currentPrice); MKList.splice(i, 1); i--; } } } function IsStockInAccount(stockCode) { var numberOfBalances = Account1.GetTheNumberOfBalances(); for (var i = 0; i < numberOfBalances; i++) { Account1.SetBalance(i); if (stockCode == Account1.Balance.code) { return true; } } return false; } 즐거운 명절 되시기 바랍니다. > ksks 님이 쓴 글입니다. > 제목 : 2759 > 2759번좀 봐주세요.
프로필 이미지

예스스탁 예스스탁 답변

2025-10-17 14:39:46.0

안녕하세요
예스스탁입니다.
1주 시장가 매수는 기존에 해당 내용으로 처리되어 있습니다.

var starttime = 90000; var endtime = 100000;
수식에 보시면 위 시간사이에만 검색돠 매수가 됩니다. 시간은 위 변수값 변경하시면 됩니다.
endtime 시간이후 모든 종목청산하는 내용만 삭제해 드립니다.


var timer5 = 2; // 2초 var 매수수량 = 1; var 손절 = -10; var 익절 = 20; var starttime = 90000; var endtime = 100000; var OrderList = []; var MKList = []; var req; var 종목제한수 = 10; function Main_OnStart() { // 1번 타이머, 2초 Main.SetTimer(1, timer5 * 1000); // 오늘 매수한 종목 관리 배열 초기화 MKList = []; // 손절/익절 체크를 위한 타이머 시작 (10초마다 확인) Main.SetTimer(3, 10000); } function Main_OnTimer(nEventID) { var d = new Date(); var HHMMSS = d.getHours() * 10000 + d.getMinutes() * 100 + d.getSeconds(); if (nEventID == 1 && HHMMSS >= starttime && HHMMSS < endtime) { // 종목검색 수행 Main.ReqPowerSearch("변동성 돌파전략"); } else if (nEventID == 1 && HHMMSS >= endtime) { MKList = []; Main.KillTimer(1); // 타이머 종료 } if (nEventID == 2) { Main.ReqMarketData(OrderList[req]); } // 손절/익절 확인 (타이머 3번으로 주기적 실행) if (nEventID == 3) { if (MKList.length > 0) { CheckStopLossTakeProfit(); } } } function Main_OnRcvItemList(aItemList, nCount) { Main.KillTimer(1); OrderList = []; if (nCount >= 1) { if (MKList.length == 0) { OrderList = aItemList.slice(0, Math.min(nCount, 종목제한수)); } 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 && !IsStockInAccount(aItemList[a]) && OrderList.length < 종목제한수 - MKList.length) { OrderList.push(aItemList[a]); } } } Main.MessageList("OrderList: " + JSON.stringify(OrderList)); if (OrderList.length == 0) { Main.SetTimer(1, timer5 * 1000); } else { req = 0; Main.ReqMarketData(OrderList[req]); } } } function Main_OnRcvMarketData(MarketData) { var d = new Date(); var HHMMSS = d.getHours() * 10000 + d.getMinutes() * 100 + d.getSeconds(); if (MarketData.code == OrderList[req]) { if (HHMMSS >= endtime) { Main.MessageList("매수 시간(09:00~10:00) 종료로 매수 중지"); Main.SetTimer(1, timer5 * 1000); return; } if (MKList.length >= 종목제한수) { Main.MessageList("종목 제한 수 초과로 매수 중지"); Main.SetTimer(1, timer5 * 1000); return; } if (!IsStockInAccount(MarketData.code)) { //var quantity = Math.floor(매수금 / MarketData.Ask(1)); quantity = 매수수량; if (quantity > 0) { // 계좌에 없는 경우에만 매수 Account1.OrderBuy(MarketData.code, quantity, 0, 1); //Account1.OrderBuy(MarketData.code, 1, 0, 1); // 고정 1주 매수 //Account1.OrderBuy(MarketData.code, Math.floor(매수금 / MarketData.Ask(1)), MarketData.Ask(1), 0); // 지정가 매수 // 지정가로 주문하고자 하시면 주문함수 내용을 위와 같이 변경하시면 됩니다. MKList.push({code: MarketData.code,buyPrice: MarketData.Ask(1),quantity: quantity}); Main.MessageList(MarketData.code + " 주식을 " + quantity + "주 매수, 매수가: " + MarketData.Ask(1)); } else { Main.MessageList(MarketData.code + " 매수 수량 0, 매수 실패"); } } 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 CheckStopLossTakeProfit() { for (var i = 0; i < MKList.length; i++) { var stock = MKList[i]; var marketData = Main.GetMarketData(stock.code); if (!marketData) continue; var currentPrice = marketData.currentPrice; if (currentPrice <= stock.buyPrice *(1+손절/100)) { Account1.OrderSell(stock.code, stock.quantity, 0, 1); Main.MessageList(stock.code + " 손절(-5%)로 " + stock.quantity + "주 매도, 현재가: " + currentPrice); MKList.splice(i, 1); i--; } else if (currentPrice >= stock.buyPrice * (1+익절/100)) { Account1.OrderSell(stock.code, stock.quantity, 0, 1); Main.MessageList(stock.code + " 익절(+5%)로 " + stock.quantity + "주 매도, 현재가: " + currentPrice); MKList.splice(i, 1); i--; } } } function IsStockInAccount(stockCode) { var numberOfBalances = Account1.GetTheNumberOfBalances(); for (var i = 0; i < numberOfBalances; i++) { Account1.SetBalance(i); if (stockCode == Account1.Balance.code) { return true; } } return false; }
즐거운 하루되세요