커뮤니티
조건검색 요청 뒤 응답이 없습니다.
var SearchCode = "재미나이"; var TOTAL_LIMIT = 10000000; // 전체 투자 한도 (1,000만 원)
var ORDER_AMOUNT = 1000000; // 1회 매수 금액 (100만 원)
var isSearching = false; // 중복 검색 요청 방지 플래그
var searchItems = []; // 검색된 종목 코드 리스트 저장
var itemDataList = []; // 시세 데이터 수집 배열
function Main_OnStart()
{
// 5초마다 타이머 동작 (자동 매수 감시)
Main.SetTimer(1, 5000);
Main.MessageLog("====================================");
Main.MessageLog("★ 예스스팟 자동매매 시작 (변동성A 최근접 종목 시장가 매수 / 20% 익절)");
Main.MessageLog("====================================");
}
function Main_OnTimer(nEventID)
{
if (nEventID == 1)
{
// 계좌 평가 금액/사용 금액 계산
var currentUsed = GetTotalInvestedAmount();
// 100만 원 이상 매수 여력이 남아있고 검색 중이 아닐 때 조건검색 실행
if ((TOTAL_LIMIT - currentUsed >= ORDER_AMOUNT) && !isSearching)
{
isSearching = true;
searchItems = [];
itemDataList = [];
Main.MessageLog("★ [조건검색 요청] 현재 사용금액: " + currentUsed + "원 / 남은한도: " + (TOTAL_LIMIT - currentUsed) + "원");
Main.ReqPowerSearch(SearchCode);
}
}
// 시세 미수신으로 인한 무한 대기 방지용 타임아웃 (3초)
if (nEventID == 2)
{
Main.KillTimer(2);
ProcessBuyOrder();
}
}
// 파워종목검색 완료 이벤트
function Main_OnPowerSearchFinished(nReturnCode)
{
if (nReturnCode == 1)
{
var itemCount = Main.GetSearchItemCount();
Main.MessageLog("-> 조건검색 완료: 총 " + itemCount + "개 종목 발견");
if (itemCount > 0)
{
for (var i = 0; i < itemCount; i++)
{
var itemCode = Main.GetSearchItemCode(i);
// 이미 계좌에 보유 중인 종목은 제외
Account1.SetBalanceItem(itemCode, 0);
if (Account1.Balance.count == 0)
{
searchItems.push(itemCode);
Main.ReqMarketData(itemCode);
}
}
// 3초 내에 시세 미수신 시 강제 처리 타임아웃 실행
Main.SetTimer(2, 3000);
}
else
{
isSearching = false;
}
}
else
{
Main.MessageLog("-> [오류] 조건검색 실패 (검색식 명칭 확인 필요)");
isSearching = false;
}
}
// 수신된 시세 데이터 수집 및 매수 조건 처리
function Main_OnRcvMarketData(MarketData)
{
// ----------------------------------------------------
// 1. 조건검색 수신 데이터 처리 및 매수 로직
// ----------------------------------------------------
var isSearchTarget = false;
for (var i = 0; i < searchItems.length; i++)
{
if (searchItems[i] == MarketData.code)
{
isSearchTarget = true;
break;
}
}
if (isSearchTarget)
{
// 중복 추가 방지
var isExist = false;
for (var j = 0; j < itemDataList.length; j++)
{
if (itemDataList[j].code == MarketData.code)
{
isExist = true;
break;
}
}
if (!isExist)
{
itemDataList.push(MarketData);
}
// 검색된 모든 종목의 시세 수신이 완료되었을 때
if (itemDataList.length == searchItems.length && isSearching)
{
Main.KillTimer(2); // 타임아웃 타이머 해제
ProcessBuyOrder();
}
}
// ----------------------------------------------------
// 2. 실시간 20% 수익률 감시 및 익절 청산
// ----------------------------------------------------
Account1.SetBalanceItem(MarketData.code, 0);
if (Account1.Balance.count > 0)
{
var avgCost = Account1.Balance.avgUnitCost; // 평균 단가
var currentPrice = MarketData.current; // 현재가
// +20% 이상 수익 시 청산
if (avgCost > 0 && currentPrice >= avgCost * 1.20)
{
Main.MessageLog("★ [20% 익절 청산] 종목: " + MarketData.code + " / 매수가: " + avgCost + " / 현재가: " + currentPrice);
Account1.OrderSell(MarketData.code, Account1.Balance.count, 0, 1); // 시장가 매도
// 청산 완료 시 시세 객체 해제
Main.RemoveMarketData(MarketData);
}
}
}
// ★ [수정] 변동성기준선 A와 가장 가까운 종목 선별 후 시장가 즉시 매수
function ProcessBuyOrder()
{
if (itemDataList.length > 0 && isSearching)
{
var targetData = null;
var minDiffRate = 999999; // 최소 이격률 초기화
var targetVolA = 0;
// 검색된 종목들 중 현재가와 '변동성기준선 A' 가격 차이가 가장 적은 종목 탐색
for (var i = 0; i < itemDataList.length; i++)
{
var mData = itemDataList[i];
if (mData.current > 0 && mData.current > mData.limitDown)
{
var volPriceA = CalculateVolPriceA(mData);
if (volPriceA > 0)
{
// 현재가와 변동성기준선 A 가격의 격차 비율 계산 (%)
var diffRate = Math.abs(mData.current - volPriceA) / mData.current * 100;
// 격차가 가장 적은 종목을 매수 타겟으로 선택
if (diffRate < minDiffRate)
{
minDiffRate = diffRate;
targetData = mData;
targetVolA = volPriceA;
}
}
}
}
// 최종 선별된 변동성기준선 최근접 종목을 현재가(시장가)로 즉시 매수
if (targetData != null)
{
// 현재가 기준으로 매수 수량 연산
var buyQty = Math.floor(ORDER_AMOUNT / targetData.current);
if (buyQty > 0)
{
Main.MessageLog("★ [최근접종목 시장가 매수] 종목: " + targetData.code +
" / 현재가: " + targetData.current +
" / 변동성A: " + targetVolA +
" / 격차: " + minDiffRate.toFixed(2) + "% / 수량: " + buyQty + "주");
// ★ 시장가(구문: 종목코드, 수량, 가격:0, 주문구분:1=시장가) 주문 발주
Account1.OrderBuy(targetData.code, buyQty, 0, 1);
}
// 매수 타겟 제외 나머지 종목 시세 메모리 해제
for (var k = 0; k < itemDataList.length; k++)
{
if (itemDataList[k].code != targetData.code)
{
Main.RemoveMarketData(itemDataList[k]);
}
}
}
else
{
Main.MessageLog("-> [매수 스킵] 조건을 만족하는 매수 대상 종목이 없습니다.");
for (var k = 0; k < itemDataList.length; k++)
{
Main.RemoveMarketData(itemDataList[k]);
}
}
}
isSearching = false;
}
// 변동성기준선 A 연산 함수
function CalculateVolPriceA(MarketData)
{
var prevClose = MarketData.GetHistory(1, 0); // 전일 종가
var prevClose2 = MarketData.GetHistory(2, 0); // 전전일 종가
var prevHigh = MarketData.GetHistory(1, 1); // 전일 고가
var prevLow = MarketData.GetHistory(1, 2); // 전일 저가
var rawA = 0;
if (prevClose > prevClose2)
rawA = (prevHigh + prevLow + prevClose + prevHigh) / 2 - prevLow;
else if (prevClose < prevClose2)
rawA = (prevHigh + prevLow + prevClose + prevLow) / 2 - prevLow;
else
rawA = (prevHigh + prevLow + prevClose + prevClose) / 2 - prevLow;
return rawA;
}
// 총 사용 금액 계산 함수
function GetTotalInvestedAmount()
{
var total = 0;
var num = Account1.GetTheNumberOfBalances();
for (var i = 0; i < num; i++)
{
Account1.SetBalanceIndex(i);
if (Account1.Balance.count > 0)
{
total += (Account1.Balance.avgUnitCost * Account1.Balance.count);
}
}
return total;
}
답변 1
예스스탁 예스스탁 답변
2026-08-03 14:07:17