예스스탁
예스스탁 답변
2019-11-29 14:17:33
안녕하세요
예스스탁입니다.
아래 수식 내용과 주석 참고하셔서 수정보완해 사용하시기 바랍니다.
스크립트 객체설정
옵션객체추가 --> 속성에서 객체명은 WeeklyOptions, weekly옵션으로 지정
옵션객체추가 --> 속성에서 객체명은 KP200Options, KP200옵션으로 지정
계좌객체추가 --> 속성에서 객체명은 Account1 주문계좌 지정
//KP200Options KP200옵션
//WeeklyOptions Weekly
var YYYYMMDD,HHMMSS,HHMMSS1;
var WCEID,WPEID,WCENUM,WPENUM;
var WCXID,WPXID,WCXNUM,WPXNUM,WCXcount,WPXcount;
var WC,WP,Strike,Fill,MC,MP,WCXFill,WPXFill;
var EntryDay,ExitDay;
function Main_OnStart()
{
var d = new Date();
YYYYMMDD = d.getFullYear()*10000+(d.getMonth()+1)*100+d.getDate();
HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds();
Main.MessageList(HHMMSS,"|KP200옵션 잔존일 : ",KP200Options.GetRemainDays(0,0),"|Weekly옵션 잔존일 : ",WeeklyOptions.GetRemainDays(0,0));
//초기값 false
EntryDay = false;
ExitDay = false;
//Weekly옵션은 잔존일수가 7일이고 K200옵션 잔존일수 7일이 아닐때
//KP200옵션 전주 금요일은 제외
if (WeeklyOptions.GetRemainDays(0,0) == 7 && KP200Options.GetRemainDays(0,0) != 7)
{
Main.MessageList(HHMMSS,"|진입일 : ",YYYYMMDD);
//시작시간이 15시 이전일때만 동작
if (HHMMSS < 150000)
{
//Entry는 true로 변경
EntryDay = true;
//5초 타이머 셋팅(1번 타이머)
Main.SetTimer(1, 5000);
}
else
{
Main.MessageList(HHMMSS,"|진입일 기준시간이후이므로 진입안함");
}
}
//Weekly옵션은 잔존일수가 4일(월요일)이고 K200옵션 잔존일수 7일 이상일때
//KP200옵션 마지막주는 제외
if (WeeklyOptions.GetRemainDays(0,0) == 4 && KP200Options.GetRemainDays(0,0) >= 7)
{
var CheckCode = Main.GetUserValue("SellWC");
if (CheckCode != "" || !(Option1.GetCurrent(CheckCode) > 0))
{
Main.MessageList(HHMMSS,"|직전금요일 휴일 오늘(월요일) 진입 : ",YYYYMMDD);
//시작시간이 15시 이전일때만 동작
if (HHMMSS < 150000)
{
//Entry는 true로 변경
EntryDay = true;
//5초 타이머 셋팅(1번 타이머)
Main.SetTimer(1, 5000);
}
else
{
Main.MessageList(HHMMSS,"|진입일 기준시간이후이므로 진입안함");
}
}
}
//Weekly옵션 만기일이면
////Weekly옵션은 잔존일수가 1일이고 K200옵션 잔존일수 1일이 아닐때
if (WeeklyOptions.GetRemainDays(0,0) == 1 && KP200Options.GetRemainDays(0,0) != 1)
{
Main.MessageList(HHMMSS,"|청산일 : ",YYYYMMDD);
//시작시간이 14시 이전때만 동작
if (HHMMSS < 140000)
{
//Exit은 true로 변경
ExitDay = true;
WC = Main.GetUserValue("SellWC");
WP = Main.GetUserValue("SellWP");
MC = Main.GetUserValue("BuyMC");
MP = Main.GetUserValue("BuyMP");
//5초 타이머 셋팅(1번 타이머)
Main.SetTimer(1, 5000);
}
else
{
Main.MessageList(HHMMSS,"|청산일 기준시간이후이므로 진입안함");
}
}
}
function Main_OnTimer(nEventID)
{
var d = new Date();
HHMMSS1 = HHMMSS;
HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds();
//EntryDay는 true이고
if (EntryDay == true)
{
// 1번타이머가 동작하고 15시가 되면
if (nEventID == 1 && HHMMSS >= 131000 /*&& HHMMSS1 < 150000*/)
{
Main.MessageList(HHMMSS,"|진입시간");
//1번 타이머 종료
Main.KillTimer(1);
//KP200옵션 콜풋양합 중 가장 작은 행사가를 찾음
Strike = 0;
var Minv = 0;
for (var i = -KP200Options.lowersATM; i <= KP200Options.uppersATM; i++)
{
var sum = KP200Options.GetCurrent(0,i) + KP200Options.GetCurrent(1,-i);
Main.MessageList(i,sum,KP200Options.GetCurrent(0,i),KP200Options.GetCurrent(1,-i));
if (Minv == 0 ||(Minv > 0 && sum < Minv))
{
Minv = sum;
Strike = KP200Options.GetExercisePrice(0,i);
}
}
Main.MessageList(HHMMSS,"|콜풋양합 중 가장 작은 행사가 : ",Strike);
WC = WeeklyOptions.GetCodeByExercisePrice(0, Strike);
WP = WeeklyOptions.GetCodeByExercisePrice(1, Strike);
MC = KP200Options.GetCodeByExercisePrice(0, Strike);
MP = KP200Options.GetCodeByExercisePrice(1, Strike);
Main.MessageList(HHMMSS,"|해당 행사가 Weekly콜 : ",WC);
Main.MessageList(HHMMSS,"|해당 행사가 Weekly풋 : ",WP);
Main.MessageList(HHMMSS,"|해당 행사가 KP200콜 : ",MC);
Main.MessageList(HHMMSS,"|해당 행사가 KP200풋 : ",MP);
//내부파일에 매도주문한 Weekly 콜풋의 종목코드를 저장
Main.SetUserValue("SellWC",WC,1);
Main.SetUserValue("SellWP",WP,1);
//내부파일에 매수주문한 KP200 콜풋의 종목코드를 저장
Main.SetUserValue("BuyMC",MC,1);
Main.SetUserValue("BuyMP",MP,1);
//해당 행사가의 Weekly 콜풋이 있으면
if (WeeklyOptions.GetCodeByExercisePrice(0, Strike) != "" && WeeklyOptions.GetCodeByExercisePrice(1, Strike) != "")
{
//매도1호가-0.01로 5계약 매도주문
Main.MessageList(HHMMSS,"|WCEID : ",WC,WeeklyOptions.GetAsk(WC,1));
WCEID = Account1.OrderSell(WC,5,WeeklyOptions.GetAsk(WC,1)-0.01,0);
Main.MessageList(HHMMSS,"|WPEID : ",WP,WeeklyOptions.GetAsk(WP,1));
WPEID = Account1.OrderSell(WP,5,WeeklyOptions.GetAsk(WP,1)-0.01,0);
//Fill변수는 false(이후 한종목이라도 체결완료되면 true로 변경)
Fill = false;
}
}
//2번 타이머 동작
if (nEventID == 2)
{
//2번 타이머 종료
Main.KillTimer(2);
//Weekly콜 진입주문번호로 미체결 객체 셋팅
Account1.SetUnfill(WCENUM);
//미체결 수량이 있고
if (Account1.Unfill.count > 0)
{
var RP = WeeklyOptions.GetAsk(WC,1)-0.01;
//매도1호가-0.01이 주문가격과 다르면
if (RP != Account1.Unfill.price)
{
//매도1호가-0.01로 정정주문
WCEID = Account1.OrderReplacePrice(WCENUM,RP);
}
}
}
//3번 타이머 동작
if (nEventID == 3)
{
//3번 타이머 종료
Main.KillTimer(3);
//Weekly풋 진입주문번호로 미체결 객체 셋팅
Account1.SetUnfill(WPENUM);
//미체결 수량이 있고
if (Account1.Unfill.count > 0)
{
//매도1호가-0.01이 주문가격과 다르면
var RP = WeeklyOptions.GetAsk(WP,1)-0.01;
if (RP != Account1.Unfill.price)
{
//매도1호가-0.01로 정정주문
WPEID = Account1.OrderReplacePrice(WPENUM,RP);
}
}
}
}
//ExitDay은 true이고 14시가 되면
if (ExitDay == true && nEventID == 1 && HHMMSS >= 140000 && HHMMSS1 < 140000)
{
//1번 타이머 종료
Main.KillTimer(1);
//WC종목의 잔고셋팅
Account1.SetBalanceItem(WC,0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
WCXcount = Account1.Balance.count;
WCXFill = false;
//현재가+0.2로 매도포지션 청산
WCXID = Account1.OrderBuy(Account1.Balance.code,WCXcount,WeeklyOptions.GetCurrent(Account1.Balance.code)+0.2,0);
}
//WP종목의 잔고셋팅
Account1.SetBalanceItem(WP,0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
WPXcount = Account1.Balance.count;
WPXFill = false;
//현재가+0.2로 매도포지션 청산
WCXID = Account1.OrderBuy(Account1.Balance.code,WPXcount,WeeklyOptions.GetCurrent(Account1.Balance.code)+0.2,0);
}
}
}
function Main_OnOrderResponse(OrderResponse)
{
if (EntryDay == true)
{
//Weekly콜 진입주문응답이 수신되면
if (OrderResponse.orderID == WCEID)
{
//Weekly콜 진입주문번호 저장
WCENUM = OrderResponse.orderNum;
//5초 타이머 셋팅(2번 타이머)
Main.SetTimer(2, 5000);
}
//Weekly풋 진입주문응답이 수신되면
if (OrderResponse.orderID == WPEID)
{
//Weekly풋 진입주문번호 저장
WPENUM = OrderResponse.orderNum;
//5초 타이머 셋팅(3번 타이머)
Main.SetTimer(3, 5000);
}
}
if (ExitDay == true)
{
//Weekly콜 청산주문응답이 수신되면
if (OrderResponse.orderID == WCXID)
{
//Weekly콜 청산주문번호 저장
WCXNUM = OrderResponse.orderNum;
}
//Weekly풋 청산주문응답이 수신되면
if (OrderResponse.orderID == WPXID)
{
//Weekly풋 청산주문번호 저장
WPXNUM = OrderResponse.orderNum;
}
}
}
function Main_OnNotifyFill(NotifyFill)
{
if (EntryDay == true)
{
//weekly콜 진입주문이 체결완료되면
if (NotifyFill.orderNum == WCENUM)
{
//Weekly콜 진입주문번호로 미체결 셋팅
Account1.SetUnfill(WCENUM);
//미체결 수량이 없으면(전량체결)
if (Account1.Unfill.count == 0 && Fill == false)
{
//Fill변수는 true로 변경
Fill = true;
//매수주문
WCEID = Account1.OrderBuy(MC,5,KP200Options.GetCurrent(MC,1)+0.2,0);
WPEID = Account1.OrderBuy(MP,5,KP200Options.GetCurrent(MP,1)+0.2,0);
}
}
//weekly풋 진입주문이 체결완료되면
if (NotifyFill.orderNum == WPENUM)
{
//Weekly풋 진입주문번호로 미체결 셋팅
Account1.SetUnfill(WPENUM);
//미체결 수량이 없으면(전량체결)
if (Account1.Unfill.count == 0 && Fill == false)
{
//Fill변수는 true로 변경
Fill = true;
//현재가+0.2로 5계약 매수주문
WCEID = Account1.OrderBuy(MC,5,KP200Options.GetCurrent(MC,1)+0.2,0);
WPEID = Account1.OrderBuy(MP,5,KP200Options.GetCurrent(MP,1)+0.2,0);
}
}
}
if (ExitDay == true)
{
//weekly콜 청산주문이 체결완료되면
if (NotifyFill.orderNum == WCXNUM)
{
//Weekly콜 진입주문번호로 미체결 셋팅
Account1.SetUnfill(WCXNUM);
//미체결 수량이 없으면(전량체결)
if (Account1.Unfill.count == 0 && WCXFill == false)
{
//WCXFill변수는 true로 변경
WCXFill = true;
if (WCXFill == true && WPXFill == true )
{
//KP200옵션 콜풋 현재가-0.2로 5계약 청산주문(매도)
MCXID = Account1.OrderSell(MC,WCXcount,KP200Options.GetCurrent(MC,1)-0.2,0);
MPXID = Account1.OrderSell(MP,WPXcount,KP200Options.GetCurrent(MP,1)-0.2,0);
}
}
}
//weekly풋 청산주문이 체결완료되면
if (NotifyFill.orderNum == WPXNUM)
{
//Weekly풋 진입주문번호로 미체결 셋팅
Account1.SetUnfill(WPXNUM);
//미체결 수량이 없으면(전량체결)
if (Account1.Unfill.count == 0 && WPXFill == false)
{
WPXFill = true;
if (WCXFill == true && WPXFill == true )
{
//KP200옵션 콜풋 현재가-0.2로 5계약 청산주문(매도)
MCXID = Account1.OrderSell(MC,WCXcount,KP200Options.GetCurrent(MC,1)-0.2,0);
MPXID = Account1.OrderSell(MP,WPXcount,KP200Options.GetCurrent(MP,1)-0.2,0);
}
}
}
}
}
즐거운 하루되세요
> 새로운세상 님이 쓴 글입니다.
> 제목 : 만기일 차월물, 위크리 차주물 거래
> 안녕하세요
다음 수식 부탁드립니다
K200 월물옵션 및 위크리옵션의 만기일에 차월물과 차주물 매매에 관련된 사항입니다
객체 및 변수 등 설정해야 할 부분이 있다면 같이 부탁드립니다.
<< K200 월물옵션의 잔존일수=1일 or 위크리 잔존일수=1일인 경우 : 차월물, 신규 위크리물 거래 >>
1) 15:00 기준으로,
K200 월물옵션 당월물 중 동일 행사가의 콜과 풋 양합이 가장 작은 행사가의 콜과 풋의 행사가를 찾음 <===== 콜,풋 행사가 같음
2) 1)의 K200 당월물 콜,풋과 동일한 행사가의
새로 생성된 K200 weekly옵션 콜과 풋을 각각 5계약씩 Ask(1)-0.01 로 매도 <===== 위크리 콜,풋 행사가 같음
** 새로 생성된 위크리 옵션이란, 월물만기 1일의 경우 새로 생성된 위크리
그리고 이외에 위크리만기 1일의 경우 2개의 위크리중 새로 생선된 것을 의미함
3) 2)의 매도주문 후 5초 단위로 가장 낮은 매도호가를 check하여,
콜과 풋 각각 현재 매도주문가와 동일하면 유지하고
그렇지 않으면 위 아래로 미체결수량 '가장 낮은 매도호가 - 0.01'로 정정 계속
(check시 매도호가의 상태에 따라 주문가가 올라가거나 내려감)
4) 이상에서 위크리 차주물 체결이 완료되면,
K200 월물옵션 차월물 중 위크리와 동일 행사가의 콜과 풋
각각 5계약씩 현재가+0.2 로 매수 <===== 위크리, 월물 행사가 같음
(위크리 콜,풋 어느쪽이든 체결완료 되는대로, 차월물 콜,풋 매수주문)
<< 금요일 or 이전 금요일이 영업일이 아니었다면 월요일 >>
5) 14:00 기준으로 계좌간고에 weekly옵션 콜 또는 풋이 있다면, 잔고 수량을 현재가+0.2 로 매도청산
6) 5)의 체결이 완료되면, 청산된 위크리와 동일한 행사가의 당월물 콜,풋을
청산된 위크리 수량과 동일 수량으로 현재가-0.2 로 매수청산
이상입니다
감사합니다 !!