커뮤니티
엑셀 객체 사용법
2026-09-20 19:12:20
89
글번호 233693
엑셀로 매수매도 결과를 출력하고 싶은데 참조할만한 간단한 예제가 없나요? 참조해서 작성하고 싶은데 처음 접근을 어떻게 해야할지 잘 모르겠습니다.
답변 1
예스스탁 예스스탁 답변
2026-10-06 16:31:22
안녕하세요
예스스탁입니다.
1
엑셀객체를 사용하기 위해서는
먼저 스크립트 객체 화면에서 엑셀객체를 추가하신 후에
속성에서 객체명과 미리 만들어 놓은 엑셀파일을 지정해 주셔야 합니다.
아래식에서는 Excel1입니다.
2
주의하실 부분은 특정엑셀파일을 사용하는 스팟수식은
실행되면 해당 엑셀파일이 자동으로 실행되고
스팟수식 종료하면 엑셀파일도 같이 종료됩니다.
메모리에 기억을 하고 있으므로
실행중에 엑셀파일 단독으로 종료하시면
프로그램 종료 후 다시 접속해셔야 해당
스팟수식을 정상적으로 사용할 수 있습니다.
3
엑셀객체는 값을 보내고 가져오기 위해4가지 함수를 많이 사용됩니다.
Excel1.GetData(nSheetIndex, sCell)
Excel1.SetData(nSheetIndex, sCell, sValue)
Excel1.SetArrayToRow(nSheetIndex, sCell, aValue)
Excel1.SetArrayToCol(nSheetIndex, sCell, aValue)
GetData함수는 쉬트번호와 셀을 지정해서 값을 가져오는 함수이고
SetData함수는 쉬트번호와 셀을 지정해서 지정한 값을 엑셀에 입력하는 함수입니다.
SetArrayToRow, SetArrayToCol은 특정 셀을 기준으로 행과 열에 여러개의 값을 한번에
입력할 때 사용합니다.
4
아래 예시 수식 참고하시기 바랍니다.
차트에서 신호발생하면 주문관련 항목과 체결수량등을 출력하게 됩니다.


