매번 도움을 받고 스팟을 잘 사용하고 있습니다. 감사합니다.
지금 사용하고 있는 수식은 아래와 같습니다. 몇 가지 수정을 좀 했으면 하는데 가능한지요.
(수정하고 싶은 내용은)
선물 진입 신호시 옵션 매도로 진입을 하려고 하는데 증거금이 부족할 때 입니다.
(방법1)
옵션 매도 대신 매수로 진입하는 방법
(방법2)
진입되어 있는 옵션 매도 포지션에서 외가 매수를 해서 증거금을 확보후 옵션 매도로 진입하는 방법입니다.
예) 진입되어 있는 포지션 - 풋 270 매도 1계약
진입하려고 하는 포지션 풋 267 매도 1계약 (하지만 증거금 부족)
증거금 확보를 위해 외가 풋 245 매수 진입 (0.04 ~ 0.07 정도의 외가)
증거금이 학보된 후 풋 267 매도 진입
위와 같이 수식 좀 부탁드립니다.
var Start;
var UNum; var LNum;
var CallCode;
var CallPrice;
var PutCode;
var PutPrice;
var CC; var PP;
var CallOrderCode;
var PutOrderCode;
function Main_OnStart()
{
Start = 0;
}
//차트에서 신호가 발생
function Chart1_OnRiseSignal(Signal)
{
//Buy신호이면
if (Signal.signalKind == 1)
{
Start = 1;
//옵션 1.0 이하 종목 중 1에 가장 높은 가격을 가지는 콜/풋 종목을 찾음
UNum = Option.uppersATM;
LNum = Option.lowersATM;
CallCode = new Array(UNum+LNum+1);
CallPrice = new Array(UNum+LNum+1);
PutCode = new Array(UNum+LNum+1);
PutPrice = new Array(UNum+LNum+1);
// 콜종목 찾기
for (var i = -LNum; i <= UNum; i++)
{
//값이 1.0 이하이면
if (Option.GetCurrent(0, i) <= Price)
{
CallPrice[i+LNum] = Option.GetCurrent(0, i);
CallCode[i+LNum] = Option.GetATMCallRecent(i);
}
else //값이 1.0 보다 크면
{
CallPrice[i+LNum] = -1;
CallCode[i+LNum] = -1;
}
}
//풋종목 찾기
for (var ii = -UNum; ii <= LNum; ii++)
{
if (Option.GetCurrent(1, ii) <= Price )
{
PutPrice[ii+UNum] = Option.GetCurrent(1, ii);
PutCode[ii+UNum] = Option.GetATMPutRecent(ii);
}
else //값이 1.0 보다 크면
{
PutPrice[ii+UNum] = -1;
PutCode[ii+UNum] = -1;
}
}
CC = -1;
CallOrderCode = -1;
for (var iii = -LNum; iii <= UNum; iii++)
{
if (CallPrice[iii+LNum] > CC)
{
CC = CallPrice[iii+LNum];
CallOrderCode = CallCode[iii+LNum];
}
}
PP = -1;
PutOrderCode = -1;
for (var iiii = -UNum; iiii <= LNum; iiii++)
{
if (PutPrice[iiii+UNum] > PP)
{
PP = PutPrice[iiii+UNum];
PutOrderCode = PutCode[iiii+UNum];
}
}
//콜매수
if (CC > -1)
Account1.OrderBuy(CallOrderCode, CBqt, Option.GetAskByCode(CallOrderCode, 5),0);
//풋매도
if (PP > -1)
Account1.OrderSell(PutOrderCode, PSqt, Option.GetBidByCode(PutOrderCode, 5),0);
}
if (Signal.signalKind == 2 && Start == 1)
{
Account1.SetBalanceItem(CallOrderCode, 0);
if(Account1.Balance.count >0 && Account1.Balance.position==2)
Account1.OrderSell(CallOrderCode, Math.min(Account1.Balance.count, CBqt), Option.GetBidByCode(CallOrderCode, 5), 0);
// Account1.OrderSell(CallOrderCode, CBqt, Option.GetBidByCode(CallOrderCode, 5), 0);
Account1.SetBalanceItem(PutOrderCode, 0);
if(Account1.Balance.count >0 && Account1.Balance.position==1)
Account1.OrderBuy(PutOrderCode, Math.min(Account1.Balance.count, PSqt), Option.GetAskByCode(PutOrderCode, 5), 0);
// Account1.OrderBuy(PutOrderCode, PSqt, Option.GetAskByCode(PutOrderCode, 5), 0);
}
//Sell신호이면
if (Signal.signalKind == 3)
{
Start = 1;
//옵션 1.0 이상 종목 중 1에 가장 가까운 가격을 가지는 콜/풋 종목을 찾음
UNum = Option.uppersATM;
LNum = Option.lowersATM;
CallCode = new Array(UNum+LNum+1);
CallPrice = new Array(UNum+LNum+1);
PutCode = new Array(UNum+LNum+1);
PutPrice = new Array(UNum+LNum+1);
//콜종목 찾기
for (var i = -LNum; i <= UNum; i++)
{
if (Option.GetCurrent(0, i) <= Price)
{
CallPrice[i+LNum] = Option.GetCurrent(0, i);
CallCode[i+LNum] = Option.GetATMCallRecent(i);
}
else//값이 1.0보다 크면
{
CallPrice[i+LNum] = -1;
CallCode[i+LNum] = -1;
}
}
//풋종목 찾기
for (var ii = -UNum; ii <= LNum; ii++)
{
if (Option.GetCurrent(1, ii) <= Price )
{
PutPrice[ii+UNum] = Option.GetCurrent(1, ii);
PutCode[ii+UNum] = Option.GetATMPutRecent(ii);
}
else// 값이 1.0보다 크면
{
PutPrice[ii+UNum] = -1;
PutCode[ii+UNum] = -1;
}
}
CC = -1;
CallOrderCode = -1;
for (var iii = -LNum; iii <= UNum; iii++)
{
if (CallPrice[iii+LNum] > CC)
{
CC = CallPrice[iii+LNum];
CallOrderCode = CallCode[iii+LNum]
}
}
PP = -1;
PutOrderCode = -1;
for (var iiii = -UNum; iiii <= LNum; iiii++)
{
if (PutPrice[iiii+UNum] > PP)
{
PP = PutPrice[iiii+UNum];
PutOrderCode = PutCode[iiii+UNum];
}
}
//콜매도
if (CC > -1)
Account1.OrderSell(CallOrderCode, CSqt, Option.GetBidByCode(CallOrderCode, 5),0);
//풋매수
if (PP > -1)
Account1.OrderBuy(PutOrderCode, PBqt, Option.GetAskByCode(PutOrderCode, 5),0);
}
//exitshort신호 발생하면
if (Signal.signalKind == 4 && Start == 1)
{
Account1.SetBalanceItem(CallOrderCode, 0);
if(Account1.Balance.count >0 && Account1.Balance.position==1)
Account1.OrderBuy(CallOrderCode, Math.min(Account1.Balance.count, CSqt), Option.GetAskByCode(CallOrderCode, 5), 0);
// Account1.OrderBuy(CallOrderCode, CSqt, Option.GetAskByCode(CallOrderCode, 5), 0);
Account1.SetBalanceItem(PutOrderCode, 0);
if(Account1.Balance.count >0 && Account1.Balance.position==2)
Account1.OrderSell(PutOrderCode, Math.min(Account1.Balance.count, PBqt), Option.GetBidByCode(PutOrderCode, 5), 0);
// Account1.OrderSell(PutOrderCode, PBqt, Option.GetBidByCode(PutOrderCode, 5), 0);
}
}
답변 1
예스스탁
예스스탁 답변
2013-10-28 19:58:36
안녕하세요
예스스탁입니다.
아래 내용 참고하셔서 수정/보완해 사용하시기 바랍니다.
해당 부분은 주문이후의 동작들이므로 저희쪽에서 테스트를 해드릴수 없고
사용자분이 실제 테스트 하시면서 식을 완성해 가셔야 합니다.
1.
증거금 부족의 주문오류 메세지는 주문 후 주문응답을 받아야 알수 있습니다
그러므로 아래식은 아래와 같은 흐름으로 작성된 식입니다.
1. 주문 후 주문아이디 저장
2. 주문응답 수신시에 해당 주문응답의 아이디와 저장한 주문아이디가 동일한 지 확인 후
3. 동일주문아이디이면 주문오류여부 확인하고 오류이면 해당 오류에 부족액이라는 메세지가 있는지 확인해서
4. 부족액이라는 메세지가 있으면 매수로 주문
즉 주문 후 주문응답이벤트 수신시에 증거금 부족을 체크하셔서
이후의 내용에 대해 제어하시면 됩니다.
buy신호시 특정 풋옵션을 매도하고
주문응답시에 오류메세지 체크해서
증거금 부족이면 매수로 전환합니다.
var Start;
var CC;
var PutOrderCode;
var PutSellID;
function Main_OnStart()
{
Start = 0;
}
//차트에서 신호가 발생
function Chart1_OnRiseSignal(Signal)
{
//Buy신호이면
if (Signal.signalKind == 1)
{
Start = 1;
//옵션 1.0 이하 종목 중 1에 가장 높은 가격을 가지는 풋 종목을 찾음
var UNum = Option.uppersATM;
var LNum = Option.lowersATM;
var PutCode = new Array(UNum+LNum+1);
var PutPrice = new Array(UNum+LNum+1);
//풋종목 찾기
for (var i = -UNum; i <= LNum; i++)
{
if (Option.GetCurrent(1, i) <= Price )
{
PutPrice[i+UNum] = Option.GetCurrent(1, i);
PutCode[i+UNum] = Option.GetATMPutRecent(i);
}
else //값이 1.0 보다 크면
{
PutPrice[i+UNum] = -1;
PutCode[i+UNum] = -1;
}
}
PP = -1;
PutOrderCode = -1;
for (var j = -UNum; j <= LNum; j++)
{
if (PutPrice[j+UNum] > PP)
{
PP = PutPrice[j+UNum];
PutOrderCode = PutCode[j+UNum];
}
}
//풋매도(해당 주문의 내부 아이디를 CallSellID에 저장)
if (PP > -1)
{
PutSellID = Account1.OrderSell(PutOrderCode, 1, Option.GetBidByCode(PutOrderCode, 5),0);
}
}
}
//주문 응답 수신
function Main_OnOrderResponse(OrderResponse)
{
//현재 수신받은 주문응답이 CallSellID와 같으면
if (PutSellID == OrderResponse.orderID)
{
//주문 오류 저장
var OrderError = OrderResponse.error;
Main.MessageList(OrderError);
//오류 메시지의 길이(오류메시지가 없으면 0)
var error1 = OrderError.length;
//부족액이라는 단어가 포함되어 있는 그 위치를 찾음(없으면 -1)
var error2 = OrderError.search("부족액");
//오류메세지가 발생하고 부족액이라는 문자열이 포함되어 있으면
if (error1 > 0 && error2 > -1)
{
Main.MessageList("오류메세지길이 :",error1,"문자열검색",error2);
//해당 풋종목을 매수
Account1.OrderBuy(PutOrderCode, 1, Option.GetAskByCode(PutOrderCode, 5),0);
}
}
}
2번
아래와 같은 흐름으로 작성된 식입니다.
1. Buy신호시 특정 콜옵션 매도주문 후 주문아이디(1) 저장
2. 주문응답 수신시에 현재 주문응답의 아이디와 저장한 주문아이디(1)가 같으면
3. 주문오류여부 확인하고 해당 오류에 부족액이라는 메세지가 있으면
4. 0.04~0.07사이 종목중 가장 가격이 작은 종목에 대해 매수주문하고 주문아이디(2) 저장
5. 주문응답 수신시에 현재 주문응답의 아이디와 저장한 주문아이디(2)가 같으면
6. 1의 종목 매도주문
var Start;
var PP;
var PutOrderCode;
var PutSellID;
var rePP;
var rePutOrderCodeB;
var rePutBuyID;
var rePutBuyNum
function Main_OnStart()
{
Start = 0;
}
//차트에서 신호가 발생
function Chart1_OnRiseSignal(Signal)
{
//Buy신호이면
if (Signal.signalKind == 1)
{
Start = 1;
//옵션 1.0 이하 종목 중 1에 가장 높은 가격을 가지는 풋 종목을 찾음
var UNum = Option.uppersATM;
var LNum = Option.lowersATM;
var PutCode = new Array(UNum+LNum+1);
var PutPrice = new Array(UNum+LNum+1);
//풋종목 찾기
for (var i = -UNum; i <= LNum; i++)
{
if (Option.GetCurrent(1, i) <= 1.0 )
{
PutPrice[i+UNum] = Option.GetCurrent(1, i);
PutCode[i+UNum] = Option.GetATMPutRecent(i);
}
else //값이 1.0 보다 크면
{
PutPrice[i+UNum] = -1;
PutCode[i+UNum] = -1;
}
}
PP = -1;
PutOrderCode = -1;
for (var j = -UNum; j <= LNum; j++)
{
if (PutPrice[j+UNum] > PP)
{
PP = PutPrice[j+UNum];
PutOrderCode = PutCode[j+UNum];
}
}
//풋매도(해당 주문의 내부 아이디를 PutSellID에 저장)
if (PP > -1)
{
PutSellID = Account1.OrderSell(PutOrderCode, 1, Option.GetBidByCode(PutOrderCode, 5),0);
}
}
}
//주문 응답 수신
function Main_OnOrderResponse(OrderResponse)
{
//현재 수신받은 주문응답이 CallSellID와 같으면
if (PutSellID == OrderResponse.orderID)
{
//주문 오류 저장
var OrderError = OrderResponse.error;
Main.MessageList(OrderError);
//오류 메시지의 길이(오류메시지가 없으면 0)
var error1 = OrderError.length;
//부족액이라는 단어가 포함되어 있는 그 위치를 찾음(없으면 -1)
var error2 = OrderError.search("부족액");
//오류메세지가 발생하고 부족액이라는 문자열이 포함되어 있으면
if (error1 > 0 && error2 > -1)
{
//풋 0.04~0.07 사이의 종목중 가장 가격이 작은 풋종목 선정
var UNum = Option.uppersATM;
var LNum = Option.lowersATM;
var PutCode = new Array(UNum+LNum+1);
var PutPrice = new Array(UNum+LNum+1);
//풋종목 찾기
for (var k = -UNum; k <= LNum; k++)
{
if (Option.GetCurrent(1, k) >= 0.04 && Option.GetCurrent(1, k) <= 0.07 )
{
PutPrice[k+UNum] = Option.GetCurrent(1, k);
PutCode[k+UNum] = Option.GetATMPutRecent(k);
}
else
{
PutPrice[k+UNum] = 9999999999;
PutCode[k+UNum] = 9999999999;
}
}
rePP = 9999999999;
rePutOrderCode = 9999999999;
for (var h = -UNum; h <= LNum; h++)
{
if (PutPrice[h+UNum] > rePP)
{
rePPP = PutPrice[h+UNum];
rePutOrderCode = PutCode[h+UNum];
}
}
//풋매수(해당 주문의 내부 아이디를 rePutSellID에 저장)
if (rePP < 9999999999)
{
rePutBuyID = Account1.OrderBuy(rePutOrderCode, 1, Option.GetAskByCode(rePutOrderCode, 5),0);
}
}
}
//rePutSellID와 같은 아이디의 주문응답이 들어오면 주문번호 저장
if (rePutBuyID == OrderResponse.orderID)
{
rePutBuyNum = OrderResponse.orderNum;
}
}
function Main_OnNotifyFill(NotifyFill)
{
//rePutSellNum주문번호와 같은 주문번호이면 PutOrderCode종목 매도주
if (NotifyFill.orderNum == rePutBuyNum)
{
Account1.OrderSell(PutOrderCode, 1, Option.GetBidByCode(PutOrderCode, 5),0);
}
}
즐거운 하루되세요
> 루이001 님이 쓴 글입니다.
> 제목 : 문의 드립니다.
> 매번 도움을 받고 스팟을 잘 사용하고 있습니다. 감사합니다.
지금 사용하고 있는 수식은 아래와 같습니다. 몇 가지 수정을 좀 했으면 하는데 가능한지요.
(수정하고 싶은 내용은)
선물 진입 신호시 옵션 매도로 진입을 하려고 하는데 증거금이 부족할 때 입니다.
(방법1)
옵션 매도 대신 매수로 진입하는 방법
(방법2)
진입되어 있는 옵션 매도 포지션에서 외가 매수를 해서 증거금을 확보후 옵션 매도로 진입하는 방법입니다.
예) 진입되어 있는 포지션 - 풋 270 매도 1계약
진입하려고 하는 포지션 풋 267 매도 1계약 (하지만 증거금 부족)
증거금 확보를 위해 외가 풋 245 매수 진입 (0.04 ~ 0.07 정도의 외가)
증거금이 학보된 후 풋 267 매도 진입
위와 같이 수식 좀 부탁드립니다.