커뮤니티

예스스팟 초보자의 수정요청

프로필 이미지
ksks
2025-09-21 11:06:30.0
72
글번호 226398
답변완료
아래 수식을 - 매수금 10만원 매수---> 종가 천원이상 5만원 이하종목에 한해서 1주만 시장가로 매수로 변경 - 손절은 매수가의 -10%로 변경 - 익절은 매수가의 20%로 변경 - 09시~10시까지만 작동(매수,손절,익절) - 10시기준 자동매도(손절/익절)되지 않은 종목은 보유(수동매도 가능 ?) - 예스스팟에 잔존종목(익절/손절이나 수동매도 후 남은 종목수)은 10개까지로 제한하여 부족한 종목 수만큼만 매수. 등의 조건들, 기타 합리적인 사항으로 추가할만한 것이 있다면 그를 반영한 수식으로 수정 부탁드립니다. ========================================================================== var timer5 = 2; // 2초 var 매수금 = 100000; var 손절 = 0.9; var 익절 = 1.2; var OrderList = []; var MKList = []; var req; var 종목제한수 = 10; function Main_OnStart() { // 1번 타이머, 2초 Main.SetTimer(1, timer5 * 1000); // 오늘 매수한 종목 관리 배열 초기화 MKList = []; } function Main_OnTimer(nEventID) { var d = new Date(); var HHMMSS = d.getHours() * 10000 + d.getMinutes() * 100 + d.getSeconds(); if (nEventID == 1 && HHMMSS >= 090000 && HHMMSS < 100000) { // 종목검색 수행 Main.ReqPowerSearch("변동성 돌파전략"); } else if (nEventID == 1 && HHMMSS >= 100000) { // 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) { 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 >= 100000) { 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)); 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 { // 손절/익절 체크를 위한 타이머 시작 (10초마다 확인) Main.SetTimer(3, 10000); 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 * 손절) { 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 * 익절) { 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; }
답변 3
프로필 이미지

예스스탁 예스스탁 답변

2025-09-26 16:35:37.0

안녕하세요 예스스탁입니다. 1 종가 천원이상 5만원 이하종목 위 내용은 종목검색식에 조건으로 추가하셔야 합니다. C >= 1000 and C <= 50000 아래 수식에 수량만 1주로 변경해 드립니다. 2 올리신 내용이 모두 올리신 수식에 반영되어 있습니다. 10시에 익절,손절되지 않은 종목은 모두 시장가 청산되게 되어 있는데 청산하지 않는다면 아래 내용을 삭제하시면 됩니다. // 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 + " 시간 종료로 매도"); } 이후 수동매도 여부는 사용자분 판단에 따라 일반주문창으로 매도 주문하시면 됩니다. 3 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 >= 100000) { // 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 >= 100000) { 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)); if (quantity > 0) { // 계좌에 없는 경우에만 매수 Account1.OrderBuy(MarketData.code, 매수수량, 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 님이 쓴 글입니다. > 제목 : 예스스팟 초보자의 수정요청 > 아래 수식을 - 매수금 10만원 매수---> 종가 천원이상 5만원 이하종목에 한해서 1주만 시장가로 매수로 변경 - 손절은 매수가의 -10%로 변경 - 익절은 매수가의 20%로 변경 - 09시~10시까지만 작동(매수,손절,익절) - 10시기준 자동매도(손절/익절)되지 않은 종목은 보유(수동매도 가능 ?) - 예스스팟에 잔존종목(익절/손절이나 수동매도 후 남은 종목수)은 10개까지로 제한하여 부족한 종목 수만큼만 매수. 등의 조건들, 기타 합리적인 사항으로 추가할만한 것이 있다면 그를 반영한 수식으로 수정 부탁드립니다. ========================================================================== var timer5 = 2; // 2초 var 매수금 = 100000; var 손절 = 0.9; var 익절 = 1.2; var OrderList = []; var MKList = []; var req; var 종목제한수 = 10; function Main_OnStart() { // 1번 타이머, 2초 Main.SetTimer(1, timer5 * 1000); // 오늘 매수한 종목 관리 배열 초기화 MKList = []; } function Main_OnTimer(nEventID) { var d = new Date(); var HHMMSS = d.getHours() * 10000 + d.getMinutes() * 100 + d.getSeconds(); if (nEventID == 1 && HHMMSS >= 090000 && HHMMSS < 100000) { // 종목검색 수행 Main.ReqPowerSearch("변동성 돌파전략"); } else if (nEventID == 1 && HHMMSS >= 100000) { // 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) { 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 >= 100000) { 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)); 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 { // 손절/익절 체크를 위한 타이머 시작 (10초마다 확인) Main.SetTimer(3, 10000); 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 * 손절) { 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 * 익절) { 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

