예스스탁
예스스탁 답변
2023-12-14 17:24:26
안녕하세요
예스스탁입니다.
1
현재 스팟 수식상에서 차트나 종목객체 생성 흐름에는 문제가 없습니다.
2
전화로 답변드린 부분과 같이
미완성신호 발생시에 매도 부분에 신호의 종류나 미완성매수신호가 발생한것을 확인하지 않는 부분이 있어
해당 부분 내용만 보강해 드립니다.
3
//************** #2en4-C9 Rev.02
//** 전 략 : 변경 (귀찮아서 정리 안함 <= 다음 기회에)
// 1. 파워종목검색 => 2. YesSpot(완성봉,미완성봉(Stoploss))
// 1-1. 거래량, 거래대금 300순위 (종목검색식 : 순위)
// 1-2. C(0) > (highest(H,3)+highest(C,3))/2 (종목검색식 : #2en4-HC01)
// 1-3. V(0) > highest(ma(v,5),130)*0.5 (종목검색식 : #2en4-V01)
// 1-4. pos == 1 (ATR(10,2)) (종목검색식 : #2en4-UTBOT)
// 2-1. 파워종목검색 => 관심종목 등록 => Chart 완성 => 매수종목 선정
// 2-2. 매수
// 1. V(0) > highest(ma(v,5),130)*0.618
// 2. xATRTS(0) 순위 (검증 후 추가 : 금액대비 매수 종목수 변경)
// 2-3. 매도
// 1. 손절, 최대수익대비하락율, 가격변화율, 당일청산 (System : Stoploss)
// 2. 당일 고가대비 6% 이하 (매수청산)
// 3. 이전봉 대비 고가, 저가 이탈(기본손절선:이전봉 저가) (매수 청산))
//** 적용 분 봉 : 15분봉
//** 종목 검색식 : #2en4-HCV01
//** 적용 시스템 : #2en4-HCV01
//** 적용 지 표 : #2en4-UNV04
//************** 2023. 12
var ensearchp = 10; //검색종목 검색주기(10초)
var enbumaxno = 50; //최대종목수
var InteList = []; //관심종목 배열선언변수
var SearList = []; //검색종목 배열선언변수
var CharList = []; //차트종목 배열선언변수
var MarkList = []; //주문종목 배열선언변수
var Num = [];
var Timer = [];
var HHMMSS,req;
var BuyEntry,BuyVol;
var enmyacc, buyacc1, buyacc2, myacc;
var tempmax, tempIndex, xATR, xATRTS, xATRTT;
var xATRTS = [];
var xATRTT = [];
var xATR = [];
var xATRR = [];
var Nth = [];
// Spot Start (잔고 및 종목당 매수금 셋팅, 보유종목 검색, 챠트생성)
function Main_OnStart()
{
CTcnt = 0;
enmyacc = Account1.GetBalanceETCinfo(100); // 계좌 정산금액, 18:현금 매수가능금액
buyacc1 = 4;
buyacc2 = 2;
myacc = (enmyacc/buyacc1)*buyacc2; // 종목당 매수금(기본 30만원) .
Main.MessageList("Spot Start!!");
var num = Account1.GetTheNumberOfBalances();
Main.MessageList("보유종목수 : ",num);
if (num > 0)
{
SearList = [];
for(var i = 0 ; i < num ; i++)
{
Account1.SetBalance(i);
SearList.push(Account1.Balance.code);
}
if (SearList.length >= 1)
{
req = 0;
var StopSet = new SystemStopInfo(new StopLoss(6, CALCMETHOD_PERCENT, 0xFFDA93), //손절
new StopTrailing(30, 30, CALCMETHOD_PERCENT, 0), //최고수익금액 대비 하락 %
new StopProfitTarget(100, CALCMETHOD_PERCENT, 0xFFDA93)); //수익
// new StopInactivity(5, 15, CALCMETHOD_PERCENT, 0xFFDA93),
// new StopEndOfDay(151500));
var ChartSet = new ReqChartItem(SearList[req],15,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false);
var SystemSet = new SystemInfo("#2en4-C9", YL_TYPE_NORMAL, null, null, StopSet);
var SetIndicator = new Array(new IndicatorInfo("#2en4-C9","#2en4-C9V"));
Main.MessageList(req,"보유종목챠트 : ",SearList[req]);
Main.ReqChartEx(ChartSet, SystemSet, SetIndicator);
}
}
else //보유종목이 없으면 바로 1분 타이머 시작
{
Main.MessageList("보유종목없음");
Main.SetTimer(1, ensearchp*1000);//1번 타이머, 10초
}
}
//전일 관심종목 삭제, 파워종목검색
function Main_OnTimer(nEventID)
{
var d = new Date();
HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds();
if (nEventID == 1 && (HHMMSS > 070000 && HHMMSS < 085900))
{
Main.SendInterests("2en4", SearList, false); //관심종목 대체
}
if (nEventID == 1 && HHMMSS >= 010000 && CharList.length < enbumaxno)
{
Main.MessageList("현금매수 가능금액 : ",myacc);
Main.MessageList(d,"종목검색 요청시간 : ",HHMMSS);
Main.ReqPowerSearch("#2en4-C9");
}
if (nEventID < enbumaxno)
{
Timer[nEventID] = Timer[nEventID]+1;
if (Timer[nEventID] == 1)
{
var num = Account1.GetTheNumberOfUnfills(); //전체미체결주문 갯수
for (var i = 0; i < num; i++) //전체 미체결수 만큼 루프를 돌면서
{
Account1.SetUnfill(i); //미체결을 하나씩 셋팅하고
if (Account1.Unfill.code == CharList[nEventID].GetCode && Account1.Unfill.count > 0) //타이머와 같은 미체결종목을 찾아
{
if (Account1.Unfill.price != MarkList[nEventID].current) //주문가격과 현재가가 다르면(같으면 정정불가)
{
Account1.OrderReplacePrice(Account1.Unfill.orderNum, MarkList[nEventID].current); //현재가로 정정
}
}
}
}
if (Timer[nEventID] == 2)
{
Main.KillTimer(Timer[nEventID]); //타이머가 2번 동작했으므로 타이머는 종료
var num = Account1.GetTheNumberOfUnfills(); //전체미체결주문 갯수
for (var i = 0; i < num; i++) //전체 미체결수 만큼 루프를 돌면서
{
Account1.SetUnfill(i); //미체결을 하나씩 셋팅하고
if (Account1.Unfill.code == CharList[nEventID].GetCode && Account1.Unfill.count > 0) //타이머와 같은 미체결종목을 찾아
{
if (Account1.Unfill.orderKind == 2 && Account1.Unfill.price != MarkList[nEventID].Ask(1)) //매수주문이고 주문가격과 매도1호가가 다르면(같으면 정정불가)
{
Account1.OrderReplacePrice(Account1.Unfill.orderNum, MarkList[nEventID].Ask(5)); //매도1호가로 정정
}
if (Account1.Unfill.orderKind == 1 && Account1.Unfill.price != MarkList[nEventID].Bid(1)) //매도주문이고 주문가격과 매수1호가가 다르면(같으면 정정불가)
{
Account1.OrderReplacePrice(Account1.Unfill.orderNum, MarkList[nEventID].Bid(5));//매수1호가로 정정
}
}
}
}
}
}
//검색된 종목 관심종목등록, 챠트 생성
function Main_OnRcvItemList(aItemList, nCount)
{
Main.MessageList("종목검색 완료 : ",nCount);
if (nCount > 0)
{
SearList = [];
if (CharList.length == 0)//첫검색일때
{
SearList = aItemList;
}
else //두번 이후(차트가 만들어진 종목을 제외하고 새로운 종목만 집계)
{
for (var i = 0; i < nCount; i++ )
{
var add = true;
for (var x = 0; x < CharList.length; x++ )
{
if (aItemList[i] == CharList[x].GetCode(1))
{
add = false;
}
}
if (add == true)
{
SearList.push(aItemList[i]);
}
}
}
Main.MessageList("종목검색 완료 SearList :",SearList.length);
Main.SendInterests("2en4", SearList, true); //관심종목 등록
Main.MessageList("관심종목 등록 ",SearList);
if (SearList.length > 0 && CharList.length < enbumaxno)//집계된 종목이 1개 이상이면 순차적으로 차트객체 요청
{
req = 0;
var StopSet = new SystemStopInfo(new StopLoss(6, CALCMETHOD_PERCENT, 0xFFDA93), //손절
new StopTrailing(30, 30, CALCMETHOD_PERCENT, 0), //최고수익금액 대비 하락 %
new StopProfitTarget(100, CALCMETHOD_PERCENT, 0xFFDA93)); //수익
// new StopInactivity(5, 15, CALCMETHOD_PERCENT, 0xFFDA93),
// new StopEndOfDay(151500));
var ChartSet = new ReqChartItem(SearList[req],15,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false);
var SystemSet = new SystemInfo("#2en4-C9", YL_TYPE_NORMAL, null, null, StopSet);
var SetIndicator = new Array(new IndicatorInfo("#2en4-C9","#2en4-C9V"));
Main.MessageList("현재차트갯수 : ",CharList.length);
Main.MessageList(req,"차트객체요청 : ",SearList[req]);
Main.ReqChartEx(ChartSet, SystemSet, SetIndicator);
}
else
{
if (CharList.length < enbumaxno)
{
Main.SetTimer(1, ensearchp*1000);
}
}
}
}
//챠트 중 종목 순위 결정
function Main_OnRcvChartEx(ChartEx)
{
if (SearList[req] == ChartEx.GetCode(1))
{
CharList[CTcnt] = ChartEx;
Main.MessageList(CTcnt,"차트객체생성 : ",CharList[CTcnt].GetCode(1));
xATRTS.push(ChartEx.GetIndicatorData("#2en4-C9",4,0)); //지표명, plot번호,0:현재봉 1:1봉전 2:2봉전
xATRTT.push(ChartEx.GetIndicatorData("#2en4-C9",4,1));
for (var i = 0; i < CharList.length; i++)
{
xATR.push(Math.floor((xATRTS[i] / xATRTT[i])*200100));
}
Nth.push(-1);
for (var i = 0; i < CharList.length; i++)
{
Main.MessageList("종목명 :",CharList[i].GetCode(1),"|xATRTS:",xATRTS[i],"|xATRTT:",xATRTT[i],"|xATR:",xATR[i]);
}
Main.MessageList("xATR 종목 순위 계산");
var Period = xATRTS.length;
for (var a = 0; a < Period; a++)
{
// Nth.push(-1);
xATRmax = -1;
for (var b = 0; b < Period; b++)
{
if (xATR[b] >= xATRmax)
{
xATRmax = xATR[b];
tempIndex = b;
}
}
xATRR[tempIndex] = -1;
Nth[tempIndex] = a;
}
for (var i = 0; i < CharList.length; i++)
{
Main.MessageList("종목명 : ",CharList[i].GetCode(1),"|순위:",Nth[i]);
}
if (CharList.length < enbumaxno)
{
Main.SetTimer(1, ensearchp*1000);
}
Main.ReqMarketData(SearList[req]);
Main.MessageList(CTcnt,"종목객체요청 : ",SearList[req]);
}
}
function Main_OnRcvMarketData(MarketData)
{
if (SearList[req] == MarketData.code)
{
Main.MessageList(CTcnt,"종목객체생성 : ",MarketData.code);
MarkList[CTcnt] = MarketData;
CTcnt = CTcnt +1;
req = req + 1;
if (req < SearList.length && CharList.length < enbumaxno)
{
var StopSet = new SystemStopInfo(new StopLoss(6, CALCMETHOD_PERCENT, 0xFFDA93),
new StopTrailing(30, 30, CALCMETHOD_PERCENT, 0),
new StopProfitTarget(100, CALCMETHOD_PERCENT, 0xFFDA93));
// new StopInactivity(5, 15, CALCMETHOD_PERCENT, 0xFFDA93),
// new StopEndOfDay(151500));
var ChartSet = new ReqChartItem(SearList[req],15,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false);
var SystemSet = new SystemInfo("#2en4-C9", YL_TYPE_NORMAL, null, null, StopSet);
var SetIndicator = new Array(new IndicatorInfo("#2en4-C9","#2en4-C9V"));
Main.MessageList("현재차트갯수 : ",CharList.length);
Main.MessageList(req,"차트객체요청 : ",SearList[req]);
Main.ReqChartEx(ChartSet, SystemSet, SetIndicator);
}
else
{
Main.MessageList("차트객체요청종료");
if (CharList.length < enbumaxno)
{
Main.SetTimer(1, ensearchp*1000);
}
}
}
}
// 계좌에 해당 종목이 있는지 확인하는 함수
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;
}
//완성봉 신호 기준 매수, 매도
function Main_OnRiseSignal(ChartEx, Signal)
{
Account1.SetBalance(Main.GetOrderCode(Signal.code),0); //신호발생 종목에 대해 잔고셋팅
var RanK;
for (var i = 0; i < CharList.length; i++)
{
if (ChartEx.GetCode(1) == CharList[i].GetCode(1))
{
RanK = Nth[i];
}
}
/*
//매수신호 발생 종목의 UTBOT 높은순으로 5위(0~4)이내이고 잔고가 없을때만 매수
if ((Signal.signalKind == 1) &&(Account1.Balance.count == 0) && (RanK >= 0 && RanK < 5))
{
Account1.OrderBuy(Main.GetOrderCode(Signal.code),Math.floor(myacc/ChartEx.GetClose(1,0)-1),0,1); //Math.floor((myacc / MarketData.current)-1)
Main.MessageList("Buy Chart!");
}
*/
if (Signal.signalKind == 2)
{
var num = Account1.GetTheNumberOfUnfills(); //전체미체결주문 갯수
for (var i = 0; i < num; i++) //전체 미체결수 만큼 루프를 돌면서
{
Account1.SetUnfill(i); //미체결을 하나씩 셋팅하고
if (Account1.Unfill.code == Main.GetOrderCode(Signal.code) && Account1.Unfill.count > 0) //미체결종목이 신호종목과 같고 미체결수량이 있으면
{
Account1.OrderCancel(Account1.Unfill.orderNum);
}
}
var XV = Math.max(Signal.count,Account1.Balance.count);
if (XV > 0)
{
Account1.OrderSell(Main.GetOrderCode(Signal.code),XV,MarkList[i].current,1);
//Account1.OrderSell(Main.GetOrderCode(Signal.code),Account1.Balance.count,MarkList[ii].current,0);
Main.MessageList("Sell Chart!");
// if (ii >= 0)
// {
// Main.SetTimer(ii,60000);
// Timer[i] = 0;
// }
}
}
}
// 미완성 신호기준 매수, 매도
function Main_OnRiseIncompleteSignal(ChartEx, IncompleteSignal)
{
Account1.SetBalance(Main.GetOrderCode(IncompleteSignal.code),0); //신호발생 종목에 대해 잔고셋팅
var ii;
if (CharList.length > 0)
{
for (var i = 0; i < CharList.length; i++)
{
if(CharList[i].GetCode(1) == ChartEx.GetCode(1))
{
ii = i;
}
}
}
//매수신호이고 잔고가 없을때만 현재가 매수 (signalkind ==1 :미완성신호 buy, signalKind == 2:미완성신호 sell)
if (Sig[ii] == 0 && IncompleteSignal.signalKind == 1 && Account1.Balance.count == 0)
{
Sig[ii] = 1; //sig 배열값은 1로 변경
HH[ii] = 0;
Account1.OrderBuy(Main.GetOrderCode(IncompleteSignal.code),Math.floor(myacc/ChartEx.GetClose(1,0)-1),0,1);
Main.MessageList("Buy Signal!");
if (ii >= 0)
{
Main.SetTimer(ii,60000);
Timer[ii] = 0;
}
}
//미완성매도신호 발생하고 해당종목 Sig값이 1이고 잔고에 수량이 있으면 매도
if (Account1.Balance.count > 0 && Sig[ii] == 1 && IncompleteSignal,signalKind == 2)
{
var XV = Math.max(Signal.count,Account1.Balance.count);
Account1.OrderSell(Main.GetOrderCode(IncompleteSignal.code),XV,MarkList[i].current,1);
Main.MessageList("Sell Signal!");
if (ii >= 0)
{
Main.SetTimer(ii,60000);
Timer[ii] = 0;
}
}
}
즐거운 하루되세요
> 예스스탁 님이 쓴 글입니다.
> 제목 : Re : 전화주시기 바랍니다.(02-3453-1060)
>
> 라엔 님이 쓴 글입니다.
> 제목 : 미완성봉 신호 매수
> 안녕하세요
시스템 수식에서 미완성봉 신호로 매수매도 하고 싶은데
잘 되지 않아 수식 수정 부탁드립니다
오늘 하루도 행복한 하루 되세요~~