예스스탁
예스스탁 답변
2020-12-18 13:42:29
안녕하세요
예스스탁입니다.
아래 가이드 수식 참고하셔서 수정보완해 사용하시기 바랍니다.
스크립트 객체설정
차트객체추가 --> 속성에서 객체명 Chart1, 3분차트와 연결
종목객체추가 --> 속성에서 객체명 MarketData1, 차트와 동일종목으로 지정
계좌객체추가 --> 속성에서 객체명 Account1,주문낼 계좌번호 지정
var S,ii,H1,L1,EntryTimeCount,ExitTimeCount;
var BuyID,SellID,BuyNum,SellNum;
var BuyPrice,SellPrice;
function Main_OnStart()
{
Main.MessageList("시작");
ii = 0;
S = 0;
}
//봉완성(다음봉시가수신))
function Chart1_OnBarAppended(nData)
{
//봉완성 카운트
ii = ii +1;
//6번쨰봉 시가수신(다섯번쨰봉완성)되고 6개전봉은 오늘봉이 아님
if (ii == 6 && Chart1.GetSDate(0,0) != Chart1.GetSDate(nData, nIndex))
{
//최근 완성된 5개봉의 양봉과 음봉갯수 카운트
var 양봉갯수 = 0;
var 음봉갯수 = 0;
for (var i = 1; i <= 5;i++)
{
if (Chart1.GetClose(1,i) > Chart1.GetOpen(1,i))
{
양봉갯수 = 양봉갯수+1;
}
if (Chart1.GetClose(1,i) < Chart1.GetOpen(1,i))
{
음봉갯수 = 음봉갯수+1;
}
}
//양봉갯수는 3개이상이고 마지막완성봉은 양봉이고 마지막완성봉의 종가가 그전봉의 고가보다 크면
if (양봉갯수 >= 3 && Chart1.GetClose(1,1) > Chart1.GetOpen(1,1) && Chart1.GetClose(0,1) < Chart1.GetHigh(0,2))
{
//매수주문(10계약 종가로 주문)
EntryID = Account1.OrderBuy(Main.GetOrderCode(MarketData1.code), 10,Chart1.GetClose(1,1), 0);
//매수평단가 저장할 변수(초기값은 0)
BuyPrice = 0;
//진입이후 매도1호가기준 최고가 저장할 변수(초기값은 매도1호가)
HH = MarketData1.Ask(1);
//매수이므로 1지정
S = 1;
//직전봉의 저가 저장(완성봉기준 2봉전)
L1 = Chart1.GetLow(0,2);
//정정및 취소 체크 타이머(60초)
Main.SetTimer(1, 60000);
//정정및 최소 타이머 카운트(초기값은 0)
EntryTimeCount = 0;
//청산체크 타이머(1초)
Main.SetTimer(2, 1000);
Main.MessageList("매수진입");
}
if (음봉갯수 >= 3 && Chart1.GetClose(1,1) < Chart1.GetOpen(1,1) && Chart1.GetLow(0,1) < Chart1.GetLow(0,2))
{
//매도주문(10계약 종가로 주문)
EntryID = Account1.OrderSell(Main.GetOrderCode(MarketData1.code), 10,Chart1.GetClose(1,1), 0);
//매도평단가 저장할 변수(초기값은 0)
SellPrice = 0;
//진입이후 매수1호가기준 최저가 저장할 변수(초기값은 매수1호가)
LL = MarketData1.Bid(1);
//매도이므로 -1저장
S = -1;
//직전봉의 고가 저장(완성봉기준 2봉전)
H1 = Chart1.GetHigh(0,2);
//정정및 취소 체크 타이머(60초)
Main.SetTimer(1, 60000);
//정정및 최소 타이머 카운트(초기값은 0)
EntryTimeCount = 0;
//청산체크 타이머(1초)
Main.SetTimer(2, 1000);
Main.MessageList("매도진입")
}
}
if (ii >= 7)
{
//매수진입 후 완성봉기준 직전봉 저점을 돌파하는 음봉으로 마감시 봉의 종가에 청산
if (S == 1 && BuyPrice > 0 &&
Chart1.GetClose(1,1) < Chart1.GetOpen(1,1) && Chart1.GetClose(1,1) < Chart1.GetLow(1,2))
{
S = 0;
Main.KillTimer(2);
BXID = Account1.OrderSell(Main.GetOrderCode(MarketData1.code), 10, MarketData1.Ask(1), 0);
//청산주문 정정취소 타이머(60초)
Main.SetTimer(3, 60000);
ExitTimeCount = 0;
}
//매도진입 후 완성봉기준 직전봉 고점을 돌파하는 양봉으로 마감시 봉의 종가에 청산
if (S == -1 && SellPrice > 0 &&
Chart1.GetClose(1,1) > Chart1.GetOpen(1,1) && Chart1.GetClose(1,1) > Chart1.GetHigh(1,2))
{
S = 0;
Main.KillTimer(2);
SXID = Account1.OrderBuy(Main.GetOrderCode(MarketData1.code), 10, MarketData1.Ask(1), 0);
//청산주문 정정취소 타이머(60초)
Main.SetTimer(3, 60000);
ExitTimeCount = 0;
}
}
}
function Main_OnTimer(nEventID)
{
var d = new Date();
HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds();
//1번 타이머 동작
if (nEventID == 1)
{
EntryTimeCount = EntryTimeCount+1;
//첫번쨰 동작
if (EntryTimeCount == 1)
{
//상대1호가로 정정
if (S == 1)
{
var OP = MarketData1.Ask(1);
Account1.SetUnfill(BuyNum);
if (Account1.Unfill.count > 0 && Account1.Unfill.price != OP)
{
BuyID = Account1.OrderReplacePrice(BuyNum,OP)
}
}
if (S == -1)
{
var OP = MarketData1.Bid(1);
Account1.SetUnfill(SellNum);
if (Account1.Unfill.count > 0 && Account1.Unfill.price != OP)
{
SellID = Account1.OrderReplacePrice(SellNum,OP)
}
}
}
//두번재 동작 취소
if (EntryTimeCount == 2)
{
Main.KillTimer(2);
if (S == 1)
{
Account1.SetUnfill(BuyNum);
if (Account1.Unfill.count > 0)
{
Account1.OrderCancel(BuyNum);
}
}
if (S == -1)
{
Account1.SetUnfill(SellNum);
if (Account1.Unfill.count > 0)
{
Account1.OrderCancel(SellNum);
}
}
}
}
//2번 타이머 동작
if (nEventID == 2)
{
//매수진입 후
if (S == 1 && BuyPrice > 0)
{
// 진입직전봉저가에 손절
if (MarketData1.current <= L1)
{
S = 0;
Main.KillTimer(2);
BXID = Account1.OrderSell(Main.GetOrderCode(MarketData1.code), 10, MarketData1.Ask(1), 0);
}
//매도1호가 기준 진입후 최고가
if (MarketData1.Ask(1) > HH)
{
HH = MarketData1.Ask(1);
}
//진입후 최고가가 평단가대비 0.5% 이상이고 수익폭의 50%를 하회하면 청산
if (HH >= BuyPrice*1.005 && MarketData1.current <= BuyPrice+(HH-BuyPrice)*0.5)
{
S = 0;
Main.KillTimer(2);
BXID = Account1.OrderSell(Main.GetOrderCode(MarketData1.code), 10, MarketData1.Ask(1), 0);
}
//15시 15분 청산
if (S == 1 && BuyPrice > 0 && HHMMSS >= 151500)
{
S = 0;
Main.KillTimer(2);
BXID = Account1.OrderSell(Main.GetOrderCode(MarketData1.code), 10, MarketData1.Ask(1), 0);
}
}
//매도진입 후
if (S == -1 && SellPrice > 0)
{
//진입직전봉고가에 손절
if (MarketData1.current >= H1)
{
S = 0;
Main.KillTimer(2);
SXID = Account1.OrderBuy(Main.GetOrderCode(MarketData1.code), 10, MarketData1.Ask(1), 0);
}
//매수1호가 기준 진입후 최저가
if (MarketData1.Bid(1) >= H1)
{
LL = MarketData1.Bid(1);
}
//진입후 최저가가 평단가대비 -0.5% 이하이고 수익폭의 50%를 하회하면 청산
if (LL <= SellPrice*0.995 && MarketData1.current >= SellPrice+(SellPrice-LL)*0.5)
{
S = 0;
Main.KillTimer(2);
SXID = Account1.OrderBuy(Main.GetOrderCode(MarketData1.code), 10, MarketData1.Ask(1), 0);
}
//15시 15분 청산
if (HHMMSS >= 151500)
{
S = 0;
Main.KillTimer(2);
SXID = Account1.OrderBuy(Main.GetOrderCode(MarketData1.code), 10, MarketData1.Ask(1), 0);
}
}
}
//3번 타이머 동작
if (nEventID == 3)
{
ExitTimeCount = ExitTimeCount+1;
//첫번쨰 동작
if (ExitTimeCount == 1)
{
//상대1호가로 정정
if (BuyPrice > 0)
{
var OP = MarketData1.Bid(1);
Account1.SetUnfill(BXNum);
if (Account1.Unfill.count > 0 && Account1.Unfill.price != OP)
{
BXID = Account1.OrderReplacePrice(BXNum,OP)
}
}
if (SellPrice > 0)
{
var OP = MarketData1.Ask(1);
Account1.SetUnfill(SXNum);
if (Account1.Unfill.count > 0 && Account1.Unfill.price != OP)
{
SXID = Account1.OrderReplacePrice(SXNum,OP)
}
}
}
//두번째 동작
if (ExitTimeCount == 2)
{
//상대1호가로 정정
if (BuyPrice > 0)
{
var OP = MarketData1.Bid(1);
Account1.SetUnfill(BXNum);
if (Account1.Unfill.count > 0 && Account1.Unfill.price != OP)
{
BXID = Account1.OrderReplacePrice(BXNum,OP)
}
}
if (SellPrice > 0)
{
var OP = MarketData1.Ask(1);
Account1.SetUnfill(SXNum);
if (Account1.Unfill.count > 0 && Account1.Unfill.price != OP)
{
SXID = Account1.OrderReplacePrice(SXNum,OP)
}
}
}
//세번째 동작
if (ExitTimeCount == 3)
{
//3번 타이머 종료
Main.KillTimer(3);
//최소
if (BuyPrice > 0)
{
Account1.SetUnfill(BXNum);
if (Account1.Unfill.count > 0)
{
Account1.OrderCancel(BXNum);
}
}
if (SellPrice > 0)
{
Account1.SetUnfill(SXNum);
if (Account1.Unfill.count > 0)
{
Account1.OrderCancel(SXNum);
}
}
}
}
}
//주문응답 이벤트
function Main_OnOrderResponse(OrderResponse)
{
//매수진입의 주문번호 저장
if (OrderResponse.orderID == BuyID)
{
BuyNum = OrderResponse.orderNum;
}
//매수청산의 주문번호 저장
if (OrderResponse.orderID == BXID)
{
BXNum = OrderResponse.orderNum;
}
//매도진입의 주문번호 저장
if (OrderResponse.orderID == SellID)
{
SellNum = OrderResponse.orderNum;
}
//매도청산의 주문번호 저장
if (OrderResponse.orderID == SXID)
{
SXNum = OrderResponse.orderNum;
}
}
//체결응답 이벤트
function Main_OnNotifyFill(NotifyFill)
{
//매수진입주문이 체결되면 평단가 저장
if (NotifyFill.orderNum == BuyNum)
{
Account1.SetBalance(Main.GetOrderCode(MarketData1.code),0);
if (Account1.Balance.position == 2 && Account1.Balance.count > 0)
{
BuyPrice = Account1.Balance.avgUnitCost;
}
}
//매도진입주문이 체결되면 평단가 저장
if (NotifyFill.orderNum == SellNum)
{
Account1.SetBalance(Main.GetOrderCode(MarketData1.code),0);
if (Account1.Balance.position == 1 && Account1.Balance.count > 0)
{
SellPrice = Account1.Balance.avgUnitCost;
}
}
}
즐거운 하루되세요
> 마식 님이 쓴 글입니다.
> 제목 : 수식 부탁드립니다.
> 예스스팟을 이제야 시작해 봅니다^^
수식 부탁드립니다^^
-------------------------------------------------------------------------------------
- 종목은 코스피 200으로 3분 봉으로 세팅 / 매수 진입 조건식입니다.
- 분봉 데이터를 기반으로 진행하고
-----------------------------------------------------------------------------------
- 하루 시작의 5봉중 3봉이 양이고
- 세번째 양의 종가에 진입
- (전제조권 5봉중 3봉이 양이면)
직전봉의 고점을 돌파하고 양봉으로 마감하는 봉의 종가에 매수 진입
- 진입 수량은 10 계약
----------------------------------------------------------------------------------
- 미체결시 60초 후 현재의 상대 1호가에 정정 주문
- 또 미체결시 주문 취소
----------------------------------------------------------------------------------
- 청산 및 손절-
- 진입한 직전봉의 저가에 손절
- 또는 직전봉 저점을 돌파하는 음봉으로 마감시 봉의 종가에 매수 청산
- 미체결시 60초 후 현재의 상대 1호가에 정정 주문
- 또 미체결시 60초 후 현재의 상대 1호가에 정정 주문
--------------------------------------------------------------------------------------
- 당일의 마지막봉 시가에 청산
--------------------------------------------------------------------------------------
- 스탑트레일링은 매수 평균매수가 대비 현재의 상대 1호가를 기준으로 수익을 0.5% 이상
상승시 그 이후 상승의 50% 하락시 현재가에 청산
- 상대 1호가 수신은 1초단위로 데이터 수신 가능 할 까요?
--------------------------------------------------------------------------------------
고맙습니다^^