🔧 준비물
항목 | 내용 |
프로그램 | 키움증권 영웅문4 설치 |
Excel 버전 | Office 2016 이상 권장 (VBA 매크로 사용 가능해야 함) |
참고 종목 | "101W6000" (예: 코스피200 선물 근월물) |
환경 | Windows (DDE 지원 필요) |
환경설정 잘 모르시는 분들 참고 하세요 : https://infoportalhub.com/entry/DDEExcelHowtolink
📌 주요 기능 요약
기능 | 설명 |
실시간 수집 | DDE로 1초마다 주요 선물 데이터 수집 |
데이터 포인트 | 일자, 시간, 종목코드, 현재가, 거래량 등 총 30개+ 항목(VBA 코딩안에 항목있음) |
기술 분석 | 1분/5분/10분 봉 생성 → 이평선(MA) + 볼린저밴드 계산 |
자동화 | Excel VBA로 실시간 저장, 분석 자동 실행 |
🧮 1. DDE 실시간 연동 설정
1-1. 엑셀에 다음 수식 입력 (A1~AZ1)
excel(셀 안에 들어가는 수식입니다. - 항목 DDE 수식)
=NKRun|'101W6000'!'22' '<== 일자
=TEXT(NOW(),"hh:mm:ss") '<== 시간
=NKRun|'101W6000'!'10' '<== 현재가
=NKRun|'101W6000'!'13' '<== 거래량
=NKRun|'101W6000'!'16' '<== 시가
=NKRun|'101W6000'!'17' '<== 고가
=NKRun|'101W6000'!'18' '<== 저가
=NKRun|'101W6000'!'10' '<== 종가
:
:
VBA코딩안에 해당 코드 확인 할수 있습니다.(밑에 화면 캡쳐도 있습니다.)
📈 2. VBA 코드 (1초 단위 실시간 기록 + 분석 자동화)
2-1. Excel VBA 코드: 실시간 데이터 저장
vba
' 모듈 전체: 실시간 수집 + 기술분석 계산 + 버튼 제어
Dim isRunning As Boolean
Dim startTime As Double
'시작
Sub 시작버튼_Click()
If isRunning Then Exit Sub
isRunning = True
Application.OnTime Now + TimeValue("00:00:01"), "기록반복"
End Sub
'중지
Sub 중지버튼_Click()
If isRunning Then
On Error Resume Next
Application.OnTime EarliestTime:=nextRunTime, Procedure:="기록반복", Schedule:=False
isRunning = False
MsgBox "수집이 중지되었습니다.", vbInformation
End If
End Sub
'초기화
Sub 초기화버튼_Click()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
If MsgBox("데이터를 초기화할까요?", vbYesNo + vbQuestion, "초기화 확인") = vbYes Then
ws.Rows("7:" & ws.Rows.Count).ClearContents
MsgBox "초기화 완료!"
End If
End Sub
🧠 3. 1분/5분/10분봉 생성 및 기술 분석
3-1. 데이터 집계 (엑셀 수식 or VBA)
vba
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
Dim r As Long: r = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
' 실시간 수집 (6행 기준 DDE 데이터 사용)
ws.Cells(r, 1).Value = "'" & Format(Now, "yyyy/mm/dd") ' 일자
ws.Cells(r, 2).Value = Format(Now, "hh:nn:ss") ' 시간
ws.Cells(r, 3).Value = ws.Range("C6").Value ' 종목코드
ws.Cells(r, 4).Value = ws.Range("D6").Value ' 종목명
ws.Cells(r, 5).Value = ws.Range("E6").Value ' 현재가
ws.Cells(r, 6).Value = ws.Range("F6").Value ' 기준가
ws.Cells(r, 7).Value = ws.Range("G6").Value ' 전일대비
ws.Cells(r, 8).Value = ws.Range("H6").Value ' 등락률
ws.Cells(r, 9).Value = ws.Range("I6").Value ' 거래량
ws.Cells(r, 10).Value = ws.Range("J6").Value ' 거래대금
ws.Cells(r, 11).Value = ws.Range("K6").Value ' 체결량
ws.Cells(r, 12).Value = ws.Range("L6").Value ' 체결강도
ws.Cells(r, 13).Value = ws.Range("M6").Value ' 상한가
ws.Cells(r, 14).Value = ws.Range("N6").Value ' 하한가
ws.Cells(r, 15).Value = ws.Range("O6").Value ' 시가
ws.Cells(r, 16).Value = ws.Range("P6").Value ' 고가
ws.Cells(r, 17).Value = ws.Range("Q6").Value ' 저가
ws.Cells(r, 18).Value = ws.Range("R6").Value ' 종가
ws.Cells(r, 19).Value = ws.Range("S6").Value ' 전일종가
ws.Cells(r, 20).Value = ws.Range("T6").Value ' 우선매도잔량
ws.Cells(r, 21).Value = ws.Range("U6").Value ' 우선매수잔량
ws.Cells(r, 22).Value = ws.Range("V6").Value ' 우선매도건수
ws.Cells(r, 23).Value = ws.Range("W6").Value ' 우선매수건수
ws.Cells(r, 24).Value = ws.Range("X6").Value ' 총매도잔량
ws.Cells(r, 25).Value = ws.Range("Y6").Value ' 총매수잔량
ws.Cells(r, 26).Value = ws.Range("Z6").Value ' 총매도건수
ws.Cells(r, 27).Value = ws.Range("AA6").Value ' 총매수건수
ws.Cells(r, 28).Value = ws.Range("AB6").Value ' 미결제약정
ws.Cells(r, 28).Value = ws.Range("AC6").Value ' 미결제전일대비
ws.Cells(r, 30).Value = ws.Range("AD6").Value ' 이론가
ws.Cells(r, 31).Value = ws.Range("AE6").Value ' 전일시가
ws.Cells(r, 32).Value = ws.Range("AF6").Value ' 전일고가
ws.Cells(r, 33).Value = ws.Range("AG6").Value ' 전일저가
✅ 전체 구문 설명
vba
ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
이 표현은 다음과 같은 의미를 가집니다:
🔍 한 줄씩 완전 분해 설명
파트 | 의미 |
ws | 현재 작업 중인 Worksheet 객체 (예: Sheet1) |
ws.Rows.Count | 해당 시트의 최대 행 수 → 1048576 (엑셀 365 기준) |
ws.Cells(ws.Rows.Count, 1) | A열의 마지막 셀 = A1048576 |
.End(xlUp) | A열 맨 아래에서 위쪽으로 올라가다가 데이터가 있는 셀을 만나면 멈춤 |
.Row | 그 셀의 행 번호 반환 (예: 데이터가 A500까지 있다면 → 500) |
+ 1 | 다음 줄(501)에 데이터를 쓰기 위해 1을 더함 |
🧠 예시로 쉽게 이해하기
예: A열이 아래와 같이 되어 있다고 가정
A열 | 값 |
A1 | 일자 |
A2 | 2025/04/14 |
A3 | 2025/04/15 |
A4 | (비어 있음) |
이때:
vba
ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
👉 A3까지 데이터가 있으므로 → 3
vba
ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
👉 4 반환 → 다음 데이터를 A4에 추가 가능
💡 실전에서 주로 어떻게 쓰이나?
✅ 실시간 데이터 누적 저장 구조에서
vba
Dim r As Long
r = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
ws.Cells(r, 1).Value = Now
ws.Cells(r, 2).Value = 현재가
이렇게 하면, 매번 자동으로 아래 행으로 한 줄씩 누적됩니다.
✨ 응용 팁
목적예시 | 코드 |
B열 기준 마지막 행 찾기 | ws.Cells(ws.Rows.Count, 2).End(xlUp).Row |
비어 있는 셀에 데이터 쓰기 | ws.Cells(마지막행 + 1, 열번호).Value = 값 |
전체 시트 마지막 행 찾기 | ws.UsedRange.Rows.Count (단, 정확도 떨어짐) |
✅ 결론
vba
ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
이 한 줄은
"A열에서 마지막으로 값이 있는 셀을 찾고, 그 아래 셀의 행 번호를 반환한다."
→ 실시간 데이터 누적 저장, 로그 기록, 거래 내역 저장 등에 필수적인 VBA 패턴입니다.
3-2. 이동평균선 (MA) 수식 (엑셀 수식 or VBA)
vba
' 기술 분석 (현재가: 열 6 기준)
Dim ma5 As Double, ma10 As Double, ma20 As Double, ma60 As Double, ma120 As Double
Dim bbAvg As Double, bbStd As Double
Dim hasEnoughData As Boolean: hasEnoughData = False
On Error Resume Next
If r >= 6 + 120 Then hasEnoughData = True
If Not hasEnoughData Then Exit Sub
On Error GoTo 0
' 이동평균선
ma5 = WorksheetFunction.Average(ws.Range("E" & r - 4 & ":E" & r))
ma10 = WorksheetFunction.Average(ws.Range("E" & r - 9 & ":E" & r))
ma20 = WorksheetFunction.Average(ws.Range("E" & r - 19 & ":E" & r))
ma60 = WorksheetFunction.Average(ws.Range("E" & r - 59 & ":E" & r))
ma120 = WorksheetFunction.Average(ws.Range("E" & r - 119 & ":E" & r))
3-3. 볼린저밴드 계산 (엑셀 수식 or VBA)
vba
' 볼린저 밴드
Set last20 = ws.Range("E" & r - 19 & ":E" & r)
bbStd = WorksheetFunction.StDev(last20)
bbAvg = ma20
📁 부록: 주요 컬럼명 정리 (필요 시 CSV 헤더용)
일자,시간,종목코드,종목명,현재가,기준가,전일대비,등락률,거래량,거래대금,체결량,체결강도,
상한가,하한가,시가,고가,저가,종가,전일종가,우선매도잔량,우선매수잔량,
우선매도건수,우선매수건수,총매도잔량,총매수잔량,총매도건수,총매수건수,
미결제약정,미결제전일대비,이론가,전일시가,전일저가
✅ 시트 구성:
- Sheet1, Sheet2, Sheet3 (현재 vba는 Sheet1에 적용했음.)
✅ 데이터 구조 요약 (Sheet1 기준)
- 5번째 row (엑셀 기준 6행): 타이틀 행 (일자, 시간, 종목코드, 종목명, 현재가, … 1분봉, 5분봉, 10분봉, 이동평균선, 볼린저밴드)
- 6번째 row (엑셀 기준 7행)부터: 실시간 데이터 누적 기록
이제 요청하신 VBA 구성 요소는 다음과 같이 작성될 예정입니다:
9시 장시작 후 엑셀로 저장하셨다가 자동매매,매수,매도 하실때 자료의 데이터를 활용할수 있습니다.
📌 최종 구현 항목 요약
항목 | 설명 |
✅ 시작 버튼 | 실시간 DDE 데이터를 1초마다 Sheet1의 7행부터 누적 저장 |
✅ 중지 버튼 | 실시간 저장 중지 |
✅ 초기화 버튼 | Sheet1의 7행 이후 데이터 전체 삭제 |
✅ 실시간 계산 | 각 Row 마지막에 1분/5분/10분봉, 이동평균선(5/10/20/60/120), 볼린저밴드(상한/중심/하한) 자동 계산 |
✅ 버튼 UI | 시트에 명시적으로 표시, 실행 가능하게 매핑됨 |
다음은 업로드하신 Excel 구조를 기준으로 완전 자동화된 실시간 데이터 기록 + 분석 + 버튼 UI까지 포함한 VBA 전체 코드입니다. 아래 내용을 Excel VBA 편집기 (Alt + F11)에 붙여 넣고, Sheet1에 버튼을 연결하면 작동합니다.
✅ 1. VBA 모듈 코드 (통합)
vba
' 모듈 전체: 실시간 수집 + 기술분석 계산 + 버튼 제어
Dim isRunning As Boolean
Dim startTime As Double
'시작
Sub 시작버튼_Click()
If isRunning Then Exit Sub
isRunning = True
Application.OnTime Now + TimeValue("00:00:01"), "기록반복"
End Sub
'중지
Sub 중지버튼_Click()
If isRunning Then
On Error Resume Next
Application.OnTime EarliestTime:=nextRunTime, Procedure:="기록반복", Schedule:=False
isRunning = False
MsgBox "수집이 중지되었습니다.", vbInformation
End If
End Sub
'초기화
Sub 초기화버튼_Click()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
If MsgBox("데이터를 초기화할까요?", vbYesNo + vbQuestion, "초기화 확인") = vbYes Then
ws.Rows("7:" & ws.Rows.Count).ClearContents
MsgBox "초기화 완료!"
End If
End Sub
'반복 호출
Sub 기록반복()
If Not isRunning Then Exit Sub
기록저장
nextRunTime = Now + TimeValue("00:00:01")
Application.OnTime EarliestTime:=nextRunTime, Procedure:="기록반복", Schedule:=True
End Sub
' 실시간 데이터 저장 + 기술지표 계산(이동평균선,볼린저밴드)
Sub 기록저장()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
Dim r As Long: r = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
' 실시간 수집 (6행 기준 DDE 데이터 사용)
ws.Cells(r, 1).Value = "'" & Format(Now, "yyyy/mm/dd") ' 일자
ws.Cells(r, 2).Value = Format(Now, "hh:nn:ss") ' 시간
ws.Cells(r, 3).Value = ws.Range("C6").Value ' 종목코드
ws.Cells(r, 4).Value = ws.Range("D6").Value ' 종목명
ws.Cells(r, 5).Value = ws.Range("E6").Value ' 현재가
ws.Cells(r, 6).Value = ws.Range("F6").Value ' 기준가
ws.Cells(r, 7).Value = ws.Range("G6").Value ' 전일대비
ws.Cells(r, 8).Value = ws.Range("H6").Value ' 등락률
ws.Cells(r, 9).Value = ws.Range("I6").Value ' 거래량
ws.Cells(r, 10).Value = ws.Range("J6").Value ' 거래대금
ws.Cells(r, 11).Value = ws.Range("K6").Value ' 체결량
ws.Cells(r, 12).Value = ws.Range("L6").Value ' 체결강도
ws.Cells(r, 13).Value = ws.Range("M6").Value ' 상한가
ws.Cells(r, 14).Value = ws.Range("N6").Value ' 하한가
ws.Cells(r, 15).Value = ws.Range("O6").Value ' 시가
ws.Cells(r, 16).Value = ws.Range("P6").Value ' 고가
ws.Cells(r, 17).Value = ws.Range("Q6").Value ' 저가
ws.Cells(r, 18).Value = ws.Range("R6").Value ' 종가
ws.Cells(r, 19).Value = ws.Range("S6").Value ' 전일종가
ws.Cells(r, 20).Value = ws.Range("T6").Value ' 우선매도잔량
ws.Cells(r, 21).Value = ws.Range("U6").Value ' 우선매수잔량
ws.Cells(r, 22).Value = ws.Range("V6").Value ' 우선매도건수
ws.Cells(r, 23).Value = ws.Range("W6").Value ' 우선매수건수
ws.Cells(r, 24).Value = ws.Range("X6").Value ' 총매도잔량
ws.Cells(r, 25).Value = ws.Range("Y6").Value ' 총매수잔량
ws.Cells(r, 26).Value = ws.Range("Z6").Value ' 총매도건수
ws.Cells(r, 27).Value = ws.Range("AA6").Value ' 총매수건수
ws.Cells(r, 28).Value = ws.Range("AB6").Value ' 미결제약정
ws.Cells(r, 28).Value = ws.Range("AC6").Value ' 미결제전일대비
ws.Cells(r, 30).Value = ws.Range("AD6").Value ' 이론가
ws.Cells(r, 31).Value = ws.Range("AE6").Value ' 전일시가
ws.Cells(r, 32).Value = ws.Range("AF6").Value ' 전일고가
ws.Cells(r, 33).Value = ws.Range("AG6").Value ' 전일저가
' 기술 분석 (현재가: 열 6 기준)
Dim ma5 As Double, ma10 As Double, ma20 As Double, ma60 As Double, ma120 As Double
Dim bbAvg As Double, bbStd As Double
Dim hasEnoughData As Boolean: hasEnoughData = False
On Error Resume Next
If r >= 6 + 120 Then hasEnoughData = True
If Not hasEnoughData Then Exit Sub
On Error GoTo 0
' 이동평균선
ma5 = WorksheetFunction.Average(ws.Range("E" & r - 4 & ":E" & r))
ma10 = WorksheetFunction.Average(ws.Range("E" & r - 9 & ":E" & r))
ma20 = WorksheetFunction.Average(ws.Range("E" & r - 19 & ":E" & r))
ma60 = WorksheetFunction.Average(ws.Range("E" & r - 59 & ":E" & r))
ma120 = WorksheetFunction.Average(ws.Range("E" & r - 119 & ":E" & r))
' 볼린저 밴드
Set last20 = ws.Range("E" & r - 19 & ":E" & r)
bbStd = WorksheetFunction.StDev(last20)
bbAvg = ma20
' 결과 화면 디스플레이 (열 순서: 35 ~ 42)
ws.Cells(r, 35).Value = ma5
ws.Cells(r, 36).Value = ma10
ws.Cells(r, 37).Value = ma20
ws.Cells(r, 38).Value = ma60
ws.Cells(r, 39).Value = ma120
ws.Cells(r, 40).Value = bbAvg + 2 * bbStd
ws.Cells(r, 41).Value = bbAvg
ws.Cells(r, 42).Value = bbAvg - 2 * bbStd
End Sub
✅ 2. Sheet1 버튼 UI 구성 (엑셀 내부)
- Sheet1 열기
- [개발도구] 탭 → [삽입] → 버튼(양식 컨트롤) 선택
- 시트 상단에 아래 버튼 3개 삽입 후 각각 매크로 연결:
버튼이름 | 연결할 매크로 |
▶ 시작 | 시작버튼 |
⏹ 중지 | 중지버튼 |
🔄 초기화 | 초기화버튼 |
📁 저장 시 주의사항
- 반드시 .xlsm 형식으로 저장해야 VBA가 포함됩니다.
- 자동 실행 방지를 위해 Application.OnTime 사용
📌 알아 두면 좋은 것들
✅ VBA에서 "일자"를 '2025/04/11 형식으로 기록하는 방법
vba
ws.Cells(r, 1).Value = "'" & Format(Date, "yyyy/mm/dd")
- 앞에 '를 붙이면 Excel은 해당 값을 문자열로 인식하고, 날짜 자동 변환을 방지합니다.
- Format(..., "yyyy/mm/dd")는 슬래시 포함 형식
🎯 수정된 코드 (기록저장() 안에 있는 '일자')
vba
ws.Cells(r, 1).Value = Format(Date, "yyyy/mm/dd") ' ← 처음에 사용한것
'결과 : 13/4/25
ws.Cells(r, 1).Value = "'" & Format(Date, "yyyy/mm/dd") ' ← 문자열로 일자 저장
'결과 : '2025/04/13