스크립트객체설정
차트객체추가 -> 속성에서 객체명 Chart1, 시스템이 적용된 차트에 아이디 지정하고 동일아이디 지정
계좌객체추가 -> 속성에서 객체명 Account1, 주문낼 계좌번호 지정
엑셀객체추가 -> 속성에서 객체명 Excel, 엑셀파일 지정
var OC, MK, pst;
var BV,SV, BXV, SXV;
var BFV,SFV, BXFV, SXFV;
var BID, SID, BNUM, SNUM;
var BXID, SXID, BXNUM, SXNUM;
var RowCount;
function Main_OnStart()
{
Main.MessageList("Start");
//차트종목 종목코드
OC = Main.GetOrderCode(Chart1.GetCode(1));
//종목객체 요청
Main.ReqMarketData(OC);
pst = 0;
//A1셀부터 j1셀까지는 항목 이름값 입력
var str = ["시간","종목명","신호종류","주문아이디","주문가격","주문수량","주문번호","체결수량","미체결수량","기타"];
//A1시작으로 해당 행에 지정한 값을 출력
Excel1.SetArrayToRow(1, "A1", str);
RowCount = 1;
Main.MessageList(Excel1.GetRowCount(1),Excel1.GetColCount(1))
}
function Main_OnRcvMarketData(MarketData)
{
if (MarketData.code == OC)
{
MK = MarketData;
}
}
function Chart1_OnRiseSignal(Signal)
{
var d = new Date();
HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds();
//매수진입신호 발생
if (Signal.signalKind == 1)
{
RowCount = RowCount+1;
//신호수량 저장
BV = Signal.count;
//매수진입 체결수량 저장할 변수
BFV = 0;
//매수주문 집행(신호수량, 현재가 지정가)
BID = Account1.OrderBuy(OC, BV, MK.Ask(5),0);
//포지션은 1
pst = 1;
Excel1.SetData(1,"A"+RowCount, HHMMSS);
Excel1.SetData(1,"B"+RowCount, MK.name);
Excel1.SetData(1,"C"+RowCount, "매수진입");
Excel1.SetData(1,"D"+RowCount, BID);
Excel1.SetData(1,"E"+RowCount, MK.current);
Excel1.SetData(1,"F"+RowCount, BV);
}
//스팟에서 매수진입 이후에 매수청산 신호 발생
if (pst == 1 && Signal.signalKind == 2)
{
RowCount = RowCount+1;
//진입매수주문 미체결 객체 셋팅
Account1.SetUnfillOrderNumber(BNUM);
//미체결이 있으면
if ( Account1.Unfill.count > 0 )
{
//진입수량에서 미체결수량 차감
BV = BV-Account1.Unfill.count;
//미체결 주문 취소
Account1.OrderCancel(BNUM);
}
Main.MessageList("매수청산:",BV);
//매수진입수량에서 미체결수량 차감후 0이 아니면(진입전량 체결이나 일부체결)
if (BV > 0)
{
//신호수량 저장
BXV = BV;
//매수청산 체결수량 저장할 변수
BXFV = 0;
//청산을 위해 매도주문 집행(수량은 BV, 매수5호가 지정가)
BXID = Account1.OrderSell(OC, BV, MK.Bid(5), 0);
Excel1.SetData(1,"A"+RowCount, HHMMSS);
Excel1.SetData(1,"B"+RowCount, MK.name);
Excel1.SetData(1,"C"+RowCount, "매수청산");
Excel1.SetData(1,"D"+RowCount, BXID);
Excel1.SetData(1,"E"+RowCount, MK.Bid(5));
Excel1.SetData(1,"F"+RowCount, BXV);
}
}
//매도진입신호 발생
if (Signal.signalKind == 3)
{
//신호수량 저장
SV = Signal.count;
//매도진입 체결수량 저장할 변수
SFV = 0;
//매도주문 집행(신호수량, 현재가 지정가)
SID = Account1.OrderSell(OC, SV,MK.Bid(5),0);
//포지션은 -1
pst = -1;
RowCount = RowCount+1;
Excel1.SetData(1,"A"+RowCount, HHMMSS);
Excel1.SetData(1,"B"+RowCount, MK.name);
Excel1.SetData(1,"C"+RowCount, "매도진입");
Excel1.SetData(1,"D"+RowCount, SID);
Excel1.SetData(1,"E"+RowCount, MK.Bid(5));
Excel1.SetData(1,"F"+RowCount, SV);
}
//스팟에서 매도진입 이후에 매도청산 신호 발생
if (pst == -1 && 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)
{
SXV = SV;
//매도청산 체결수량 저장할 변수
SXFV = 0;
//청산을 위해 매수주문 집행(수량은 SV, 매도5호가 지정가)
SXID = Account1.OrderBuy(OC, SV, MK.Ask(5), 0);
RowCount = RowCount+1;
Excel1.SetData(1,"A"+RowCount, HHMMSS);
Excel1.SetData(1,"B"+RowCount, MK.name);
Excel1.SetData(1,"C"+RowCount, "매도청산");
Excel1.SetData(1,"D"+RowCount, SXID);
Excel1.SetData(1,"E"+RowCount, MK.Ask(5));
Excel1.SetData(1,"F"+RowCount, SXV);
}
}
}
//주문응답
function Main_OnOrderResponse(OrderResponse)
{
//매수진입주문에 대한 응답이 오면
if (OrderResponse.orderID == BID)
{
if (OrderResponse.isNormal == true)
{
//주문번호 저장
BNUM = OrderResponse.orderNum;
//엑셀의 주문아이디에서 동일 주문아이디를 찾아서 주문번호에 값 입력
for (var i = 1; i <= RowCount; i++)
{
if (OrderResponse.orderID == Excel1.GetData(1,"D"+i))
{
Excel1.SetData(1,"G"+i, BNUM);
}
}
}
else
{
//엑셀의 주문아이디에서 동일 주문아이디를 찾아서 기타에 주문오류로 표시
for (var i = 1; i <= RowCount; i++)
{
if (OrderResponse.orderID == Excel1.GetData(1,"D"+i))
{
Excel1.SetData(1,"J"+i, "주문오류");
}
}
}
}
//매수청산주문에 대한 응답이 오면
if (OrderResponse.orderID == BXID)
{
if (OrderResponse.isNormal == true)
{
//주문번호 저장
BXNUM = OrderResponse.orderNum;
//엑셀의 주문아이디에서 동일 주문아이디를 찾아서 주문번호에 값 입력
for (var i = 1; i <= RowCount; i++)
{
if (OrderResponse.orderID == Excel1.GetData(1,"D"+i))
{
Excel1.SetData(1,"G"+i, BXNUM);
}
}
}
else
{
//엑셀의 주문아이디에서 동일 주문아이디를 찾아서 기타에 주문오류로 표시
for (var i = 1; i <= RowCount; i++)
{
if (OrderResponse.orderID == Excel1.GetData(1,"D"+i))
{
Excel1.SetData(1,"J"+i, "주문오류");
}
}
}
}
//매도진입주문에 대한 응답이 오면
if (OrderResponse.orderID == SID)
{
if (OrderResponse.isNormal == true)
{
//주문번호 저장
SNUM = OrderResponse.orderNum;
//엑셀의 주문아이디에서 동일 주문아이디를 찾아서 주문번호에 값 입력
for (var i = 1; i <= RowCount; i++)
{
if (OrderResponse.orderID == Excel1.GetData(1,"D"+i))
{
Excel1.SetData(1,"G"+i, SNUM);
}
}
}
else
{
//엑셀의 주문아이디에서 동일 주문아이디를 찾아서 기타에 주문오류로 표시
for (var i = 1; i <= RowCount; i++)
{
if (OrderResponse.orderID == Excel1.GetData(1,"D"+i))
{
Excel1.SetData(1,"J"+i, "주문오류");
}
}
}
}
//매도청산주문에 대한 응답이 오면
if (OrderResponse.orderID == SXID)
{
if (OrderResponse.isNormal == true)
{
//주문번호 저장
SXNUM = OrderResponse.orderNum;
//엑셀의 주문아이디에서 동일 주문아이디를 찾아서 주문번호에 값 입력
for (var i = 1; i <= RowCount; i++)
{
if (OrderResponse.orderID == Excel1.GetData(1,"D"+i))
{
Excel1.SetData(1,"G"+i, SXNUM);
}
}
}
else
{
//엑셀의 주문아이디에서 동일 주문아이디를 찾아서 기타에 주문오류로 표시
for (var i = 1; i <= RowCount; i++)
{
if (OrderResponse.orderID == Excel1.GetData(1,"D"+i))
{
Excel1.SetData(1,"J"+i, "주문오류");
}
}
}
}
}
function Main_OnNotifyFill(NotifyFill)
{
//매수진입 주문에 대한 체결응답이 오면
if (NotifyFill.orderNum == BNUM)
{
BFV = BFV + NotifyFill.fillCount;
//엑셀의 주문번호에서 동일 주문번호를 찾아서 체결수량에 누적체결수량 입력
for (var i = 1; i <= RowCount; i++)
{
if (NotifyFill.orderNum == Excel1.GetData(1,"G"+i))
{
Excel1.SetData(1,"H"+i, BFV);
Excel1.SetData(1,"I"+i, BV-BFV);
}
}
}
//매수청산 주문에 대한 체결응답이 오면
if (NotifyFill.orderNum == BXNUM)
{
BXFV = BXFV + NotifyFill.fillCount;
//엑셀의 주문번호에서 동일 주문번호를 찾아서 체결수량에 누적체결수량 입력
for (var i = 1; i <= RowCount; i++)
{
if (NotifyFill.orderNum == Excel1.GetData(1,"G"+i))
{
Excel1.SetData(1,"H"+i, BXFV);
Excel1.SetData(1,"I"+i, BXV-BXFV);
}
}
}
//매수청산 주문에 대한 체결응답이 오면
if (NotifyFill.orderNum == SNUM)
{
SFV = SFV + NotifyFill.fillCount;
//엑셀의 주문번호에서 동일 주문번호를 찾아서 체결수량에 누적체결수량 입력
for (var i = 1; i <= RowCount; i++)
{
if (NotifyFill.orderNum == Excel1.GetData(1,"G"+i))
{
Excel1.SetData(1,"H"+i, SFV);
Excel1.SetData(1,"I"+i, SV-SFV);
}
}
}
//매수청산 주문에 대한 체결응답이 오면
if (NotifyFill.orderNum == SXNUM)
{
SXFV = SXFV + NotifyFill.fillCount;
//엑셀의 주문번호에서 동일 주문번호를 찾아서 체결수량에 누적체결수량 입력
for (var i = 1; i <= RowCount; i++)
{
if (NotifyFill.orderNum == Excel1.GetData(1,"G"+i))
{
Excel1.SetData(1,"H"+i, SXFV);
Excel1.SetData(1,"I"+i, SXV-SXFV);
}
}
}
}
5
참고로 스팟식에서 발생한 주문과 관련된 내용은
예스스팟 화면의 하단에 전체/체결/미체결탭에서
보실 수 있고 리스트 위에서 마우스 우클릭하면
엑셀로 보내기 기능을 이용하시면 됩니다.
즐거운 하루되세요