예스스탁
예스스탁 답변
2016-02-23 13:19:30
안녕하세요
예스스탁입니다.
var Start = 0;
var BC;
var BP;
var Bcount;
var SC;
var SP;
var Scount;
var upv = 2.9;
var dnv = 0.7;
var add1, add2;
function Main_OnStart()
{
Start = 0;
Main.MessageList("시작",Start);
}
function Chart1_OnRiseSignal(Signal)
{
//차트에서 매도신호 발생
if (Signal.signalKind == 3)
{
//ATM위 행사가 갯수
var UNum = Option.uppersATM;
//ATM아래 행사가 갯수
var LNum = Option.lowersATM;
//각 행사가의 콜종목의 종목코드를 저장할 변수를 배열변수로 선언
var CallCode = new Array(UNum+LNum+1);
//각 행사가의 콜종목의 현재가를 저장할 변수를 배열변수로 선언
var CallPrice = new Array(UNum+LNum+1);
//각 행사가의 풋종목의 종목코드를 저장할 변수를 배열변수로 선언
var PutCode = new Array(UNum+LNum+1);
//각 행사가의 풋종목의 현재가를 저장할 변수를 배열변수로 선언
var PutPrice = new Array(UNum+LNum+1);
//콜종목 찾기
//콜옵션은 ATM기준 위행사가 +단계, 아래가 -단계이므로
//for문에서 LNum의 역수부터 시작해서 UNum까지 1씩 증가하면서 수행하도록 함
for (var i = -LNum; i <= UNum; i++)
{
//값이 0.7~2.9사이이면
if (Option.GetCurrent(0, i) >= dnv && Option.GetCurrent(0, i) <= upv)
{
//해당종목의 현재가를 배열변수 CallPrice의 방번호 i+LNum에 저장
CallPrice[i+LNum] = Option.GetCurrent(0, i);
//해당종목의 종목코드를 배열변수 CallCode의 방번호 i+LNum에 저장
CallCode[i+LNum] = Option.GetATMCallRecent(i);
//주의
//배열변수의 방(공간)번호은 -가 없으므로 최하단 행사가를 0번방부터
//저장하도록 작성해야 함
}
else//0.7~2.9 사이가 아니면
{
//배열변수 CallPrice의 방번호 i+LNum에 -1 저장
CallPrice[i+LNum] = -1;
//배열변수 CallCode의 방번호 i+LNum에 -1 저장
CallCode[i+LNum] = -1;
}
}
//풋종목 찾기
//풋옵션은 ATM기준 아래 행사가 +단계, 위가 -단계이므로
//for문에서 HNum의 역수부터 시작해서 LNum까지 1씩 증가하면서 수행하도록 함
for (var i = -UNum; i <= LNum; i++)
{
//값이 0.7~2.9사이이면
if (Option.GetCurrent(1, i) >= dnv && Option.GetCurrent(1, i) <= upv )
{
//해당종목의 현재가를 배열변수 PutPrice의 방번호 ii+LNum에 저장
PutPrice[i+UNum] = Option.GetCurrent(1, i);
//해당종목의 현재가를 배열변수 PutCode의 방번호 ii+LNum에 저장
PutCode[i+UNum] = Option.GetATMPutRecent(i);
}
else //2.0보다 크면
{
//배열변수 PutPrice의 방번호 ii+LNum에 -1 저장
PutPrice[i+UNum] = -1;
//배열변수 PutCode의 방번호 ii+LNum에 -1 저장
PutCode[i+UNum] = -1;
}
}
//배열변수 CallPrice의 각 배열방의 값중 가장 큰값을 찾아 CC에 저장하고
//CallCode의 동일 방번호의 값을 CallOrderCode에 저장
var CC = -1;
var CallOrderCode = -1;
for (var i = -LNum; i <= UNum; i++)
{
if (CallPrice[i+LNum] > CC)
{
CC = CallPrice[i+LNum];
CallOrderCode = CallCode[i+LNum]
}
}
//배열변수 PutPrice의 각 배열방의 값중 가장 큰값을 찾아 PP에 저장하고
//PutCode의 동일 방번호의 값을 PutOrderCode에 저장
var PP = -1;
var PutOrderCode = -1;
for (var i = -UNum; i <= LNum; i++)
{
if (PutPrice[i+UNum] > PP)
{
PP = PutPrice[i+UNum];
PutOrderCode = PutCode[i+UNum];
}
}
if (CC > 0 && PP > 0)
{
Start = -1;
SC = CallOrderCode;
SP = PutOrderCode;
Scount = Signal.count;
Account1.OrderSell(SC,Scount,Option.GetBidByCode(SC,3),0);
Account1.OrderSell(SP,Scount,Option.GetBidByCode(SP,3),0);
//주문후 타이머 셋팅(1번,5초)
Main.SetTimer(1, 5000);
add1 = false;
add2 = false;
}
}
//차트에서 매도청산신호 발생
if (Start == -1 && Signal.signalKind == 4)
{
//청산신호발생했으므로 타이머 종료
Main.KillTimer(1);
Start = 0;
//SC,SP종목 미체결 모두 취소
for (var i = 0; i < IN; i++)
{
var IN = Account1.SetUnfill(i);
if (Account1.Unfill.count > 0 &&
(Account1.Unfill.code == SC || Account1.Unfill.code == SP))
{
Account1.OrderCancel(Account1.Unfill.orderNum)
}
}
//SC 잔고 모두 청산
Account1.SetBalance(SC,0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
Account1.OrderBuy(Account1.Balance.code,Account1.Balance.count,Option.GetAskByCode(SC,3),0);
}
//SP잔고 모두 청산
Account1.SetBalance(SP,0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
Account1.OrderBuy(Account1.Balance.code,Account1.Balance.count,Option.GetAskByCode(SP,3),0);
}
}
}
function Main_OnTimer(nEventID)
{
var d = new Date();
var HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds();
//1번 타이머 동작
if (nEventID == 1)
{
//콜잔고셋팅
Account1.SetBalance(SC, 0);
//포지션과 손익저장
var SCP = Account1.Balance.position;
var SCV = Account1.Balance.current-Account1.Balance.avgUnitCost;
//풋잔고 셋팅
Account1.SetBalance(SP, 0);
//포지션과 손익저장
var SPP = Account1.Balance.position;
var SPV = Account1.Balance.current-Account1.Balance.avgUnitCost;
//추가진입
if ( HHMMSS < 120000)
{
//add1이 false이고
//콜폿 모두 매도포지션이고 평균수익이 0.1 이상이면
if (add1 == false && SCP == 1 && SPP == 1 && (SCV+SPV)/2 >= 0.1)
{
//add1을 true로 변경해서 해당 조건으로 두번 신호 발생하지 않게함
add1 = true;
//추가 매도
Account1.OrderSell(SC,Scount,Option.GetBidByCode(SC,3),0);
Account1.OrderSell(SP,Scount,Option.GetBidByCode(SP,3),0);
}
//add2가 false이고
//콜폿 모두 매도포지션이고 평균수익이 0.13 이상이면
if (add1 == false && SCP == 1 && SPP == 1 && (SCV+SPV)/2 >= 0.13)
{
//add2을 true로 변경해서 해당 조건으로 두번 신호 발생하지 않게함
add2 = true;
//추가 매도
Account1.OrderSell(SC,Scount,Option.GetBidByCode(SC,3),0);
Account1.OrderSell(SP,Scount,Option.GetBidByCode(SP,3),0);
}
}
//추가진입이 모두 없는상태(1Set만 진입후)
if (add1 == false && add2 == false)
{
if ((SCV+SPV)/2 <= -0.15)
{
//SC,SP종목 미체결 모두 취소
for (var i = 0; i < IN; i++)
{
var IN = Account1.SetUnfill(i);
if (Account1.Unfill.count > 0 &&
(Account1.Unfill.code == SC || Account1.Unfill.code == SP))
{
Account1.OrderCancel(Account1.Unfill.orderNum)
}
}
//SC 잔고 모두 청산
Account1.SetBalance(SC,0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
Account1.OrderBuy(Account1.Balance.code,Account1.Balance.count,Option.GetAskByCode(SC,3),0);
}
//SP잔고 모두 청산
Account1.SetBalance(SP,0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
Account1.OrderBuy(Account1.Balance.code,Account1.Balance.count,Option.GetAskByCode(SP,3),0);
}
//청산되었으므로 타이머 종료
Main.KillTimer(1);
}
}
//2Set 진입후
if (add1 == true && add2 == false)
{
if ((SCV+SPV)/2 <= -0.10)
{
//SC,SP종목 미체결 모두 취소
for (var i = 0; i < IN; i++)
{
var IN = Account1.SetUnfill(i);
if (Account1.Unfill.count > 0 &&
(Account1.Unfill.code == SC || Account1.Unfill.code == SP))
{
Account1.OrderCancel(Account1.Unfill.orderNum)
}
}
//SC 잔고 모두 청산
Account1.SetBalance(SC,0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
Account1.OrderBuy(Account1.Balance.code,Account1.Balance.count,Option.GetAskByCode(SC,3),0);
}
//SP잔고 모두 청산
Account1.SetBalance(SP,0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
Account1.OrderBuy(Account1.Balance.code,Account1.Balance.count,Option.GetAskByCode(SP,3),0);
}
//청산되었으므로 타이머 종료
Main.KillTimer(1);
}
}
//3Set 진입후
if (add1 == true && add2 == true)
{
if ((SCV+SPV)/2 <= -0.05)
{
//SC,SP종목 미체결 모두 취소
for (var i = 0; i < IN; i++)
{
var IN = Account1.SetUnfill(i);
if (Account1.Unfill.count > 0 &&
(Account1.Unfill.code == SC || Account1.Unfill.code == SP))
{
Account1.OrderCancel(Account1.Unfill.orderNum)
}
}
//SC 잔고 모두 청산
Account1.SetBalance(SC,0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
Account1.OrderBuy(Account1.Balance.code,Account1.Balance.count,Option.GetAskByCode(SC,3),0);
}
//SP잔고 모두 청산
Account1.SetBalance(SP,0);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
Account1.OrderBuy(Account1.Balance.code,Account1.Balance.count,Option.GetAskByCode(SP,3),0);
}
//청산되었으므로 타이머 종료
Main.KillTimer(1);
}
}
}
}
즐거운 하루되세요
> 탄젠트80 님이 쓴 글입니다.
> 제목 : 양매도 문의
> 안녕하세요~ 항상 답변 감사히 받고 있습니다.
아래식은 선물매도시 콜풋양매도, 선물매도청산시 양매도 청산 스팟식입니다.
다음과 같이 변경하고 싶습니다.
당일 양매도 전략인데요
ㅁㅁ진입
- 선물매도신호 --> 스팟 콜,풋 양매도 ---> 12시 이전이고 포지션 평균수익이 0.1P
이상이면 ---> 스팟 콜, 풋 양매도 1SET 추가 ---> 이후 12시 이전이고 포지션
평균수익(총수익/4계약) 0.13P 이상이면 ---> 스팟 콜, 풋 양매도 1SET 추가(최대3SET)
*첫진입, 추가진입하는 옵션의 종목은 항상 설정값(0.7~2.9) 사이에 있음
ㅁㅁ청산
- 1SET 양매도 진입후 포지션 평균수익이 -0.15P이상이면 양매도 청산(2계약 청산)
- 2SET 양매도 진입후 포지션 평균수익이 -0.10P이상이면 양매도 청산(4계약 청산)
- 3SET 양매도 진입후 포지션 평균수익이 -0.05P이상이면 양매도 청산(6계약 청산)
- 선물매도청산 신호시 옵션 모든 포지션 청산
- 한번 청산하면 당일 재진입 없음
ㅁ 코딩 실력이 많이 부족하오니 주석도 부탁드립니다. 진심으로 미리 감사합니다.
============================================================================
var Start = 0;
var BC;
var BP;
var Bcount;
var SC;
var SP;
var Scount;
var upv = 2.9;
var dnv = 0.7;
function Main_OnStart()
{
Start = 0;
Main.MessageList("시작",Start);
}
function Chart1_OnRiseSignal(Signal)
{
//차트에서 매도신호 발생
if (Signal.signalKind == 3)
{
//ATM위 행사가 갯수
var UNum = Option.uppersATM;
//ATM아래 행사가 갯수
var LNum = Option.lowersATM;
//각 행사가의 콜종목의 종목코드를 저장할 변수를 배열변수로 선언
var CallCode = new Array(UNum+LNum+1);
//각 행사가의 콜종목의 현재가를 저장할 변수를 배열변수로 선언
var CallPrice = new Array(UNum+LNum+1);
//각 행사가의 풋종목의 종목코드를 저장할 변수를 배열변수로 선언
var PutCode = new Array(UNum+LNum+1);
//각 행사가의 풋종목의 현재가를 저장할 변수를 배열변수로 선언
var PutPrice = new Array(UNum+LNum+1);
//콜종목 찾기
//콜옵션은 ATM기준 위행사가 +단계, 아래가 -단계이므로
//for문에서 LNum의 역수부터 시작해서 UNum까지 1씩 증가하면서 수행하도록 함
for (var i = -LNum; i <= UNum; i++)
{
//값이 0.7~2.9사이이면
if (Option.GetCurrent(0, i) >= dnv && Option.GetCurrent(0, i) <= upv)
{
//해당종목의 현재가를 배열변수 CallPrice의 방번호 i+LNum에 저장
CallPrice[i+LNum] = Option.GetCurrent(0, i);
//해당종목의 종목코드를 배열변수 CallCode의 방번호 i+LNum에 저장
CallCode[i+LNum] = Option.GetATMCallRecent(i);
//주의
//배열변수의 방(공간)번호은 -가 없으므로 최하단 행사가를 0번방부터
//저장하도록 작성해야 함
}
else//0.7~2.9 사이가 아니면
{
//배열변수 CallPrice의 방번호 i+LNum에 -1 저장
CallPrice[i+LNum] = -1;
//배열변수 CallCode의 방번호 i+LNum에 -1 저장
CallCode[i+LNum] = -1;
}
}
//풋종목 찾기
//풋옵션은 ATM기준 아래 행사가 +단계, 위가 -단계이므로
//for문에서 HNum의 역수부터 시작해서 LNum까지 1씩 증가하면서 수행하도록 함
for (var i = -UNum; i <= LNum; i++)
{
//값이 0.7~2.9사이이면
if (Option.GetCurrent(1, i) >= dnv && Option.GetCurrent(1, i) <= upv )
{
//해당종목의 현재가를 배열변수 PutPrice의 방번호 ii+LNum에 저장
PutPrice[i+UNum] = Option.GetCurrent(1, i);
//해당종목의 현재가를 배열변수 PutCode의 방번호 ii+LNum에 저장
PutCode[i+UNum] = Option.GetATMPutRecent(i);
}
else //2.0보다 크면
{
//배열변수 PutPrice의 방번호 ii+LNum에 -1 저장
PutPrice[i+UNum] = -1;
//배열변수 PutCode의 방번호 ii+LNum에 -1 저장
PutCode[i+UNum] = -1;
}
}
//배열변수 CallPrice의 각 배열방의 값중 가장 큰값을 찾아 CC에 저장하고
//CallCode의 동일 방번호의 값을 CallOrderCode에 저장
var CC = -1;
var CallOrderCode = -1;
for (var i = -LNum; i <= UNum; i++)
{
if (CallPrice[i+LNum] > CC)
{
CC = CallPrice[i+LNum];
CallOrderCode = CallCode[i+LNum]
}
}
//배열변수 PutPrice의 각 배열방의 값중 가장 큰값을 찾아 PP에 저장하고
//PutCode의 동일 방번호의 값을 PutOrderCode에 저장
var PP = -1;
var PutOrderCode = -1;
for (var i = -UNum; i <= LNum; i++)
{
if (PutPrice[i+UNum] > PP)
{
PP = PutPrice[i+UNum];
PutOrderCode = PutCode[i+UNum];
}
}
if (CC > 0 && PP > 0)
{
Start = -1;
SC = CallOrderCode;
SP = PutOrderCode;
Scount = Signal.count;
Account1.OrderSell(SC,Scount,Option.GetBidByCode(SC,3),0);
Account1.OrderSell(SP,Scount,Option.GetBidByCode(SP,3),0);
}
}
//차트에서 매도청산신호 발생
if (Start == -1 && Signal.signalKind == 4)
{
Start = 0;
Account1.OrderBuy(SC,Scount,Option.GetAskByCode(SC,3),0);
Account1.OrderBuy(SP,Scount,Option.GetAskByCode(SP,3),0);
}
}
=================================================================================