DDE객체 이용 방법에 대한 예제입니다.
DDE(Dynamic Data Exchange)는 증권사 HTS에서 실시간 시세 데이터를
엑셀(Excel) 등 다른 Windows 애플리케이션으로 연동해주는 기능입니다.
iM증권, NH투자증권에 제공되는 프로그램은 국내종목의 시세만 제공되며
NH선물, 한국투자증권, LS증권, NEXT증권, 유진투자선물에 제공되는 프로그램에는
해외파생 데이터만 제공됩니다.
만약 사용하는 프로그램에서 제공하지 않는 데이터를 사용하고자 하면
DDE로 데이터를 수신해 이용해 볼 수 있습니다.
예스스팟에서는
DDE를 이용하고자 하시면 스크립트 객체화면에 DDE객체를 추가하고
속성에서 사용하고자 하는 DDE의 Service, Topic을 지정하고
item지정해서 값을 가져와 사용하시면 됩니다.
키움DDE을 예로 설명하면
키움영웅문Global에서 DDE로 데이터를 수신하려면 DDE를 실행해야 합니다.
엑셀 데이터 연동서비스(DDE) 시작을 클릭하면 엑셀 데이터 연동서비스화면이 나타나고
필요한 종목과 값들을 설정할 수 있습니다.
설정완료 후 엑셀로 보내기를 하면 엑셀에 각 값들이 표시되는데
각 출력되는 값을 선택해 수식입력줄을 보시면 Service, Topic, item을 확인할 수 있습니다.
해당 값들 확인하시고 DDE 객체 속성화면에서
Service는 NFRun, Topic은 NQM26, 각 값의 필드코드를 item에 지정해 주시면 됩니다.
1.
전략내용
아래 전략은 예제5번을 기본으로 하는 식입니다.
차트에서 진입신호가 발생하면 현재가로 주문 후 30초 후에 미체결이 있으면 취소를 하고
청산신호가 발생하면 미체결된 수량을 제외하고 상대5호가로 주문을 집행하게 되는데
진입 신호가 발생할 때 DDE객체에서 값을 가져와서
매수진입주문은 나스닥100 선물이 일봉상 양봉이고 전일보다 종가가 클 때만 집행
매도진입주문은 나스닥100 선물이 일봉상 음봉이고 전일보다 종가가 작을 때만 집행합니다.
즉 위 주문이 만족하지 않는 진입은 건너뛰게 됩니다.
2.
스크립트 객체화면 설정
차트객체 : 객체명 Chart1 → 속성에서 차트와 동일 아이디 지정
계좌객체 : 객체명 Account1 → 속성에서 계좌번호 선택
DDE객체 : 객체명 DDE1 → 속성에서 Service, Topice, item들 지정
3.
스팟수식
var OC, MK, pst;
var BID, SID, BNUM, SNUM;
var 취소주문시간 = 30;//30초
var BV,SV;
function Main_OnStart()
{
Main.MessageList("Start");
//차트종목 종목코드
OC = Main.GetOrderCode(Chart1.GetCode(1));
//종목객체 요청
Main.ReqMarketData(OC);
pst = 0;
}
function Main_OnRcvMarketData(MarketData)
{
if (MarketData.code == OC)
{
MK = MarketData;
}
}
function Chart1_OnRiseSignal(Signal)
{
//매수진입신호 발생
if (Signal.signalKind == 1)
{
Main.MessageList("매수진입신호발생");
var cur = Number(DDE1.Request("10").replace(/,/g, ''));
var dayo = Number(DDE1.Request("16").replace(/,/g, ''));
var predayc = Number(DDE1.Request("346").replace(/,/g, ''));
Main.MessageList(DDE1.topic,"|현재가:",cur,"|시가",dayo,"|전일종가:",predayc);
if (cur > dayo && cur > predayc)
{
Main.MessageList("DDE 데이터 조건충족 : 매수주문실행");
//신호수량 저장
BV = Signal.count;
//매수주문 집행(신호수량, 현재가 지정가)
BID = Account1.OrderBuy(OC, BV, MK.current,0);
//포지션은 2
pst = 2;
//1번 300초 타이머 셋팅
Main.SetTimer(1, 취소주문시간*1000);
}
else
{
pst = 1;
Main.MessageList("DDE값 조건 미충족 : 매수진입주문안함");
}
}
//pst가 2이고 매수청산 신호 발생
if (pst == 2 && Signal.signalKind == 2)
{
//1번 타이머 종료
Main.KillTimer(1);
//진입매수주문 미체결 객체 셋팅
Account1.SetUnfillOrderNumber(BNUM);
//미체결이 있으면
if ( Account1.Unfill.count > 0 )
{
//진입수량에서 미체결수량 차감
BV = BV-Account1.Unfill.count;
//미체결 주문 취소
Account1.OrderCancel(BNUM);
}
Main.MessageList("매수청산:",BV);
//매수진입수량에서 미체결수량 차감후 0이 아니면(진입전량 체결이나 일부체결)
if (BV > 0)
{
//청산을 위해 매도주문 집행(수량은 BV, 매수5호가 지정가)
Account1.OrderSell(OC, BV, MK.Bid(5), 0);
}
}
//매도진입신호 발생
if (Signal.signalKind == 3)
{
Main.MessageList("매도진입신호발생");
var cur = Number(DDE1.Request("10").replace(/,/g, ''));
var dayo = Number(DDE1.Request("16").replace(/,/g, ''));
var predayc = Number(DDE1.Request("346").replace(/,/g, ''));
Main.MessageList(DDE1.topic,"|현재가:",cur,"|시가",dayo,"|전일종가:",predayc);
if (cur < dayo && cur < predayc)
{
Main.MessageList("DDE 데이터 조건충족 : 매도주문실행");
//신호수량 저장
SV = Signal.count;
//매도주문 집행(신호수량, 현재가 지정가)
SID = Account1.OrderSell(OC, SV,MK.current,0);
//포지션은 -1
pst = -2;
//3번 300초 타이머 셋팅
Main.SetTimer(3, 취소주문시간*1000);
}
else
{
pst = -1;
Main.MessageList("DDE값 조건 미충족 : 매도진입주문안함");
}
}
//pst가 -2이고 매도청산 신호 발생
if (pst == -2 && Signal.signalKind == 4)
{
//3번 타이머 종료
Main.KillTimer(3);
//진입매도주문 미체결 객체 셋팅
Account1.SetUnfillOrderNumber(SNUM);
//미체결이 있으면
if ( Account1.Unfill.count > 0 )
{
//진입수량에서 미체결수량 차감
SV = SV-Account1.Unfill.count;
//미체결 주문 취소
Account1.OrderCancel(SNUM);
}
Main.MessageList("매도청산:",SV);
//매도진입수량에서 미체결수량 차감후 0이 아니면(진입전량 체결이나 일부체결)
if (SV > 0)
{
//청산을 위해 매수주문 집행(수량은 SV, 매도5호가 지정가)
Account1.OrderBuy(OC, SV, MK.Ask(5), 0);
}
}
}
//주문응답
function Main_OnOrderResponse(OrderResponse)
{
//매수진입주문에 대한 응답이 오면
if (OrderResponse.orderID == BID)
{
//주문번호 저장
BNUM = OrderResponse.orderNum;
}
//매도진입주문에 대한 응답이 오면
if (OrderResponse.orderID == SID)
{
//주문번호 저장
SNUM = OrderResponse.orderNum;
}
}
//타이머 실행
function Main_OnTimer(nEventID)
{
//1번타이머
if (nEventID == 1)
{
//타이머 종료
Main.KillTimer(1);
//매수진입주문에 대해 미체결 셋팅
Account1.SetUnfillOrderNumber(BNUM);
//미체결이 있으면
if (Account1.Unfill.count > 0)
{
//매수진입수량에서 미체결수량 차감
BV = BV-Account1.Unfill.count;
Main.MessageList("매수진입취소:",BV);
//미체결주문 취소
Account1.OrderCancel(BNUM);
}
}
//3번타이머
if (nEventID == 3)
{
//타이머 종료
Main.KillTimer(3);
//매도진입주문에 대해 미체결 셋팅
Account1.SetUnfillOrderNumber(SNUM);
//미체결이 있으면
if (Account1.Unfill.count > 0)
{
//매수진입수량에서 미체결수량 차감
SV = SV-Account1.Unfill.count;
Main.MessageList("매도진입취소:",SV);
//미체결주문 취소
Account1.OrderCancel(SNUM);
}
}
}
JavaScript
복사



