예스스탁
예스스탁 답변
2018-08-23 11:18:49
안녕하세요
예스스탁입니다.
1
첨부하신 그림은 시험적용입니다.
시험적용은 실제 주문이 나가는 것이 아니므로 잔고에 수량이 없습니다.
그러므로 매도는 분할매도할 주문수량이 없으므므로 0으로 찍히는 것입니다.
스팟은 시뮬레이션이 되는 프로그램이 아닙니다.
모두 실제 잔고와 실제주문을 집행하게 됩니다.
2
첨부된 그림과 같이 NH투자증권 모의투자로 해당식 테스트 해보았지만
모두 정상적으로 주문이 집행되고 있습니다.
3
스팟은 자바스크립트로 코딩가능한 분께 제공하는 프로그램입니다.
모두 실시간에서만 동작하고 실계좌와 연동되는 내용이 많아
저희가 식을 완전히 검증해서 올려드리는 내용은 아닙니다.
스팟의 수식답변은 단순히 사용자분이 직접작성하기 위한 가이드 입니다
가이드를 참고하셔서 이후 내용은 사용자분이 수정보완해 완성하셔야 합니다
즐거운 하루되세요
> 택군아 님이 쓴 글입니다.
> 제목 : 수식에 에러가 발생했습니다. 수정부탁합니다.
> 안녕하세요.
앞에 문의번호 1740번 문의 관련입니다.
보내주신 수정한 수식을 예스트레이드로 돌려보니
아래와 같은 에러가 발생되네요.
수정부탁 드립니다.
<에러발생내역>
1. 종목1(코덱스코스닥150인버스)매도시 외부입력변수에 지정된 분할매도횟수(초기값 3회 분할매도) 만큼 매도가 되어야하나, 매도횟수는 3회 매도 주문이 정상적으로 나가고 있으나, 주문수량이 0 로 나가면서 매도체결이 되지 않고 매도처리 되어야 할 주식수량이 잔고로 남아 있습니다.
예시) 인버스가 1회29주식 3회에 걸쳐 87주가 분할매수되었으며, 15:00시에 3회에 걸쳐 1회29주식 87주가 전량분할매도 되어야 하나, 3회에 걸쳐 주문은 나가고 있으나 주문수랑이 0 로 나가고 있어 분할매도가 되지 않고 87주가 잔고로 잔고로 남아 있음.(첨부파일 1참고)
2. 종목2(코덱스코스닥150레버리지)매도시 외부입력변수에 지정된 분할매도횟수(초기값3회) 만큼 매도가 되어야하나, 매도횟수는 3회 매도 주문이 정상적으로 나가고 있으나 1회 매도주문수량이 많이 주문이 나갑니다.
예시) 레버리지가 1회 14주식 3회에 걸쳐 42주가 분할매수 되었으며, 09:00시에 3회에 걸쳐 1회 14주식 42주가 분할매도가 되어야, 1회에 걸쳐 24주식 3회에 걸쳐 72주를 매도하고 있습니다.
3. 아래는 보내주신 스팟코딩 자료입니다.
수정부탁합니다
var HHMMSS,HHMMSS1;
var count1, count2, count3, count4, count5;
var M1;
function Main_OnStart()
{
//1번 타이머 5초간격, 지정한 간격으로 시간체크하기 위한 용도
Main.SetTimer(1, 5000);
}
function Main_OnTimer(nEventID)
{
var d = new Date();
HHMMSS1 = HHMMSS;
HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds();
//종목1(MarketData1)
// 첫매수
if (nEventID == 1 && HHMMSS >= 매수시간1 && HHMMSS1 < 매수시간1)
{
//지정한 금액만큼 매도3호가로 매수주문
var BuyPrice1 = MarketData1.Ask(3);
var Bvol1 = Math.floor(매수금액1/BuyPrice1);
Account1.OrderBuy(Main.GetOrderCode(MarketData1.code),Bvol1,BuyPrice1,0);
if (분할매수횟수1 >= 2)
{
//2번 타이머(종목1 추가매수 간격)
Main.SetTimer(2, 분할매수시간간격1*1000);
count2 = 1;
}
}
//2번타이머 동작
//종목1(MarketData1) 추가매수(첫매수 후 N초 단위로)
if (nEventID == 2)
{
//지정한 분할횟수보다 작으면
if (count2 < 분할매수횟수1)
{
//타이머 동작횟수 카운트
count2 = count2+1;
//추가 매수 실행
var BuyPrice1 = MarketData1.Ask(3);
var Bvol1 = Math.floor(매수금액1/BuyPrice1);
Account1.OrderBuy(Main.GetOrderCode(MarketData1.code),Bvol1,BuyPrice1,0);
}
//지정한 분할횟수에 도달하면
if (count2 == 분할매수횟수1)
{
//2번 타이머 종료
Main.KillTimer(2);
}
}
//종목1(MarketData1) 첫매도
if (nEventID == 1 && HHMMSS >= 매도시간1 && HHMMSS1 < 매도시간1)
{
//종목1에 대한 매수 미체결 모두 취소
var num1 = Account1.GetTheNumberOfUnfills()
for(var i = 1 ; i < num1 ; i++)
{
Account1.SetUnfill(i);
if (Account1.Unfill.orderKind == 2 && Account1.Unfill.count > 0 &&
Account1.Unfill.code == MarketData1.code)
{
Account1.OrderCancel(Account1.Unfill.orderNum);
}
}
//종목1 잔고셋팅
Account1.SetBalance(Main.GetOrderCode(MarketData1.code), 0);
//잔고수량
Xvol1 = Account1.Balance.count;
if (분할매도횟수1 >= 2)
{
var V1 = Math.floor(Xvol1/분할매도횟수1);
Xvol11 = Xvol1 - V1*(분할매도횟수1-1);
Xvol12 = V1;
}
else
{
Xvol11 = Xvol1;
}
var SellPrice1 = MarketData1.Bid(3);
Account1.OrderSell(Main.GetOrderCode(MarketData1.code),Xvol11,SellPrice1,0);
if (분할매도횟수1 >= 2)
{
//3번 타이머,10초 타이머(분할매도 간격)
Main.SetTimer(3, 10000);
count3 = 1;
}
}
//종목1(MarketData1) 추가매수(첫매수 후 N초 단위로)
if (nEventID == 3)
{
if (count3 < 분할매도횟수1)
{
count3 = count3+1;
var SellPrice1 = MarketData1.Bid(3);
Account1.OrderSell(Main.GetOrderCode(MarketData1.code),Xvol12,SellPrice1,0);
}
if (count3 == 분할매도횟수1)
{
Main.KillTimer(3);
}
}
//종목2(MarketData2)
// 첫매수
if (nEventID == 1 && HHMMSS >= 매수시간2 && HHMMSS1 < 매수시간2)
{
//지정한 금액만큼 매도3호가로 매수주문
var BuyPrice2 = MarketData2.Ask(3);
var Bvol2 = Math.floor(매수금액2/BuyPrice2);
Account1.OrderBuy(Main.GetOrderCode(MarketData2.code),Bvol2,BuyPrice2,0);
if (분할매수횟수2 >= 2)
{
//2번 타이머(종목1 추가매수 간격)
Main.SetTimer(4, 분할매수시간간격2*1000);
count4 = 1;
}
}
//2번타이머 동작
//종목2(MarketData2) 추가매수(첫매수 후 N초 단위로)
if (nEventID == 4)
{
//카운트 값이 지정한 분할횟수 미만이면
if (count4 < 분할매수횟수2)
{
//타이머 동작횟수 카운트
count4 = count4+1;
//추가 매수 실행
var BuyPrice2 = MarketData2.Ask(3);
var Bvol2 = Math.floor(매수금액2/BuyPrice2);
Account1.OrderBuy(Main.GetOrderCode(MarketData2.code),Bvol2,BuyPrice2,0);
}
//지정한 분할횟수에 도달하면
if (count4 == 분할매수횟수1)
{
//4번 타이머 종료
Main.KillTimer(4);
}
}
//종목2(MarketData2) 첫매도
if (nEventID == 1 && HHMMSS >= 매도시간2 && HHMMSS1 < 매도시간2)
{
//종목2에 대한 매수 미체결 모두 취소
var num1 = Account1.GetTheNumberOfUnfills()
for(var i = 1 ; i < num1 ; i++)
{
Account1.SetUnfill(i);
if (Account1.Unfill.orderKind == 2 && Account1.Unfill.count > 0 &&
Account1.Unfill.code == MarketData2.code)
{
Account1.OrderCancel(Account1.Unfill.orderNum);
}
}
//종목2 잔고셋팅
Account1.SetBalance(Main.GetOrderCode(MarketData2.code), 0);
//잔고수량
Xvol2 = Account1.Balance.count;
//분할매도횟수가 2이상일때
if (분할매도횟수2 >= 2)
{
//잔고수량을 지정한 횟수로 나누어 1회 주문할 수량 계산
var V2 = Math.floor(Xvol2/분할매도횟수2);
Xvol21 = Xvol2 - V2*(분할매도횟수2-1);
Xvol22 = V2;
}
else
{
Xvol21 = Xvol2;
}
var SellPrice2 = MarketData2.Bid(3);
Account1.OrderSell(Main.GetOrderCode(MarketData2.code),Xvol21,SellPrice2,0);
if (분할매도횟수2 >= 2)
{
//3번 타이머,10초 타이머(분할매도 간격)
Main.SetTimer(5, 10000);
//횟수 카운트 변수는 초기값 1
count5 = 1;
}
}
//종목1(MarketData2) 추가매수(첫매수 후 N초 단위로)
if (nEventID == 5)
{
//카운트 값이 분할매도횟수2 미만이면
if (count5 < 분할매도횟수2)
{
//타이저 동작할때 마다 1씩 증가
count5 = count5+1;
//추가매도 실행
var SellPrice2 = MarketData2.Bid(3);
Account1.OrderSell(Main.GetOrderCode(MarketData2.code),Xvol22,SellPrice2,0);
}
//카운트 값이 분할매도횟수와 같이면
if (count5 == 분할매도횟수2)
{
//5번타이머 종
Main.KillTimer(5);
}
}
}