답변완료
다음날 청산 되는 수식
아래 수식은 전일 15시 10분에 매도하여 다음날 15시 5분에 청산하는 수식입니다.
그런데 실전에서는 당일 15시 10분에 주문(매도)이 되나 다음날 15시 05분에 청산이 안되는데 뭐가 잘못되었는지 수정 부탁합니다.
var CallOrderCode,PutOrderCode;
var Entry, Exit;
function Main_OnStart()
{
Entry = false;
Exit = false;
Main.SetTimer(1, 5000);
}
function Main_OnTimer(nEventID)
{
if (nEventID <= 1)
{
var d = new Date();
var HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds();
//15시 10분
if (Entry == false && HHMMSS >= 151000 )
{
Entry = true;
//차트가 무포지션
if (Chart1.GetOpenContracts() == 0)
{
Main.SetUserValue("CallOrderCode", "");
Main.SetUserValue("PutOrderCode", "");
}
//차트가 매수유지봉
if (Chart1.GetOpenContracts() > 0)
{
Main.MessageList("--------------------------------------------");
Main.MessageList("매수신호유지");
var UNum = Option.uppersATM;
var LNum = Option.lowersATM;
================================ 중략 ========================================
//종목을 찾았으면
if (CC < 99999999 && PP < 99999999)
{
Account1.OrderSell(CallOrderCode, 1, 0, 1);
Account1.OrderSell(PutOrderCode, 1, 0, 1);
Main.SetUserValue("CallOrderCode", CallOrderCode);
Main.SetUserValue("PutOrderCode", PutOrderCode);
}
}
}
//15시 5분
if (Exit == false && HHMMSS >= 150500 )
{
Exit = true;
//내부파일의 값을 가져와 변수에 저장
var PreDayCall = Main.GetUserValue("CallOrderCode");
var PreDayPut = Main.GetUserValue("PutOrderCode");
//PreDayCall에 값이 있으면
if (PreDayCall != "")
{
//잔고셋팅후 매도포지션이면 청산하고
//내부파일의 값을 빈공간으로 만듬
Account1.SetBalanceItem(PreDayCall,0)
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
Account1.OrderBuy(Account1.Balance.code, Account1.Balance.count, 0, 1);
Main.SetUserValue("CallOrderCode", "");
}
}
//PreDayPutl에 값이 있으면
if (PreDayPut != "")
{
//잔고셋팅후 매도포지션이면 청산하고
//내부파일의 값을 빈공간으로 만듬
Account1.SetBalanceItem(PreDayPut,0)
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
Account1.OrderBuy(Account1.Balance.code, Account1.Balance.count, 0, 1);
Main.SetUserValue("PutOrderCode", "");
}
}
//모두 수행후 값을 빈공간으로 만듬
Main.SetUserValue("CallOrderCode", "");
Main.SetUserValue("PutOrderCode", "");
}
//콜매도, 풋매도 금액의 합으로 +500000원 익절, -500000원 손절
if (HHMMSS < 150500)
{
// 옵션매도포지션 전체 손익계산
var num = Account1.GetTheNumberOfBalances();
var PLsum = 0;
for(var i = 0; i < num; i++)
{
//잔고셋팅
Account1.SetBalanceIndex(i);
//매도포지션이고 옵션종목이고
if (Account1.Balance.position == 1 && (Account1.Balance.code.substring(0,1) == "2" || Account1.Balance.code.substring(0,1) == "3"))
{
//각 옵션매도종목의 (평균단가-현재가)*수량*50만원을 누적
PLsum = PLsum + ((Account1.Balance.avgUnitCost - Account1.Balance.current)*Account1.Balance.count)*500000;
}
}
//손익이 +50만원이상이거나 -50만원 이하이면
if (PLsum >= 500000 || Plsum <= -500000)
{
for(var i = 0; i < num; i++)
{
//잔고셋팅
Account1.SetBalanceIndex(i);
//매도포지션이고 옵션종목이고
if (Account1.Balance.position == 1 && (Account1.Balance.code.substring(0,1) == "2" || Account1.Balance.code.substring(0,1) == "3"))
{
Account1.OrderBuy(Account1.Balance.code, Account1.Balance.count, 0,1);
}
}
}
}
}
}
2017-12-14
2690
글번호 224278
답변완료
문의 드립니다.
아래의 국내선물 시스템수식을 사용하고 있는데 일단 매수, 매도는 체결이 잘 됩니다.
그런데 문제가 있습니다.
1) Account2.Balance.count < 3 를 사용해서 잔고가 3개 이상이면 매수나 매도를 안되어야 되는데 위의 첨부그림파일처럼 매도가 7개 이상 계속 체결이 되어 버립니다.
2) 그리고 더 큰 문제는 청산이 전혀 안되고 있는 것입니다.
가령 매수잔고가 있다면 4개 차트 중에 하나만 매도신호가 떠도 바로 청산을 해야 하는데 전혀 안되고 그 밑의 익절청산과 손절청산 수식도 역시나 작동이 안됩니다.
3) 그리고 사운드도 안됩니다. 모두 alert.wav 소리로 대체되어 나옵니다.
도움을 좀 부탁드립니다.
=====================
var SK1;
var SK2;
var SK3;
function Main_OnStart()
{
SK1 = 0;
SK2 = 0;
SK3 = 0;
SK4 = 0;
}
function Chart1_OnRiseSignal(Signal)
{
SK1 = Signal.signalKind;
//현재차트1에서 매도신호 발생하고 차트2,3,4에서 매도신호 발생중이면 매도 && 매수 잔고 수량은 3개 미만
if (SK1 == 3 && ( SK2 == 3 || SK3 == 3 || SK4 == 3) && Account2.Balance.count < 3 )
{
//1계약 신호가격으로 매도주문
Account2.OrderSell(Main.GetOrderCode(Signal.code), 1, Signal.price, 0);
Main.PlaySound("C:₩예스트레이더₩data₩Sound₩SingalSell.wav");
}
//잔고가 매도포지션이고 수량이 있을떄만
if (Account2.Balance.position == 1 && Account2.Balance.count > 0)
{
//네 차트 중 하나라도 매도청산신호 발생하면 매도포지션 청산
if ( SK1 == 4 || SK2 == 4 || SK3 == 4 || SK4 == 4 )
{
Account2.OrderBuy(Main.GetOrderCode(Signal.code), Account2.Balance.count, 0, 1); //시장가 청산
// Account2.OrderBuy(Main.GetOrderCode(Signal.code), 1, Signal.price, 0);
Main.PlaySound("C:₩예스트레이더₩data₩Sound₩SingalClearSell.wav");
}
//현재가가 잔고평단가 대비 -0.25 이하이면 익절청산
if (MarketData1.current <= Account2.Balance.avgUnitCost - 0.25)
//if (MarketData1.current <= Account2.Balance.avgUnitCost - MarketData1.GetTickSize()*5 ) //5틱이상 하락하면
{
Account2.OrderBuy(Account2.Balance.code, Account2.Balance.count, 0, 1);
// Account2.OrderBuy(Account2.Balance.code, Account2.Balance.count, MarketData1.Ask(1), 0);
Main.PlaySound("C:₩예스트레이더₩data₩Sound₩SingalClearSell.wav");
}
//현재가가 잔고평단가 대비 +0.3 이상이면 손절청산
if (MarketData1.current >= Account2.Balance.avgUnitCost + 0.3)
{
Account2.OrderBuy(Account2.Balance.code,Account2.Balance.count, 0, 1);
Main.PlaySound("C:₩예스트레이더₩data₩Sound₩SingalClearSell.wav");
}
}
//현재차트1에서 매수신호 발생하고 차트2,3,4에서 매수신호 발생이면 매도
if (SK1 == 1 && ( SK2 == 1 || SK3 == 1 || SK4 == 1 ) && Account2.Balance.count < 3 )
{
//1계약 신호가격으로 매수주문
Account2.OrderBuy(Main.GetOrderCode(Signal.code), 1, Signal.price, 0);
Main.PlaySound("C:₩예스트레이더₩data₩Sound₩SingalBuy.wav");
}
//잔고가 매수포지션이고 매수잔고 수량이 있을떄
if (Account2.Balance.position == 2 && Account2.Balance.count > 0)
{
//네 차트 중 하나라도 매수청산신호 발생하면 매수포지션 청산
if ( SK1 == 2 || SK2 == 2 || SK3 == 2 || SK4 == 2 )
{
Account2.OrderSell(Main.GetOrderCode(Signal.code), 1, Signal.price, 0);
Main.PlaySound("C:₩예스트레이더₩data₩Sound₩SignalClearBuy.wav");
}
//현재가가 잔고평단가 대비 +0.25 이상이면 익절청산
if (MarketData1.current >= Account2.Balance.avgUnitCost + 0.25)
{
Account2.OrderSell(Account2.Balance.code,Account2.Balance.count, 0, 1);
Main.PlaySound("C:₩예스트레이더₩data₩Sound₩SignalClearBuy.wav");
}
//현재가가 잔고평단가 대비 -0.3 이하이면 손절청산
if (MarketData1.current <= Account2.Balance.avgUnitCost - 0.3)
{
Account2.OrderSell(Account2.Balance.code,Account2.Balance.count, 0, 1);
Main.PlaySound("C:₩예스트레이더₩data₩Sound₩SignalClearBuy.wav");
}
}
}
2017-12-15
2849
글번호 224275
답변완료
수식 요청드립니다.
안녕하세요.
다음과 같은 전략을 실행시키기 위해 예스스팟 파일을 작성해 보았습니다.
이상은 없는지 한 번 검토해 주시면 감사드리겠습니다.
[전략 내용]
1. 해외 선물 데이트레이딩 전략으로 뉴욕 시각 기준으로 18시부터 진입을 하고 다음날 16시 40분에 모든 포지션을 청산함
2. 일 목표 수익액은 50만원이고, 일 최대 손실액도 50만원 임. 위 수익액 또는 손실액에 도달하면 모든 매매를 종료함
3. Chart1에서 신호가 발생하면 최초로 진입을 하되, 일단 최초 진입을 한 이후부터는 Chart2의 신호에 따라서 계속 스위칭을 하게 됨
1) Chart1에서 매수 신호가 발생하면, MarketData1 종목을 1개 매수하고, 동시에 MarketData2 종목도 1개 매수함
1-1) 이후 Chart1에서 발생하는 신호는 무시되며, Chart2의 스위칭 신호에 따라서 스위칭을 반복하게 됨
1-2) 이후 Chart2에서 매수 신호가 발생하면, 이미 매수 진입을 했으므로 추가 진입은 없음
1-3) 이후 Chart3에서 매도 신호가 발생하면, 진입된 매수 포지션을 모두 청산하고, MarketData1 종목을 1개 매도하고, 동시에 MarketData2 종목도 1개 매도함
1-4) 일 목표 수익/손실액을 달성할 때까지, 1-2) 및 1-3) 과정을 반복함
2) Chart1에서 매도 신호가 발생하면, MarketData1 종목을 1개 매수하고, 동시에 MarketData2 종목도 1개 매수함
2-1) 이후 Chart1에서 발생하는 신호는 무시되며, Chart2의 스위칭 신호에 따라서 스위칭을 반복하게 됨
2-2) 이후 Chart2에서 매도 신호가 발생하면, 이미 매도 진입을 했으므로 추가 진입은 없음
2-3) 이후 Chart3에서 매수 신호가 발생하면, 진입된 매도 포지션을 모두 청산하고, MarketData1 종목을 1개 매수하고, 동시에 MarketData2 종목도 1개 매수함
2-4) 일 목표 수익/손실액을 달성할 때까지, 2-2) 및 2-3) 과정을 반복함
[HTS 환경]
- 현대선물
[예스스팟 코드]
var N=0;
var IsChart1on=0;
var X;
var i1;
function Main_OnStart()
{
Main.MessageList("스팟 시작"); //i1에 예수금/예탁총액 저장
i1 = Account1.GetBalanceETCinfo(4);
X = 0;
Main.SetTimer(1, 1000); //5초 타이머 셋팅
Main.MessageList("예수금", Account1.GetBalanceETCinfo(4));
}
function Chart1_OnRiseSignal(Signal)
{
if (IsChart1on == 0 && Signal.signalKind == 1) // 매수 신호 발생시
{
Main.MessageList("최초 진입신호!!! Chart1 매수 신호 발생");
Account1.Orderbuy(Main.GetOrderCode(MarketData1.code), 1, 0, 1);
Account1.Orderbuy(Main.GetOrderCode(MarketData2.code), 1, 0, 1);
IsChart1on = 1; // IsChart1on의 값을 1로 변경하여 더 이상 Chart1에서 발생하는 신호에는 진입하지 않도록 함
N = 1;
}
if (IsChart1on == 0 && Signal.signalKind == 3)// 매도 신호 발생시
{
Main.MessageList("최초 진입신호!!! Chart1 매도 신호 발생");
Account1.Ordersell(Main.GetOrderCode(MarketData1.code), 1, 0, 1);
Account1.Ordersell(Main.GetOrderCode(MarketData2.code), 1, 0, 1);
IsChart1on = 1; // IsChart1on의 값을 1로 변경하여 더 이상 Chart1에서 발생하는 신호에는 진입하지 않도록 함
N = -1;
}
}
// 일단 Chart1에서 진입 신호가 발생한 이후에는 Chart2에서 발생하는 스위칭 신호에 따라서만 스위칭 함
function Chart2_OnRiseSignal(Signal)
{
if (N == 1 && Signal.signalKind == 2) // 매수청산 신호 발생시
{
Main.MessageList("Chart2 매수청산 신호 발생");
Account1.Ordersell(Main.GetOrderCode(MarketData1.code), 1, 0, 1);
Account1.Ordersell(Main.GetOrderCode(MarketData2.code), 1, 0, 1);
N = 0;
}
if (N == 0 && Signal.signalKind == 1) // 매수 신호 발생시
// Chart1에 의해서 매수신호가 발생해서 이미 진입된 상태에서 Chart2에서 또 매수 신호가 나오더라도 추가 진입을
// 시키지 않기 위해 N이 1이면 추가 진입하지 않음
{
Main.MessageList("Chart2 매수 신호 발생");
Account1.Orderbuy(Main.GetOrderCode(MarketData1.code), 1, 0, 1);
Account1.Orderbuy(Main.GetOrderCode(MarketData2.code), 1, 0, 1);
N = 1;
}
if (N == -1 && Signal.signalKind == 4) // 매도청산 신호 발생시
{
Main.MessageList("Chart2 매도청산 신호 발생");
Account1.Orderbuy(Main.GetOrderCode(MarketData1.code), 1, 0, 1);
Account1.Orderbuy(Main.GetOrderCode(MarketData2.code), 1, 0, 1);
N = 0;
}
if (N == 0 && Signal.signalKind == 3) // 매도 신호 발생
// Chart1에 의해서 매도신호가 발생해서 이미 진입된 상태에서 Chart2에서 또 매도 신호가 나오더라도 추가 진입을
// 시키지 않기 위해 N이 -1이면 추가 진입하지 않음
{
Main.MessageList("Chart2 매도 신호 발생");
Account1.Ordersell(Main.GetOrderCode(MarketData1.code), 1, 0, 1);
Account1.Ordersell(Main.GetOrderCode(MarketData2.code), 1, 0, 1);
N = -1;
}
}
// 일(daily) 수익 목표 및 손실 한도액(각 50만원)에 도달할 경우 당일 매매는 중지함
// 뉴욕 현지 시각 기준으로 16시 40분에 모든 포지션 청산함
function Main_OnTimer(nEventID)
{
//현재 예수금이 스팟 시작시값보다 50만원 이상 감소하면 진입 금지
if (nEventID == 1 && Account1.GetBalanceETCinfo(4) <= i1-500000)
{
//미체결주문 전체 취소
var num1 = Account1.GetTheNumberOfUnfills();
for(i = 0; i < num1; i++)
{
Account1.SetUnfillIndex(i)
Account1.OrderCancel(Account1.Unfill.orderNum);
}
//잔고 전체 종목 청산
var num2 = Account1.GetTheNumberOfBalances();
for(i = 0; i < num2; i++)
{
Account1.SetBalanceIndex(i);
if (Account1.Balance.count > 0 && Account1.Balance.position == 2)
Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
Account1.OrderBuy(Account1.Balance.code,Account1.Balance.count,0,1);
}
X = 1;
Main.MessageList("당일 손실 한도액 초과! 진입 금지!");
}
//현재 예수금이 스팟 시작시값보다 50만원 이상 증가하면 진입 금지
if (nEventID == 1 && Account1.GetBalanceETCinfo(4) >= i1+500000)
{
//미체결주문 전체 취소
var num1 = Account1.GetTheNumberOfUnfills();
for(i = 0; i < num1; i++)
{
Account1.SetUnfillIndex(i)
Account1.OrderCancel(Account1.Unfill.orderNum);
}
//잔고 전체 종목 청산
var num2 = Account1.GetTheNumberOfBalances();
for(i = 0; i < num2; i++)
{
Account1.SetBalanceIndex(i);
if (Account1.Balance.count > 0 && Account1.Balance.position == 2)
Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1);
if (Account1.Balance.count > 0 && Account1.Balance.position == 1)
Account1.OrderBuy(Account1.Balance.code,Account1.Balance.count,0,1);
}
X = 1;
Main.MessageList("당일 수익 달성! 진입 금지!");
}
//뉴욕 현지 시각 기준 16시 40분 모두 청산
var d = new Date();
var HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds();
if (nEventID == 1 && HHMMSS <= 170000 && HHMMSS >= 164000) //16시 40분에 계좌 잔고 모두 시장가로 청산주문
{
Main.KillTimer(1);
num = Account1.GetTheNumberOfBalances();
for(var i = 0; i < num; i++)
{
Account1.SetBalanceIndex(i);
if (Account1.Balance.position == 1)
Account1.OrderBuy(Account1.Balance.code,Account1.Balance.count,0,1);
if (Account1.Balance.position == 2)
Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1);
}
Main.MessageList("장마감 청산");
IsChart1on = 0; //IsChart1on의 값을 0으로 변경하고 18시 뉴욕 장 시작 이후 chart1의 진입 신호를 기다림
}
}
2017-12-03
2670
글번호 224268