2025-09-30 13:49:34.0

아래와 같이 수정하여 6131화면에 정상적으로 띄웠는데 거래가 안됩니다. (3202 파워종목검색에는 해당 수식으로 종목이 나오는 걸 확인함) 무엇이 문제인지 수정바랍니다. var timer5 = 2; // 2초 var 매수수량 = 1; var 손절 = -10; var 익절 = 20; var starttime = 90000; var endtime = 153000; 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("1.CVD-HA"); } 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 (MKList.length >= 종목제한수) { Main.MessageList("종목 제한 수 초과로 매수 중지"); Main.SetTimer(1, timer5 * 1000); return; } if (!IsStockInAccount(MarketData.code)) { //var quantity = Math.floor(매수금 / MarketData.Ask(1)); if (quantity > 0) { // 계좌에 없는 경우에만 매수 Account1.OrderBuy(MarketData.code, 매수수량, 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 + " 손절(-10%)로 " + 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 + " 익절(+20%)로 " + 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; } > 예스스탁 님이 쓴 글입니다. > 제목 : Re : 예스스팟 초보자의 수정요청 > 안녕하세요 예스스탁입니다. 1 종가 천원이상 5만원 이하종목 위 내용은 종목검색식에 조건으로 추가하셔야 합니다. C >= 1000 and C <= 50000 아래 수식에 수량만 1주로 변경해 드립니다. 2 올리신 내용이 모두 올리신 수식에 반영되어 있습니다. 10시에 익절,손절되지 않은 종목은 모두 시장가 청산되게 되어 있는데 청산하지 않는다면 아래 내용을 삭제하시면 됩니다. // 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 + " 시간 종료로 매도"); } 이후 수동매도 여부는 사용자분 판단에 따라 일반주문창으로 매도 주문하시면 됩니다. 3 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 >= 100000) { // 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 >= 100000) { 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)); if (quantity > 0) { // 계좌에 없는 경우에만 매수 Account1.OrderBuy(MarketData.code, 매수수량, 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 님이 쓴 글입니다. > 제목 : 예스스팟 초보자의 수정요청 > 아래 수식을 - 매수금 10만원 매수---> 종가 천원이상 5만원 이하종목에 한해서 1주만 시장가로 매수로 변경 - 손절은 매수가의 -10%로 변경 - 익절은 매수가의 20%로 변경 - 09시~10시까지만 작동(매수,손절,익절) - 10시기준 자동매도(손절/익절)되지 않은 종목은 보유(수동매도 가능 ?) - 예스스팟에 잔존종목(익절/손절이나 수동매도 후 남은 종목수)은 10개까지로 제한하여 부족한 종목 수만큼만 매수. 등의 조건들, 기타 합리적인 사항으로 추가할만한 것이 있다면 그를 반영한 수식으로 수정 부탁드립니다. ========================================================================== var timer5 = 2; // 2초 var 매수금 = 100000; var 손절 = 0.9; var 익절 = 1.2; var OrderList = []; var MKList = []; var req; var 종목제한수 = 10; function Main_OnStart() { // 1번 타이머, 2초 Main.SetTimer(1, timer5 * 1000); // 오늘 매수한 종목 관리 배열 초기화 MKList = []; } function Main_OnTimer(nEventID) { var d = new Date(); var HHMMSS = d.getHours() * 10000 + d.getMinutes() * 100 + d.getSeconds(); if (nEventID == 1 && HHMMSS >= 090000 && HHMMSS < 100000) { // 종목검색 수행 Main.ReqPowerSearch("변동성 돌파전략"); } else if (nEventID == 1 && HHMMSS >= 100000) { // 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) { 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 >= 100000) { 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)); 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 { // 손절/익절 체크를 위한 타이머 시작 (10초마다 확인) Main.SetTimer(3, 10000); 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 * 손절) { 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 * 익절) { 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; }
프로필 이미지

