차트에서 신호발생시 스팟으로 주문을 내는 수식입니다.
예제6은 차트에서 신호가 발생하면 종목객체에서 지정한 종목으로 주문을 집행하게 됩니다.
아래는 차트에서 진입신호가 발생하면
지정한 수량을 N회 분할하여 일정주기로 주문을 집행하는 수식입니다.
1.
전략내용
진입신호가 발생하면 종목객체에서 지정한 종목을 주문을 하는데
수량을 N분할하여 현재가로 일정간격(초)으로 주문을 집행하게 됩니다.
청산신호가 발생하면 분할된 주문들 중 미체결된 수량은 취소하고
체결된 수량으로 상대5호가 주문을 집행하게 됩니다.
2.
스크립트 객체화면 설정
차트객체 : 객체명 Chart1 → 속성에서 차트와 동일 아이디 지정
계좌객체 : 객체명 Account1 → 속성에서 계좌번호 선택
종목객체 : 객체명 MarketData1 → 속성에서 주문종목을 지정
3.
스팟수식
var OC, MK, pst;
var BV,SV;
var BID = [], SID = [], BNUM = [], SNUM = [];
var 진입주문수량 = 12;
var 분할간격 = 6; //초
var 분할횟수 = 10;
var V1 = Math.floor(진입주문수량/분할횟수);//1회 주문수량
//진입주문수량을 분할횟수로 나누고 정수만 취해서 주문을 합니다.
//수량의 소숫점을 제외하므로 마지막 회차에는 남은 잔량 일괄로 주문합니다.
function Main_OnStart()
{
Main.MessageList("Start");
//주문종목 종목코드
OC = Main.GetOrderCode(MarketData1.code);
pst = 0;
}
function Chart1_OnRiseSignal(Signal)
{
//매수진입신호 발생
if (Signal.signalKind == 1)
{
Main.MessageList("매수진입신호:");
BID = [];
BNUM = [];
sumBV = Math.min(Math.max(진입주문수량,1),V1);
//매수주문 집행(지정수량,현재가 지정가)
BID.push(Account1.OrderBuy(OC, Math.min(Math.max(진입주문수량,1),V1), MarketData1.current,0));
Main.MessageList(BID.length,"차 매수주문:",BID[BID.length-1]);
//포지션은 1
pst = 1;
//1번 타이머 셋팅
if (분할횟수 > 1 && sumBV < 진입주문수량)
{
Main.SetTimer(1, 분할간격*1000);
}
}
//스팟에서 매수진입 이후에 매수청산 신호 발생
if (pst == 1 && Signal.signalKind == 2)
{
//1번 타이머 종료
Main.KillTimer(1);
var BCV = 0;
if (BNUM.length > 0)
{
//진입매수주문 미체결 객체 셋팅
for (var i = 0; i < BNUM.length; i++)
{
Account1.SetUnfillOrderNumber(BNUM[i]);
//미체결이 있으면
if ( Account1.Unfill.count > 0 )
{
//취소수량 합계
BCV = BCV+Account1.Unfill.count;
//미체결 주문 취소
Account1.OrderCancel(BNUM[i]);
}
}
}
//진입수량에서 취소수량 차감
var BXV = sumBV-BCV;
Account1.SetBalance(OC, 0);
if (BXV > 0 && Account1.Balance.count > 0)
{
//청산을 위해 매도주문 집행(수량은 BV, 매수5호가 지정가)
Account1.OrderSell(OC, Math.min(BXV,Account1.Balance.count), MarketData1.Bid(5), 0);
Main.MessageList("매수청산:",Math.min(BXV,Account1.Balance.count));
}
}
//매도진입신호 발생
if (Signal.signalKind == 3)
{
Main.MessageList("매도진입신호:");
SID = [];
SNUM = [];
sumSV = Math.min(Math.max(진입주문수량,1),V1);
//매수주문 집행(지정수량,현재가 지정가)
SID.push(Account1.OrderSell(OC, Math.min(Math.max(진입주문수량,1),V1), MarketData1.current,0));
Main.MessageList(SID.length,"차 매도주문:",SID[SID.length-1]);
//포지션은 1
pst = -1;
if (분할횟수 > 1 && sumSV < 진입주문수량)
{
//3번 타이머 셋팅
Main.SetTimer(3, 분할간격*1000);
}
}
//스팟에서 매도진입 이후에 매도청산 신호 발생
if (pst == -1 && Signal.signalKind == 4)
{
//3번 타이머 종료
Main.KillTimer(3);
var SCV = 0;
if (SNUM.length > 0)
{
//진입매수주문 미체결 객체 셋팅
for (var i = 0; i < SNUM.length; i++)
{
Account1.SetUnfillOrderNumber(SNUM[i]);
//미체결이 있으면
if ( Account1.Unfill.count > 0 )
{
//취소물량 합산
SCV = SCV+Account1.Unfill.count;
//미체결 주문 취소
Account1.OrderCancel(SNUM[i]);
}
}
}
//진입수량에서 미체결수량 차감
var SXV = sumSV-SCV;
Account1.SetBalance(OC, 0);
if (SXV > 0 && Account1.Balance.count > 0 && Account1.Balance.position == 1)
{
//청산을 위해 매수주문 집행(수량은 SXV, 매도5호가 지정가)
Account1.OrderBuy(OC, Math.min(SXV,Account1.Balance.count), MarketData1.Ask(5), 0);
Main.MessageList("매도청산:",Math.min(SXV,Account1.Balance.count));
}
}
}
function Main_OnTimer(nEventID)
{
if (nEventID == 1)
{
if (sumBV < 진입주문수량)
{
var VV = 0;
if (BID.length < 분할횟수-1)
VV = Math.min(V1,진입주문수량-sumBV)
else
VV = 진입주문수량-sumBV;
sumBV = sumBV + VV;
//매수주문 집행하고 아이디는 BID에 추가(신호수량, 현재가 지정가)
BID.push(Account1.OrderBuy(OC,VV, MarketData1.current,0));
Main.MessageList(BID.length,"차 매수주문:",BID[BID.length-1]);
}
if (BID.length == 분할횟수 || sumBV >= 진입주문수량)
{
Main.KillTimer(1);
}
}
if (nEventID == 3)
{
if (sumSV < 진입주문수량)
{
var VV = 0;
if (SID.length < 분할횟수-1)
VV = Math.min(V1,진입주문수량-sumSV)
else
VV = 진입주문수량-sumSV;
sumSV = sumSV + VV;
//매도주문 집행하고 아이디는 SID에 추가(신호수량, 현재가 지정가)
SID.push(Account1.OrderSell(OC,VV, MarketData1.current,0));
Main.MessageList(SID.length,"차 매도주문:",SID[SID.length-1]);
}
if (SID.length == 분할횟수 || sumSV >= 진입주문수량)
{
Main.KillTimer(3);
}
}
}
//주문응답
function Main_OnOrderResponse(OrderResponse)
{
//매수진입주문에 대한 응답이 오면
if (OrderResponse.orderID == BID[BID.length-1])
{
//주문번호 저장
BNUM.push(OrderResponse.orderNum);
Main.MessageList(BID.length,"차 주문응답:",OrderResponse.orderID,"|주문번호:",BNUM[BNUM.length-1]);
}
//매도진입주문에 대한 응답이 오면
if (OrderResponse.orderID == SID[SID.length-1])
{
//주문번호 저장
SNUM = OrderResponse.orderNum;
Main.MessageList(SID.length,"차 주문응답:",OrderResponse.orderID,"|주문번호:",SNUM[SNUM.length-1]);
}
}
JavaScript
복사