답변완료
종목검색 삭제
안녕하세요.
아래 수식에서 PSearch 종목검색후 종목검색조건에서 제외되어 파워종목검색에서 사라진 종목도 여전히 스팟에 남아 있는데요.
조건에서 제외되어 파워종먹검색에서 사라진 종목들은 스팟에서 검색 업데이트시 제외되도록 수정 부탁드립니다.
var BL = [],req;
var CT = [],MK = [];
function Main_OnStart()
{
//처음 시작시 step은 0
step = 0;
//시작시점의 보유종목수
var num = Account1.GetTheNumberOfBalances();
//보유종목이 1개 이상이면 보유종목의 종목코드를 BL변수에 순차적으로 저장
if (num > 0)
{
BL = [];
for(var i = 0 ; i < num ; i++)
{
Account1.SetBalance(i);
BL.push(Account1.Balance.code);
}
Main.MessageList("BL : ",BL);
if (BL.length >= 1)
{
req = 0;
var TradeSet = new SystemTradeInfo(TRADE_FIXCOUNT,
1, // 거래수량
123456789, // 자산
1, // 단위수량
0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료
0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지
PYRAMIDING_ENTRY, // 피라미딩 설정여부
100000, // 최대진입수량
10); // 최대진입횟수
var ChartSet = new ReqChartItem(BL[req],5,CHART_PERIOD_MINUTE,5000,CHART_REQCOUNT_BAR,false,false);
var SymSet = new SystemInfo("[현물]WayPointStock01_H_Signal",YL_TYPE_NORMAL,null,TradeSet);
Main.ReqChartEx(ChartSet, SymSet);
Main.MessageList("차트객체요청 :",BL[req]);
}
}
else //보유종목이 없으면 바로 1분 타이머 시작
{
Main.MessageList("보유종목없음");
Main.SetTimer(1, 10000);//1번 타이머, 60초
}
}
function Main_OnRcvChartEx(ChartEx)
{
if (ChartEx.GetCode(1) == BL[req])
{
Main.MessageList("차트객체생성 :",ChartEx.GetCode(1));
CT.push(ChartEx);
Main.ReqMarketData(BL[req]);
Main.MessageList("종목객체요청 :",BL[req]);
}
}
function Main_OnRcvMarketData(MarketData)
{
if (MarketData.code == BL[req])
{
Main.MessageList("종목객체생성 :",MarketData.code);
MK.push(MarketData);
req = req+1;
if (req < BL.length)
{
var TradeSet = new SystemTradeInfo(TRADE_FIXCOUNT,
1, // 거래수량
123456789, // 자산
1, // 단위수량
0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료
0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지
PYRAMIDING_ENTRY, // 피라미딩 설정여부
100000, // 최대진입수량
10);
var ChartSet = new ReqChartItem(BL[req],5,CHART_PERIOD_MINUTE,5000,CHART_REQCOUNT_BAR,false,false);
var SymSet = new SystemInfo("[현물]WayPointStock01_H_Signal",YL_TYPE_NORMAL,null,TradeSet);
Main.ReqChartEx(ChartSet, SymSet);
Main.MessageList("차트객체요청 :",BL[req]);
}
else
{
Main.SetTimer(1, 10000);//1번 타이머, 60초
Main.MessageList("보유종목차트생성완료",CT.length,MK.length);
}
}
}
function Main_OnTimer(nEventID)
{
if (nEventID == 1)
{
//타이머 종료
Main.KillTimer(1);
Main.ReqPowerSearch("PSearch");
}
}
function Main_OnRcvItemList(aItemList, nCount)
{
//검색된 종목이 없으면
if (nCount == 0)
{
//타이머 다시 셋팅
Main.SetTimer(1, 100000);//1번 타이머, 60초
}
//검색된 종목이 있으면
if (nCount >= 1)
{
//검색된 종목과 기존 만든 차트들의 종목코드를 비교해
//차트가 만들어 지지 않은 종목이면 BL변수에 종목코드 추가
BL = [];
for(var i = 0 ; i < aItemList.length ; i++)
{
var add = true;
for(var z = 0 ; z < CT.length ; z++)
{
if (aItemList[i] == CT[z].GetCode(1))
{
add = false;
break;
}
}
if (add == true)
{
BL.push(aItemList[i]);
}
}
Main.MessageList("BL : ",BL);
//차트 생성해야할 종목이 있으면 차트요청
if (BL.length >= 1)
{
req = 0;
//차트 요청
var TradeSet = new SystemTradeInfo(TRADE_FIXCOUNT,
1, // 거래수량
123456789, // 자산
1, // 단위수량
0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료
0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지
PYRAMIDING_ENTRY, // 피라미딩 설정여부
100000, // 최대진입수량
10);
var ChartSet = new ReqChartItem(BL[req],5,CHART_PERIOD_MINUTE,5000,CHART_REQCOUNT_BAR,false,false);
var SymSet = new SystemInfo("[현물]WayPointStock01_H_Signal",YL_TYPE_NORMAL,null,TradeSet);
Main.ReqChartEx(ChartSet, SymSet);
}
else //없으면 타이머 다시 셋팅
{
Main.SetTimer(1, 100000);//1번 타이머, 60초
}
}
}
답변완료
문의드립니다.
안녕하세요. YL에서 도움을 많이 주셔서 시스템 구성을 개략적으로 마무리하고 이제 자동매매를 위해 예스스팟을 공부 중에 있습니다.
현재 현물/선물 거래를 동시에 하고 있어서 몇가지 질문을 드리고자 합니다.
1) 계좌 1에서 선물거래 중인데 수익금/손실금을 기준으로 계좌2에서 피라미딩 또는 헷지를 해보려고 합니다.
예를 들어
* 진입
계좌 1에서 300만원 수익이 난 경우, 매수/매도 수량 절반을 계좌2에서 반대로 진입하고, 600만원까지 수익이 증가하면 나머지 수량 절반을 계좌2에서 반대로 진입
* 청산
1. 계좌1 수익이 600만원 수익 후 300만원까지 수익이 감소하면 계좌 2 진입물량 절반 청산, 계좌1 수익이 300만원 수익 후 0까지 감소하면 계좌2 진입물량을 모두 청산.
2. 계좌1 진입물량이 모두 청산(잔고0)되면 계좌 2 진입물량도 모두 청산.
이렇게 가정하고 수식을 짜봤습니다.
var HCount1 = 0;
var HCount2 = 0;
var BaNumber = 0;
function Main_OnStart()
{
Main.MessageLog("시작")
//1초 타이머
Main.SetTimer(1, 1000);
}
function Main_OnTimer(nEventID)
{
//계좌 재조회
Account1.Refresh();
Account1.SetBalance(Account1.Balance.code,0);
BaNum = Account1.GetTheNumberOfBalances();
}
function Main_OnU*dateAccount(sAccntNum, sItemCode, lU*dateID)
{
if (Account1.number == sAccntNum && lU*dateID == 30000)
{
//현재 예탁자산총평가액과 전일예탁자산의 차이
var PL = Account1.GetBalanceETCinfo(10)-Account1.GetBalanceETCinfo(0);
//300만원 이상 수익인 경우
if (PL >= 3000000)
{
if (Account1.Balance.position == 1) // 계좌1 매도일 때 매수수량의 절반을 계좌2에서 매도
Account2.OrderBuy(Account1.Balance.code, Account1.Balance.count/2,0,1);
if (Account1.Balance.position == 2) // 계좌1 매수일 때 매도수량의 절반을 계좌2에서 매도
Account2.OrderSell(Account1.Balance.code, Account1.Balance.count/2,0,1);
HCount1 = HCount1++; // 수익이 300만원 이상인 경우를 체크
}
//600만원 이상 수익
if (PL >= 6000000)
{
if (Account1.Balance.position == 1)
Account2.OrderBuy(Account1.Balance.code, Account1.Balance.count/2,0,1);
if (Account1.Balance.position == 2)
Account2.OrderSell(Account1.Balance.code, Account1.Balance.count/2,0,1);
HCount2 = HCount2++; // 수익이 600만원 이상은 경우를 체크
}
if (HCount1 > 0 && HCount2 > 0 && PL<=3000000) // 수익이 600만원 이상 발생했다가 300만원까지 떨어진 경우
{
if (Account1.Balance.position == 1)
Account2.OrderBuy(Account1.Balance.code, Account2.Balance.count/2,0,1); // 계좌2 매도수량의 절반 정리
if (Account1.Balance.position == 2)
Account2.OrderSell(Account1.Balance.code, Account2.Balance.count/2,0,1); // 계좌2 매도수량의 절반 정리
}
if (HCount1 > 0 && PL<=0) // 수익이 300만원 이상 발생했다가 0까지 떨어진 경우
{
if (Account1.Balance.position == 1)
Account2.OrderBuy(Account1.Balance.code, Account1.Balance.count,0,1); // 계좌2 매도수량 정리
if (Account1.Balance.position == 2)
Account2.OrderSell(Account1.Balance.code, Account1.Balance.count,0,1); // 계좌2 매수수량 정리
}
if (BaNum == 0) // 계좌1에 잔고가 없는 경우 매수/매도수량 정리(이미 Account1은 잔고가 없는 상황이라서 괄호안 내용으로는 맞지 않는 것 같습니다)
{
if (Account1.Balance.position == 1)
Account2.OrderBuy(Account1.Balance.code, Account2.Balance.count,0,1);
if (Account1.Balance.position == 2)
Account2.OrderSell(Account1.Balance.code, Account2.Balance.count,0,1);
}
}
//타이머종료
Main.KillTimer(1);
}
2. 현물시스템 운용 중에 특정가격을 YL에서 매수 가격으로 세팅하고 Yesstop으로 매수 시, 하루에 한 번만 매수가 되는 것 같습니다.
yl에서는 분할매수를 하고 있으며 1) 통계목적 상으로, 신호가 나오면 수량을 달리해서 2~3회 동시 매수하고 있고, 2)가격을 달리해서 매수(같은 봉 또는 다른 봉에서 3-4회)하고 있습니다.
작성한 수식 중
=> if (Signal.signalKind == 1) ////// && Account1.Balance.count == 0)
이 부분에서 count부분을 삭제하면 수차례 매수될 것으로 생각했는데 어떻게 수정해야되는지 가이드 부탁드립니다. 감사합니다.
var ItemList;
var Count;
var ReqCount;
var d;
var H;
function Main_OnStart()
{
Main.MessageLog("스팟시작");
d = new Date();
h=d.getDate();
//지정한 관심그룹의 종목수(관심그룹지정 필요)
Count = Main.GetItemCountOfInterest("스팟연습");
Main.MessageList("지정관심그룹 종목수 : ", Count);
ItemList = [];
//관심그룹 종목코드를 ItemList로 옮김
for(var i = 0 ; i < Count ; i++)
{
//관심그룹지정 필요
ItemList.push(Main.GetItemCodeInInterest("스팟연습", i));
}
Main.SetTimer(1, 500);
ReqCount = 0;
}
function Main_OnTimer(nEventID)
{
if (nEventID == 1)
{
var ChartSet = new ReqChartItem(ItemList[ReqCount],15,CHART_PERIOD_MINUTE,1000,CHART_REQCOUNT_BAR,false,false);
/////SystemInfo(name,kind,inputVar,tradeInfo,stopInfo)
var SystemSet = new SystemInfo("@@연습", YL_TYPE_NORMAL, null, null, null);
Main.ReqChartEx(ChartSet,SystemSet);
Main.MessageLog("확장차트생성_"+ItemList[ReqCount]);
ReqCount = ReqCount+1;
if (ReqCount == Count)
{
Main.KillTimer(1);
Main.MessageLog("종목검색완료");
}
}
}
//신호발생
function Main_OnRiseSignal(ChartEx, Signal)
{
//신호발생 종목에 대해 잔고셋팅
Account1.SetBalance(Main.GetOrderCode(Signal.code),0);
//매수신호이고 잔고가 없을때만 매수 수정
if (Signal.signalKind == 1) ////// && Account1.Balance.count == 0)
{
Account1.OrderBuy(Main.GetOrderCode(Signal.code), Signal.count, Signal.price, 0);
Main.MessageLog("매수주문9");
}
if (Signal.signalKind == 2)
{
//전체미체결주문 갯수
var num = Account1.GetTheNumberOfUnfills();
//전체 미체결수 만큼 루프를 돌면서
for (var i = 0; i < num; i++)
{
//미체결을 하나씩 셋팅하고 Account1.GetTotalAmount(nCategory, nTradeKind)
Account1.SetUnfill(i);
//미체결종목이 신호종목과 같고 미체결수량이 있으면
if (Account1.Unfill.code == Main.GetOrderCode(Signal.code) && Account1.Unfill.count > 0)
{
Account1.OrderCancel(Account1.Unfill.orderNum);
}
}
//잔고수량만큼만 매도
if (Account1.Balance.count > 0)
{
Account1.OrderSell(Main.GetOrderCode(Signal.code), Signal.count, Signal.price, 0);
Main.MessageLog("매도주문");
}
}
}
가이드 주시면 보완해 나가겠습니다.
노고에 항상 감사드립니다.
즐거운 주말 보내세요.
답변완료
수식 부탁합니다
수정해 주신 식은 매도는 되나 청산(매수)이 전혀되지 않습니다.
다음식은 수정해 주신 2253 입니다.
var EntryTime = 103000;
var ExitTime = 144500;
var MaxEnryVol = 10;
var Entry,Exit,CurrentVol;
var CSV,PSV,CSX,PSX;
var CallOrderCode,PutOrderCode;
function Main_OnStart()
{
var d = new Date();
var YYYYMMDD = d.getFullYear()*10000+(d.getMonth()+1)*100+d.getDate();
var HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds();
Main.MessageList(HHMMSS,"Start");
Entry = true;
if (HHMMSS >= EntryTime)
{
Entry = false;
}
Exit = true;
if (HHMMSS >= ExitTime)
{
Exit = false;
}
if (Entry == true || Exit == true)
{
Main.MessageList(HHMMSS,"1번 타이머동작");
Main.SetTimer(1, 5000);
}
}
function Main_OnTimer(nEventID)
{
var d = new Date();
var YYYYMMDD = d.getFullYear()*10000+(d.getMonth()+1)*100+d.getDate();
var HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds();
if (nEventID == 1)
{
if (Entry == true && HHMMSS >= EntryTime)
{
//양매도종목
CallOrderCode = Option.GetATMCallRecent(0);
PutOrderCode = Option.GetATMPutRecent(0);
Main.SetUserValue("SellDate",YYYYMMDD);
Main.SetUserValue("CallOrderCode",CallOrderCode);
Main.SetUserValue("PutOrderCode",PutOrderCode);
Entry = false;
if (ExitTime > EntryTime)
Main.KillTimer(1);
Account1.OrderSell(CallOrderCode, 1, Option.GetBid(CallOrderCode, 2),0);
Account1.OrderSell(PutOrderCode, 1, Option.GetBid(PutOrderCode, 2), 0);
CurrentVol = 1;
Main.SetTimer(2, 5000);
}
if (Exit == true && HHMMSS >= ExitTime)
{
Exit = false;
if (ExitTime > EntryTime)
Main.KillTimer(1);
var SellDate = Main.GetUserValue("SellDate")
if (YYYYMMDD == SellDate)
{
CallOrderCode = Main.GetUserValue("CallOrderCode");
PutOrderCode = Main.GetUserValue("PutOrderCode");
if (CallOrderCode != "")
{
Account1.SetBalance(CallOrderCode, 0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
CSV = Account1.Balance.count;
else
CSV = 0;
if (PSV > 0)
{
Main.SetTimer(3, 5000);
CSX = 1;
Account1.OrderBuy(CallOrderCode, 1, Option.GetAsk(CallOrderCode, 2),0);
}
}
if (PutOrderCode != "")
{
Account1.SetBalance(PutOrderCode, 0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
PSV = Account1.Balance.count;
else
PSV = 0;
if (PSV > 0)
{
Main.SetTimer(4, 5000);
PSX = 1;
Account1.OrderBuy(PutOrderCode, 1, Option.GetAsk(PutOrderCode, 2),0);
}
}
}
}
}
if (nEventID == 2)
{
CurrentVol = CurrentVol+1;
if (CurrentVol <= MaxEnryVol)
{
Account1.OrderSell(CallOrderCode, 1, Option.GetBid(CallOrderCode, 2),0);
Account1.OrderSell(PutCode, 1, Option.GetBid(PutCode, 2), 0);
}
else
{
Main.KillTimer(2);
}
}
if (nEventID == 3)
{
CSX = CSX+1;
if (CSX <= CSV)
{
Account1.OrderBuy(CallOrderCode, 1, Option.GetAsk(CallOrderCode, 2),0);
}
else
{
Main.KillTimer(3);
}
}
if (nEventID == 4)
{
PSX = PSX+1;
if (PSX <= PSV)
{
Account1.OrderBuy(PutOrderCode, 1, Option.GetAsk(PutOrderCode, 2),0);
}
else
{
Main.KillTimer(4);
}
}
}
답변완료
지표값을 Tick Size 단위로 변환시 이상현상 문의합니다.
문의에 항상 빠른 답변에 감사드립니다.
제가 하고자 하는 것은 지표값을 구하여 그 지표값을 주문 가격에 이용하고자 틱 사이즈 단위로 변환하여 수치을 구하고자 합니다.
GetTickSize 함수로 마이크로 골드 종목을 구하면 0.1000000...
소수점 이하 많은 양이 나오네요.
그래서 0.1로 조정을 했습니다.
그런데 TickSize 값은 0.1로 잘 나오는데, BBC1, BBU1, BBD1 등 값은 0.1단위로
나올때도 있고 수수점 이하 많은 자리가 나올때도 있는 등 들쑥날쑥이네요.
제가 무엇을 잘못 했나요?!
아래 식은 제가 일부분을 발췌하였습니다.
var TickSize = F1.GetTickSize();//: 호가단위 : NH 실제:소수점 이하 10이상 존재
TickSize = Math.floor(TickSize*1000000)/1000000; // 종목 적용시 소수점 이하 6자리까지 적용가능
var BBC1 = C1.GetIndicatorData("Bollinger Bands", 1,0); //BB지표
var BBU1 = C1.GetIndicatorData("Bollinger Bands", 2,0);
var BBD1 = C1.GetIndicatorData("Bollinger Bands", 3,0);
Main.MessageList("상단 : " + BBU1 +
", 하단 : "+ BBD1 +
", 중심선 : "+ BBC1
);
//TickSize로 Price 변경 Math.floor(A / TickSize)*TickSize
Main.MessageList("틱 사이즈 : " + TickSize);
BBC1 = Math.floor(BBC1 / TickSize)*TickSize; //TickSize 단위로 내림
BBU1 = Math.floor(BBU1 / TickSize)*TickSize;
BBD1 = Math.floor(BBD1 / TickSize)*TickSize;
Main.MessageList("1분봉 틱 조정 상단 : " + BBU1 +
", 하단 : "+ BBD1 +
", 중심선 : "+ BBC1
);
갑사합니다.