예스스탁 예스스탁 답변

2025-10-02 17:24:20.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 님이 쓴 글입니다. > 제목 : Re : Re : 예스스팟 초보자의 수정요청 > 아래와 같이 수정하여 6131화면에 정상적으로 띄웠는데 거래가 안됩니다. (3202 파워종목검색에는 해당 수식으로 종목이 나오는 걸 확인함) 무엇이 문제인지 수정바랍니다. var timer5 = 2; // 2초 var 매수수량 = 1; var 손절 = -10; var 익절 = 20; var starttime = 90000; var endtime = 153000; 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("1.CVD-HA"); } 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 (MKList.length >= 종목제한수) { Main.MessageList("종목 제한 수 초과로 매수 중지"); Main.SetTimer(1, timer5 * 1000); return; } if (!IsStockInAccount(MarketData.code)) { //var quantity = Math.floor(매수금 / MarketData.Ask(1)); if (quantity > 0) { // 계좌에 없는 경우에만 매수 Account1.OrderBuy(MarketData.code, 매수수량, 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 + " 손절(-10%)로 " + 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 + " 익절(+20%)로 " + 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; } > 예스스탁 님이 쓴 글입니다. > 제목 : Re : 예스스팟 초보자의 수정요청 > 안녕하세요 예스스탁입니다. 1 종가 천원이상 5만원 이하종목 위 내용은 종목검색식에 조건으로 추가하셔야 합니다. C >= 1000 and C <= 50000 아래 수식에 수량만 1주로 변경해 드립니다. 2 올리신 내용이 모두 올리신 수식에 반영되어 있습니다. 10시에 익절,손절되지 않은 종목은 모두 시장가 청산되게 되어 있는데 청산하지 않는다면 아래 내용을 삭제하시면 됩니다. // 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 + " 시간 종료로 매도"); } 이후 수동매도 여부는 사용자분 판단에 따라 일반주문창으로 매도 주문하시면 됩니다. 3 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 >= 100000) { // 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 >= 100000) { 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)); if (quantity > 0) { // 계좌에 없는 경우에만 매수 Account1.OrderBuy(MarketData.code, 매수수량, 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 님이 쓴 글입니다. > 제목 : 예스스팟 초보자의 수정요청 > 아래 수식을 - 매수금 10만원 매수---> 종가 천원이상 5만원 이하종목에 한해서 1주만 시장가로 매수로 변경 - 손절은 매수가의 -10%로 변경 - 익절은 매수가의 20%로 변경 - 09시~10시까지만 작동(매수,손절,익절) - 10시기준 자동매도(손절/익절)되지 않은 종목은 보유(수동매도 가능 ?) - 예스스팟에 잔존종목(익절/손절이나 수동매도 후 남은 종목수)은 10개까지로 제한하여 부족한 종목 수만큼만 매수. 등의 조건들, 기타 합리적인 사항으로 추가할만한 것이 있다면 그를 반영한 수식으로 수정 부탁드립니다. ========================================================================== var timer5 = 2; // 2초 var 매수금 = 100000; var 손절 = 0.9; var 익절 = 1.2; var OrderList = []; var MKList = []; var req; var 종목제한수 = 10; function Main_OnStart() { // 1번 타이머, 2초 Main.SetTimer(1, timer5 * 1000); // 오늘 매수한 종목 관리 배열 초기화 MKList = []; } function Main_OnTimer(nEventID) { var d = new Date(); var HHMMSS = d.getHours() * 10000 + d.getMinutes() * 100 + d.getSeconds(); if (nEventID == 1 && HHMMSS >= 090000 && HHMMSS < 100000) { // 종목검색 수행 Main.ReqPowerSearch("변동성 돌파전략"); } else if (nEventID == 1 && HHMMSS >= 100000) { // 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) { 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 >= 100000) { 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)); 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 { // 손절/익절 체크를 위한 타이머 시작 (10초마다 확인) Main.SetTimer(3, 10000); 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 * 손절) { 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 * 익절) { 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; }