예스스탁
예스스탁 답변
2014-03-06 15:34:32
안녕하세요
예스스탁입니다.
아래 내용 참고하셔서 수정보완해 사용하시기 바랍니다.
매수와 매수청산만 처리해 드립니다.
함수나 이벤트의 영문 업데이트가 Up*Date로 중간에 *가 있으니 삭제하시기 바랍니다.
// COMMON
var gUNum, gLNum;
var gCallCode, gPutCode;
var gCallPrice, gPutPrice;
var gCC, gPP;
var gBStep;
var gSStep;
// BUY
var gGetRxBUY;
var gCallOrderCode;
var gEntryBuyID1;
var gEntryBuyID2;
var gEntryBuyID3;
var gEntryBuyNum1;
var gEntryBuyNum2;
var gEntryBuyNum3;
var gEntryPrice;
var gEntryFuture;
var gEntryContracts;
var gEntryContracts1;
var gEntryContracts2;
var gEntryContracts3;
var gExitBuyID1;
var gExitBuyID2;
var gExitBuyID3;
var gExitBuyNum1;
var gExitBuyNum2;
var gExitBuyNum3;
var gExitBuyNum3;
var gExitContracts;
var gExitContracts1;
var gExitContracts2;
var gExitContracts3;
// SELL
var gGetRxSELL;
var gPutOrderCode;
var gEntrySellID;
var gEntrySellNum;
var gExitSellID;
var gExitSellNum;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// INIT
//
function Main_OnStart()
{
Main.MessageLog("+READY!");
gGetRxBUY = 0;
gGetRxSELL = 0;
gBStep = 0;
gSStep = 0;
gEntryContracts = 1;
Main.SetTimer(1, 60000);//1번 타이머 60초
}
//타이머 동작
function Main_OnTimer(nEventID)
{
//1번 타이머 동작(스팟시작후 1분후 옵션 미체결이 있으면 모두 취소)
if (nEventID == 1)
{
//1번 타이머 종료
Main.KillTimer(1);
//CA계좌의 총미체결 건수
var UFnum = CA.GetTheNumberOfUnfills();
for (var i = 0; i < UFnum; i++)
{
CA.SetUnfillIndex(nIndex);
//셋팅된 미체결의 종목코드가 첫번째 글자가 1(선물)이 아니면 취소
if (CA.Unfill.code.substring(0,1) != "1")
CA.OrderCancel(CA.Unfill.orderNum);
}
}
//2번 타이머 동작(Buy신호 발생 후 1분후)
if (nEventID == 2)
{
//2번 타이머 종료
Main.KillTimer(2);
if (Option.GetCurrentByCode(gCallOrderCode) >= 3.0)
var tick = 0.05;
else
var tick = 0.01
gEntryBuyID2 = CA.OrderBuy(gCallOrderCode, gEntryContracts2,gEntryPrice-Tick*5, 0);
}
//3번 타이머 동작(Buy신호 발생 후 2분후))
if (nEventID == 3)
{
//3번 타이머 종료
Main.KillTimer(3);
if (Option.GetCurrentByCode(gCallOrderCode) >= 3.0)
var tick = 0.05;
else
var tick = 0.01
gEntryBuyID3 = CA.OrderBuy(gCallOrderCode, gEntryContracts3,gEntryPrice-Tick*5, 0);
}
//4번 타이머 동작(Buy신호후 5분 후 미체결 취소)
if (nEventID == 4)
{
//4번 타이머 종료
Main.KillTimer(4);
//gEntryBuyNum1 주문번호의 미체결객체 설정
CA.SetUnfillOrderNumber(gEntryBuyNum1);
//미체결 수량이 있으면 취소
if (CA.Unfill.count > 0)
{
CA.OrderCancel(gEntryBuyNum1);
}
//gEntryBuyNum2 주문번호의 미체결객체 설정
CA.SetUnfillOrderNumber(gEntryBuyNum2);
//미체결 수량이 있으면 취소
if (CA.Unfill.count > 0)
{
CA.OrderCancel(gEntryBuyNum2);
}
//gEntryBuyNum3 주문번호의 미체결객체 설정
CA.SetUnfillOrderNumber(gEntryBuyNum3);
//미체결 수량이 있으면 취소
if (CA.Unfill.count > 0)
{
CA.OrderCancel(gEntryBuyNum3);
}
}
//5번 타이머 동작(Buy신호 발생 후 10초후))
if (nEventID == 2)
{
//5번 타이머 종료
Main.KillTimer(6);
//gEntryBuyNum1 주문번호의 미체결객체 설정
CA.SetUnfillOrderNumber(gEntryBuyNum1);
//미체결 수량이 있으면 취소
if (CA.Unfill.count > 0)
{
//현재가로 정정주문
gEntryBuyID1 = CA.OrderReplacePrice(gEntryBuyNum1, Option.GetCurrentByCode(CA.Unfill.code));
}
}
//12번 타이머 동작(Exitlong신호 발생 후 1분후)
if (nEventID == 12)
{
//12번 타이머 종료
Main.KillTimer(12);
if (Option.GetCurrentByCode(gCallOrderCode) >= 3.0)
var tick = 0.05;
else
var tick = 0.01
gEntryBuyID2 = CA.OrderSell(gCallOrderCode, gEntryContracts2,Option.GetCurrentByCode(gCallOrderCode)+Tick*5, 0);
}
//13번 타이머 동작(Exitlong신호 발생 후 1분후)
if (nEventID == 13)
{
//13번 타이머 종료
Main.KillTimer(13);
if (Option.GetCurrentByCode(gCallOrderCode) >= 3.0)
var tick = 0.05;
else
var tick = 0.01
gEntryBuyID3 = CA.OrderSell(gCallOrderCode, gEntryContracts3,Option.GetCurrentByCode(gCallOrderCode)+Tick*5, 0);
}
//14번 타이머 동작(Exitlong신호 발생 후 5분후)
if (nEventID == 13)
{
//3개의 청산주문에 대해 미체결을 모두 취소
//14번 타이머 종료
Main.KillTimer(14);
CA.SetUnfillOrderNumber(gExitBuyNum1);
if (CA.Unfill.count > 0)
CA.OrderCancel(gExitBuyNum1);
CA.SetUnfillOrderNumber(gExitBuyNum2);
if (CA.Unfill.count > 0)
CA.OrderCancel(gExitBuyNum2);
CA.SetUnfillOrderNumber(gExitBuyNum3);
if (CA.Unfill.count > 0)
CA.OrderCancel(gExitBuyNum3);
//잔고수량만큼 시장가로 매
CA.SetBalanceItem(gCallOrderCode, 0);
if (CA.Balance.count > 0)
CA.OrderSell(gCallOrderCode,CA.Balance.count3,0, 1);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ON RISE SIGNAL FROM CHART
//
function CC_OnRiseSignal(Signal)
{
Main.MessageLog("+SIGNAL TYPE: [" + Signal.signalKind + "]");
//------------------------------------------------------------------------------------------------------------------------------------------------------
// BUY SIGNAL: sigKind(1)
if (Signal.signalKind == SIG_BUY)
{
// 2.5이하 중 가장 큰 가격을 가지는 콜종목을 찾음
gUNum = Option.uppersATM;
gLNum = Option.lowersATM;
gCallCode = new Array(gUNum + gLNum + 1);
gCallPrice = new Array(gUNum + gLNum + 1);
for (var i = -gLNum; i <= gUNum; i++)
{
// CALL: 0
if (Option.GetCurrent(0, i) <= 2.8)
{
gCallPrice[i + gLNum] = Option.GetCurrent(0, i);
gCallCode[i + gLNum] = Option.GetATMCallRecent(i);
}
else
{
gCallPrice[i + gLNum] = -1;
gCallCode[i + gLNum] = -1;
}
}
gCC = -1;
gCallOrderCode = -1;
for (var j = -gLNum; j <= gUNum; j++)
{
if (gCallPrice[j + gLNum] > gCC)
{
gCC = gCallPrice[j + gLNum];
gCallOrderCode = gCallCode[j + gLNum];
}
}
//Option.GetBidByCode(gCallOrderCode, 2);
//gEntryBuyID = Account.OrderBuy(gCallOrderCode, gEntryContracts, gCC, 0);
//최대주문가능총액의 80%의 1/3 과 10 중 작은 수량지정
gEntryContracts = Math.min(Math.floor(((CA.GetBalanceETCinfo(29)*0.8))/(Option.GetCurrentByCode(gCallOrderCode)*500000)),10);
gEntryContracts1 = Math.floor(gEntryContracts/3);
gEntryContracts2 = Math.floor(gEntryContracts/3);
gEntryContracts3 = gEntryContracts-gEntryContracts1-gEntryContracts2;
if (Option.GetCurrentByCode(gCallOrderCode) >= 3.0)
var tick = 0.05;
else
var tick = 0.01
gEntryPrice = Option.GetCurrentByCode(gCallOrderCode)-Tick*2;
gEntryBuyID1 = CA.OrderBuy(gCallOrderCode, gEntryContracts1,gEntryPrice, 0);
gEntryFuture = CF.current;
Main.MessageLog("+ENTRY[BUY], CALL CODE[" + gCallOrderCode + "], " + "CALL PRICE[" + gCC + "]" + "BID[" + gEntryBuyID +"]");
Main.SetTimer(2, 60000);//2번 타이머 60초
Main.SetTimer(3, 120000);//3번 타이머 120초
Main.SetTimer(4, 300000);//4번 타이머 300초
gGetRxBUY = 1;
gBStep = 1;
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
// EXITLONG SIGNAL: sigKind(2)
if (gGetRxBUY == 1 && Signal.signalKind == SIG_EXITLONG)
{
//gCallOrderCode잔고 셋팅
CA.SetBalanceItem(gCallOrderCode, 0);
//수량이 0이상이면
if (CA.Balance.count > 0)
{
gExitContracts = CA.Balance.count;
gExitContracts1 = Math.floor(gExitContracts/3);
gExitContracts2 = Math.floor(gExitContracts/3);
gExitContracts3 = gExitContracts-gExitContracts1-gExitContracts2;
//선물 기준 수익
if (CF.current >= gEntryFuture)
{if (Option.GetCurrentByCode(gCallOrderCode) >= 3.0)
var tick = 0.05;
else
var tick = 0.01
var XBxCallPrice = Option.GetCurrentByCode(gCallOrderCode)-Tick*2;; // 매수 3호가
gExitBuyID1 = CA.OrderSell(gCallOrderCode, gExitContracts1, XBxCallPrice, 0);
Main.SetTimer(12, 60000);//12번 타이머 60초
Main.SetTimer(13, 120000);//13번 타이머 120초
Main.SetTimer(14, 300000);//14번 타이머 300초
}
//선물 기준 손실
if (CF.current < gEntryFuture)
{
gExitBuyID4 = CA.OrderSell(gCallOrderCode, CA.Balance.count, 0,1);
}
}
Main.MessageLog("+EXIT[BUY], CALL CODE[" + gCallOrderCode + "]" + XBxCallPrice + "ELxID[" + gExitBuyID + "]");
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
// SELL SIGANL: sigKind(3)
if (Signal.signalKind == SIG_SELL)
{
// 2.5이하 중 가장 큰 가격을 가지는 풋종목을 찾음
gUNum = Option.uppersATM;
gLNum = Option.lowersATM;
gPutCode = new Array(gUNum + gLNum + 1);
gPutPrice = new Array(gUNum + gLNum + 1);
for (var i = -gUNum; i <= gLNum; i++)
{
// PUT: 1
if (Option.GetCurrent(1, i) <= 2.8)
{
gPutPrice[i + gUNum] = Option.GetCurrent(1, i);
gPutCode[i + gUNum] = Option.GetATMPutRecent(i);
}
else
{
gPutPrice[i + gUNum] = -1;
gPutCode[i + gUNum] = -1;
}
}
gPP = -1;
gPutOrderCode = -1;
for (var j = -gUNum; j <= gLNum; j++)
{
if (gPutPrice[j + gUNum] > gPP)
{
gPP = gPutPrice[j + gUNum];
gPutOrderCode = gPutCode[j + gUNum];
}
}
gEntrySellID = CA.OrderBuy(gPutOrderCode, gEntryContracts, gPP, 0);
Main.MessageLog("+ENTRY[SELL], PUT CODE[" + gPutOrderCode + "], " + "PUT PRICE[" + gPP + "]" + "SID[" + gEntrySellID + "]");
gGetRxSELL = 1;
gSStep = 1;
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
// EXITSHORT SIGANL: sigKind(4)
if (gGetRxSELL == 1 && Signal.signalKind == SIG_EXITSHORT)
{
var XBxPutPrice;
XBxPutPrice = Option.GetBidByCode(gPutOrderCode, 3); // 매수 3호가
gExitSellID = CA.OrderSell(gPutOrderCode, gEntryContracts, XBxPutPrice, 0);
Main.MessageLog("+EXIT[SELL], PUT CODE[" + gPutOrderCode + "]" + XBxPutPrice + "ESxID[" + gExitSellID + "]");
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CHECK ORDER ID
//
function Main_OnOrderResponse(OrderResponse)
{
if (OrderResponse.orderID == gEntryBuyID1)
{
gEntryBuyNum1 = OrderResponse.OrderNum;
Main.SetTimer(5, 1000);//5번 타이머 10초
}
if (OrderResponse.orderID == gEntryBuyID2)
{
gEntryBuyNum2 = OrderResponse.OrderNum;
}
if (OrderResponse.orderID == gEntryBuyID3)
{
gEntryBuyNum3 = OrderResponse.OrderNum;
}
if (OrderResponse.orderID == gExitBuyID1)
{
gExitBuyNum1 = OrderResponse.OrderNum;
}
if (OrderResponse.orderID == gExitBuyID2)
{
gExitBuyNum2 = OrderResponse.OrderNum;
}
if (OrderResponse.orderID == gExitBuyID3)
{
gExitBuyNum3 = OrderResponse.OrderNum;
}
else if (OrderResponse.orderID == gEntrySellID)
{
gEntrySellNum = OrderResponse.OrderNum;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 종목시세 수신
//
function Main_OnUp*dateMarket(sItemCode, lUp*dateID) //*제거
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 주문 접수후 체결응답이 오면
//
function Main_OnNotifyFill(NotifyFill)
{
if (NotifyFill.orderNum == gEntrySellNum)
{
gSStep = 2;
}
if (gSStep == 2 && NotifyFill.orderNum == gExitSellNum)
{
gSStep = 0;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 주문 접수후 체결응답이 오면
//
function Main_OnUp*dateAccount(sAccntNum, sItemCode, lUp*dateID)//*제거
{
}
즐거운 하루되세요
> TRF 님이 쓴 글입니다.
> 제목 : 문의 (YS)
> 파일을 첨부하였는데 아래내용 추가를 부탁드립니다.
어카운트객체: CA
차트객체: CC
마켓객체: CF
** 시작
1. YS시작할때 미체결된 옵션수량을 체크하고, 존재하면 1분까지 기다리다 미체결시에 모두 최종취소함
2. 차트에서 선물진입신호가 발생하면 진입신호부터 허용함(기존 체결되어 잔고에 수량이 있으면 모두 청산)
** 차트에서 매수진입신호 발생시
1. 선물 매수 진입신호 발생시 잔고금액을 확인하여 최대 매수금액의 80%에서 최대 10계약을 3분할로 옵션매수함.
최초 진입은 옵션현재가 (-2틱) 매수주문함. 10초후 미체결시 현재가 정정주문
최초 진입신호 발생후 1분 단위로 이후 2번째 3번째 매수되어야 하며, 첫진입가격의 -5틱(더싸게)에 주문함.
2. 5분이 지난후 미체결된 수량이 있을 시 모두 취소함
** 차트에서 매수청산신호 발생시
1. 잔고를 확인하여 옵션 몇계약이 있는지 확인
2-1. 수익시: 진입과 마찬가지로 1분 이내 단위로 3분할 매수청산함. 첫청산가격의 +5틱(더 비싸게)에 주문함
2-2. 손실시: 전량시장가 청산
(수익과 손익은 차트에서 발생한 선물진입가격 기준으로 현재 선물가격으로 판단함)
3. 5분이 지난후 미체결된 수량이 있을 시 시장가 청산함
감사합니다.