예스스탁
예스스탁 답변
2021-08-19 11:20:32
안녕하세요
예스스탁입니다.
1
1-1
BaNum은 수식상 불필요한 부분인것 같아 삭제했습니다.
1-2
수식에 타이머가 1초인데 한번 동작후 종료하므로 계속 감시를 하지 못합니다.
일정간격으로 반복적으로 계좌를 감시하게 구현하셔야 합니다.
1-3
수익이 3000000,6000000이상이면 반복적으로 주문이 나가게 되어 있습니다.
조건만족시 한번만 주문이 집행되게 하셔야 합니다.
1-4
수량이 홀수일경우 /2만 하면 소숫점이 발생합니다.
소숫점 제외하고 지정되도록 작성하셔야 합니다.
2로 나눠서 소숫점제외하고 수량이 지정되게 작성해 드립니다.
또한 계산에 의해 수량이 0이면 주문이 집행되지 않게 작성해 드립니다.
1-5
Account1.Balance는 Account1.SetBalance함수로
특정종목에 대해 잔고가 셋팅이 되어야 사용이 가능합니다.
Account1.SetBalance(Account1.Balance.code,0);
는 잔고가 셋팅이 되지 않았는데 해당코드로 잔고를 셋팅하게 되어 있습니다.
선물 종목의 종목객체를 추가해서 해당 객체의 종목코드로 잔고 셋팅되게 하셔야 합니다.
1-6
아래 가이드 수식 참고하셔서 수정보완해 사용하시기 바랍니다.
var HCount1 = 0;
var HCount2 = 0;
function Main_OnStart()
{
Main.MessageLog("시작")
//1초 타이머
Main.SetTimer(1, 1000);
}
function Main_OnTimer(nEventID)
{
Main.MessageList("Main_OnTimer");
//계좌 재조회
Account1.Refresh();
}
//계좌이벤트
function Main_OnU*dateAccount(sAccntNum, sItemCode, lU*dateID)
{
//계좌refresh 완료
if (Account1.number == sAccntNum && lU*dateID == 30000)
{
//현재 예탁자산총평가액과 전일예탁자산의 차이
var PL = Account1.GetBalanceETCinfo(10)-Account1.GetBalanceETCinfo(0);
//계좌1의 특정종목 잔고셋팅
Account1.SetBalance(Main.GetOrderCode(MarketData1.code),0);
//계좌1에 특정종목의 수량이 있는 상태에서 HCount1이 0이고 300만원 이상 수익인 경우
if (HCount1 == 0 && PL >= 3000000 && Account1.Balance.count > 0)
{
// 계좌1 매도일 때 매수수량의 절반을 계좌2에서 매도
if (Account1.Balance.position == 1)
{
//절반계산
var vol = Math.floor(Account1.Balance.count/2)
//전반이 1이상일때만 주문
if (vol > 0)
{
Account2.OrderBuy(Account1.Balance.code,vol,0,1);
}
}
// 계좌1 매수일 때 매도수량의 절반을 계좌2에서 매도
if (Account1.Balance.position == 2)
{
var vol = Math.floor(Account1.Balance.count/2)
if (vol > 0)
{
Account2.OrderSell(Account1.Balance.code,vol,0,1);
}
}
//HCount1는 1
HCount1 = 1; // 수익이 300만원 이상인 경우를 체크
}
// 계좌1에 특정종목의 수량이 있는 상태에서 HCount2가 0이고 600만원 이상 수익
if (HCount2 == 0 && PL >= 6000000 && Account1.Balance.count > 0)
{
Account1.SetBalance(Main.GetOrderCode(MarketData1.code),0);
if (Account1.Balance.position == 1)
{
var vol = Math.floor(Account1.Balance.count/2)
if (vol > 0)
{
Account2.OrderBuy(Account1.Balance.code, vol,0,1);
}
}
if (Account1.Balance.position == 2)
{
var vol = Math.floor(Account1.Balance.count/2)
if (vol > 0)
{
Account2.OrderSell(Account1.Balance.code, vol,0,1);
}
}
//HCount2는 1
HCount2 = 1; // 수익이 600만원 이상은 경우를 체크
}
//계좌1에 특정종목의 수량이 있는 상태에서 수익이 600만원 이상 발생했다가 300만원까지 떨어진 경우
if (HCount1 > 0 && HCount2 > 0 && PL<=3000000 && Account1.Balance.count > 0 )
{
//계좌2의 특정종목 잔고셋팅
Account2.SetBalance(Main.GetOrderCode(MarketData1.code),0);
if (Account2.Balance.position == 1)
{
var vol = Math.floor(Account2.Balance.count/2)
if (vol > 0)
{
Account2.OrderBuy(Account2.Balance.code, vol,0,1); // 계좌2 매도수량의 절반 정리
}
}
if (Account2.Balance.position == 2)
{
var vol = Math.floor(Account2.Balance.count/2)
if (vol > 0)
{
Account2.OrderSell(Account2.Balance.code,vol,0,1); // 계좌2 매수수량의 절반 정리
}
}
}
//계좌1에 특정종목의 수량이 있는 상태에서 수익이 300만원 이상 발생했다가 0까지 떨어진 경우
if (HCount1 > 0 && PL<=0 && Account1.Balance.count > 0)
{
//계좌2의 특정종목 잔고셋팅
Account2.SetBalance(Main.GetOrderCode(MarketData1.code),0);
if (Account2.Balance.position == 1)
{
Account2.OrderBuy(Account2.Balance.code, Account2.Balance.count,0,1); // 계좌2 매도수량 정리
}
if (Account2.Balance.position == 2)
{
Account2.OrderSell(Account2.Balance.code, Account2.Balance.count,0,1); // 계좌2 매수수량 정리
}
}
// 계좌1에 잔고가 없는 경우 매수/매도수량 정리
if (Account1.Balance.count == 0)
{
//계좌2의 특정종목 잔고셋팅
Account2.SetBalance(Main.GetOrderCode(MarketData1.code),0);
if (Account2.Balance.position == 1)
{
Account2.OrderBuy(Account2.Balance.code, Account2.Balance.count,0,1); // 계좌2 매도수량 정리
}
if (Account2.Balance.position == 2)
{
Account2.OrderSell(Account2.Balance.code, Account2.Balance.count,0,1); // 계좌2 매수수량 정리
}
}
}
}
2
2번 내용은 작성하신 내용상 별도로 수정해 드릴 부분이 없습니다.
차트에서 발생하는 신호에 따라 주문하는 부분으로
차트에서 피라미딩으로 신호가 발생하면 스팟도 Signal.signalKind == 1이 반복적으로 발생하게 됩니다.
수식에 별도로 해당붑분을 막는 코딩내용이 없습니다.
즐거운 하루되세요
> 깜피 님이 쓴 글입니다.
> 제목 : 문의드립니다.
> 안녕하세요. 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("매도주문");
}
}
}
가이드 주시면 보완해 나가겠습니다.
노고에 항상 감사드립니다.
즐거운 주말 보내세요.
답변 감사드립니다.
한국컴퓨터 차트인데 2번 식을 운용해서 매수할 때 예스랭귀지와 예스스팟 간에 다음과 같은 차이가 발생합니다.
답글 주시는 사이에 매수식 부분을
if (Signal.signalKind == 1)// && Account1.Balance.count == 0)
이렇게 수정해서 사용해봐도 여전히 1회만 매수가 되고 있는데 다시 한 번 검토부탁드립니다.
감사합니다. 즐거운 주말 보내세요.
-------------------------------------------------------------------------------
> 예스스탁 님이 쓴 글입니다.
> 제목 : Re : 문의드립니다.
> 안녕하세요
예스스탁입니다.
1
1-1
BaNum은 수식상 불필요한 부분인것 같아 삭제했습니다.
1-2
수식에 타이머가 1초인데 한번 동작후 종료하므로 계속 감시를 하지 못합니다.
일정간격으로 반복적으로 계좌를 감시하게 구현하셔야 합니다.
1-3
수익이 3000000,6000000이상이면 반복적으로 주문이 나가게 되어 있습니다.
조건만족시 한번만 주문이 집행되게 하셔야 합니다.
1-4
수량이 홀수일경우 /2만 하면 소숫점이 발생합니다.
소숫점 제외하고 지정되도록 작성하셔야 합니다.
2로 나눠서 소숫점제외하고 수량이 지정되게 작성해 드립니다.
또한 계산에 의해 수량이 0이면 주문이 집행되지 않게 작성해 드립니다.
1-5
Account1.Balance는 Account1.SetBalance함수로
특정종목에 대해 잔고가 셋팅이 되어야 사용이 가능합니다.
Account1.SetBalance(Account1.Balance.code,0);
는 잔고가 셋팅이 되지 않았는데 해당코드로 잔고를 셋팅하게 되어 있습니다.
선물 종목의 종목객체를 추가해서 해당 객체의 종목코드로 잔고 셋팅되게 하셔야 합니다.
1-6
아래 가이드 수식 참고하셔서 수정보완해 사용하시기 바랍니다.
var HCount1 = 0;
var HCount2 = 0;
function Main_OnStart()
{
Main.MessageLog("시작")
//1초 타이머
Main.SetTimer(1, 1000);
}
function Main_OnTimer(nEventID)
{
Main.MessageList("Main_OnTimer");
//계좌 재조회
Account1.Refresh();
}
//계좌이벤트
function Main_OnU*dateAccount(sAccntNum, sItemCode, lU*dateID)
{
//계좌refresh 완료
if (Account1.number == sAccntNum && lU*dateID == 30000)
{
//현재 예탁자산총평가액과 전일예탁자산의 차이
var PL = Account1.GetBalanceETCinfo(10)-Account1.GetBalanceETCinfo(0);
//계좌1의 특정종목 잔고셋팅
Account1.SetBalance(Main.GetOrderCode(MarketData1.code),0);
//계좌1에 특정종목의 수량이 있는 상태에서 HCount1이 0이고 300만원 이상 수익인 경우
if (HCount1 == 0 && PL >= 3000000 && Account1.Balance.count > 0)
{
// 계좌1 매도일 때 매수수량의 절반을 계좌2에서 매도
if (Account1.Balance.position == 1)
{
//절반계산
var vol = Math.floor(Account1.Balance.count/2)
//전반이 1이상일때만 주문
if (vol > 0)
{
Account2.OrderBuy(Account1.Balance.code,vol,0,1);
}
}
// 계좌1 매수일 때 매도수량의 절반을 계좌2에서 매도
if (Account1.Balance.position == 2)
{
var vol = Math.floor(Account1.Balance.count/2)
if (vol > 0)
{
Account2.OrderSell(Account1.Balance.code,vol,0,1);
}
}
//HCount1는 1
HCount1 = 1; // 수익이 300만원 이상인 경우를 체크
}
// 계좌1에 특정종목의 수량이 있는 상태에서 HCount2가 0이고 600만원 이상 수익
if (HCount2 == 0 && PL >= 6000000 && Account1.Balance.count > 0)
{
Account1.SetBalance(Main.GetOrderCode(MarketData1.code),0);
if (Account1.Balance.position == 1)
{
var vol = Math.floor(Account1.Balance.count/2)
if (vol > 0)
{
Account2.OrderBuy(Account1.Balance.code, vol,0,1);
}
}
if (Account1.Balance.position == 2)
{
var vol = Math.floor(Account1.Balance.count/2)
if (vol > 0)
{
Account2.OrderSell(Account1.Balance.code, vol,0,1);
}
}
//HCount2는 1
HCount2 = 1; // 수익이 600만원 이상은 경우를 체크
}
//계좌1에 특정종목의 수량이 있는 상태에서 수익이 600만원 이상 발생했다가 300만원까지 떨어진 경우
if (HCount1 > 0 && HCount2 > 0 && PL<=3000000 && Account1.Balance.count > 0 )
{
//계좌2의 특정종목 잔고셋팅
Account2.SetBalance(Main.GetOrderCode(MarketData1.code),0);
if (Account2.Balance.position == 1)
{
var vol = Math.floor(Account2.Balance.count/2)
if (vol > 0)
{
Account2.OrderBuy(Account2.Balance.code, vol,0,1); // 계좌2 매도수량의 절반 정리
}
}
if (Account2.Balance.position == 2)
{
var vol = Math.floor(Account2.Balance.count/2)
if (vol > 0)
{
Account2.OrderSell(Account2.Balance.code,vol,0,1); // 계좌2 매수수량의 절반 정리
}
}
}
//계좌1에 특정종목의 수량이 있는 상태에서 수익이 300만원 이상 발생했다가 0까지 떨어진 경우
if (HCount1 > 0 && PL<=0 && Account1.Balance.count > 0)
{
//계좌2의 특정종목 잔고셋팅
Account2.SetBalance(Main.GetOrderCode(MarketData1.code),0);
if (Account2.Balance.position == 1)
{
Account2.OrderBuy(Account2.Balance.code, Account2.Balance.count,0,1); // 계좌2 매도수량 정리
}
if (Account2.Balance.position == 2)
{
Account2.OrderSell(Account2.Balance.code, Account2.Balance.count,0,1); // 계좌2 매수수량 정리
}
}
// 계좌1에 잔고가 없는 경우 매수/매도수량 정리
if (Account1.Balance.count == 0)
{
//계좌2의 특정종목 잔고셋팅
Account2.SetBalance(Main.GetOrderCode(MarketData1.code),0);
if (Account2.Balance.position == 1)
{
Account2.OrderBuy(Account2.Balance.code, Account2.Balance.count,0,1); // 계좌2 매도수량 정리
}
if (Account2.Balance.position == 2)
{
Account2.OrderSell(Account2.Balance.code, Account2.Balance.count,0,1); // 계좌2 매수수량 정리
}
}
}
}
2
2번 내용은 작성하신 내용상 별도로 수정해 드릴 부분이 없습니다.
차트에서 발생하는 신호에 따라 주문하는 부분으로
차트에서 피라미딩으로 신호가 발생하면 스팟도 Signal.signalKind == 1이 반복적으로 발생하게 됩니다.
수식에 별도로 해당붑분을 막는 코딩내용이 없습니다.
즐거운 하루되세요
> 깜피 님이 쓴 글입니다.
> 제목 : 문의드립니다.
> 안녕하세요. 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("매도주문");
}
}
}
가이드 주시면 보완해 나가겠습니다.
노고에 항상 감사드립니다.
즐거운 주말 보내세요.
예스스탁
예스스탁 답변
2021-08-25 14:49:59
안녕하세요
예스스탁입니다.
차트에 시스템 적용시 피라미딩을 다른진입신호만허용으로 설정되게 수정해 드립니다.
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));
}
ReqCount = 0;
if (Count > 0)
{
Main.SetTimer(1, 500);
}
}
function Main_OnTimer(nEventID)
{
if (nEventID == 1)
{
var TradeSet = new SystemTradeInfo(TRADE_FIXCOUNT,
1, // 거래수량
123456789, // 자산
1, // 단위수량
0, 0, CALCMETHOD_PERCENT, // 진입/청산 수수료
0, 0, CALCMETHOD_POINT, // 진입/청산 슬리피지
PYRAMIDING_ENTRY, // 피라미딩 설정여부(다른진입신호만 허용)
100000, // 최대진입수량
20); // 최대진입횟수
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, TradeSet);
Main.ReqChartEx(ChartSet,SystemSet);
Main.MessageList("확장차트생성요청:",ItemList[ReqCount]);
ReqCount = ReqCount+1;
if (ReqCount == Count)
{
Main.KillTimer(1);
Main.MessageList("종목객체생성완료");
}
}
}
//신호발생
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.MessageList("매수주문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.MessageList("매도주문");
}
}
}
즐거운 하루되세요
> 깜피 님이 쓴 글입니다.
> 제목 : Re : Re : 문의드립니다.
> 답변 감사드립니다.
한국컴퓨터 차트인데 2번 식을 운용해서 매수할 때 예스랭귀지와 예스스팟 간에 다음과 같은 차이가 발생합니다.
답글 주시는 사이에 매수식 부분을
if (Signal.signalKind == 1)// && Account1.Balance.count == 0)
이렇게 수정해서 사용해봐도 여전히 1회만 매수가 되고 있는데 다시 한 번 검토부탁드립니다.
감사합니다. 즐거운 주말 보내세요.
-------------------------------------------------------------------------------
> 예스스탁 님이 쓴 글입니다.
> 제목 : Re : 문의드립니다.
> 안녕하세요
예스스탁입니다.
1
1-1
BaNum은 수식상 불필요한 부분인것 같아 삭제했습니다.
1-2
수식에 타이머가 1초인데 한번 동작후 종료하므로 계속 감시를 하지 못합니다.
일정간격으로 반복적으로 계좌를 감시하게 구현하셔야 합니다.
1-3
수익이 3000000,6000000이상이면 반복적으로 주문이 나가게 되어 있습니다.
조건만족시 한번만 주문이 집행되게 하셔야 합니다.
1-4
수량이 홀수일경우 /2만 하면 소숫점이 발생합니다.
소숫점 제외하고 지정되도록 작성하셔야 합니다.
2로 나눠서 소숫점제외하고 수량이 지정되게 작성해 드립니다.
또한 계산에 의해 수량이 0이면 주문이 집행되지 않게 작성해 드립니다.
1-5
Account1.Balance는 Account1.SetBalance함수로
특정종목에 대해 잔고가 셋팅이 되어야 사용이 가능합니다.
Account1.SetBalance(Account1.Balance.code,0);
는 잔고가 셋팅이 되지 않았는데 해당코드로 잔고를 셋팅하게 되어 있습니다.
선물 종목의 종목객체를 추가해서 해당 객체의 종목코드로 잔고 셋팅되게 하셔야 합니다.
1-6
아래 가이드 수식 참고하셔서 수정보완해 사용하시기 바랍니다.
var HCount1 = 0;
var HCount2 = 0;
function Main_OnStart()
{
Main.MessageLog("시작")
//1초 타이머
Main.SetTimer(1, 1000);
}
function Main_OnTimer(nEventID)
{
Main.MessageList("Main_OnTimer");
//계좌 재조회
Account1.Refresh();
}
//계좌이벤트
function Main_OnU*dateAccount(sAccntNum, sItemCode, lU*dateID)
{
//계좌refresh 완료
if (Account1.number == sAccntNum && lU*dateID == 30000)
{
//현재 예탁자산총평가액과 전일예탁자산의 차이
var PL = Account1.GetBalanceETCinfo(10)-Account1.GetBalanceETCinfo(0);
//계좌1의 특정종목 잔고셋팅
Account1.SetBalance(Main.GetOrderCode(MarketData1.code),0);
//계좌1에 특정종목의 수량이 있는 상태에서 HCount1이 0이고 300만원 이상 수익인 경우
if (HCount1 == 0 && PL >= 3000000 && Account1.Balance.count > 0)
{
// 계좌1 매도일 때 매수수량의 절반을 계좌2에서 매도
if (Account1.Balance.position == 1)
{
//절반계산
var vol = Math.floor(Account1.Balance.count/2)
//전반이 1이상일때만 주문
if (vol > 0)
{
Account2.OrderBuy(Account1.Balance.code,vol,0,1);
}
}
// 계좌1 매수일 때 매도수량의 절반을 계좌2에서 매도
if (Account1.Balance.position == 2)
{
var vol = Math.floor(Account1.Balance.count/2)
if (vol > 0)
{
Account2.OrderSell(Account1.Balance.code,vol,0,1);
}
}
//HCount1는 1
HCount1 = 1; // 수익이 300만원 이상인 경우를 체크
}
// 계좌1에 특정종목의 수량이 있는 상태에서 HCount2가 0이고 600만원 이상 수익
if (HCount2 == 0 && PL >= 6000000 && Account1.Balance.count > 0)
{
Account1.SetBalance(Main.GetOrderCode(MarketData1.code),0);
if (Account1.Balance.position == 1)
{
var vol = Math.floor(Account1.Balance.count/2)
if (vol > 0)
{
Account2.OrderBuy(Account1.Balance.code, vol,0,1);
}
}
if (Account1.Balance.position == 2)
{
var vol = Math.floor(Account1.Balance.count/2)
if (vol > 0)
{
Account2.OrderSell(Account1.Balance.code, vol,0,1);
}
}
//HCount2는 1
HCount2 = 1; // 수익이 600만원 이상은 경우를 체크
}
//계좌1에 특정종목의 수량이 있는 상태에서 수익이 600만원 이상 발생했다가 300만원까지 떨어진 경우
if (HCount1 > 0 && HCount2 > 0 && PL<=3000000 && Account1.Balance.count > 0 )
{
//계좌2의 특정종목 잔고셋팅
Account2.SetBalance(Main.GetOrderCode(MarketData1.code),0);
if (Account2.Balance.position == 1)
{
var vol = Math.floor(Account2.Balance.count/2)
if (vol > 0)
{
Account2.OrderBuy(Account2.Balance.code, vol,0,1); // 계좌2 매도수량의 절반 정리
}
}
if (Account2.Balance.position == 2)
{
var vol = Math.floor(Account2.Balance.count/2)
if (vol > 0)
{
Account2.OrderSell(Account2.Balance.code,vol,0,1); // 계좌2 매수수량의 절반 정리
}
}
}
//계좌1에 특정종목의 수량이 있는 상태에서 수익이 300만원 이상 발생했다가 0까지 떨어진 경우
if (HCount1 > 0 && PL<=0 && Account1.Balance.count > 0)
{
//계좌2의 특정종목 잔고셋팅
Account2.SetBalance(Main.GetOrderCode(MarketData1.code),0);
if (Account2.Balance.position == 1)
{
Account2.OrderBuy(Account2.Balance.code, Account2.Balance.count,0,1); // 계좌2 매도수량 정리
}
if (Account2.Balance.position == 2)
{
Account2.OrderSell(Account2.Balance.code, Account2.Balance.count,0,1); // 계좌2 매수수량 정리
}
}
// 계좌1에 잔고가 없는 경우 매수/매도수량 정리
if (Account1.Balance.count == 0)
{
//계좌2의 특정종목 잔고셋팅
Account2.SetBalance(Main.GetOrderCode(MarketData1.code),0);
if (Account2.Balance.position == 1)
{
Account2.OrderBuy(Account2.Balance.code, Account2.Balance.count,0,1); // 계좌2 매도수량 정리
}
if (Account2.Balance.position == 2)
{
Account2.OrderSell(Account2.Balance.code, Account2.Balance.count,0,1); // 계좌2 매수수량 정리
}
}
}
}
2
2번 내용은 작성하신 내용상 별도로 수정해 드릴 부분이 없습니다.
차트에서 발생하는 신호에 따라 주문하는 부분으로
차트에서 피라미딩으로 신호가 발생하면 스팟도 Signal.signalKind == 1이 반복적으로 발생하게 됩니다.
수식에 별도로 해당붑분을 막는 코딩내용이 없습니다.
즐거운 하루되세요
> 깜피 님이 쓴 글입니다.
> 제목 : 문의드립니다.
> 안녕하세요. 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("매도주문");
}
}
}
가이드 주시면 보완해 나가겠습니다.
노고에 항상 감사드립니다.
즐거운 주말 보내세요.