예스스탁
예스스탁 답변
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;
}