📘 프로젝트 명:Excel VBA + 7단계 : 조건매매 전략 필터링 및 최적화

반응형

🔍 개요

조건매매 시스템을 고도화할수록 중요한 것은 단 하나의 전략만 사용하는 것이 아니라,
여러 조건 전략을 조합하거나 필터링하여 가장 수익성이 높은 조합을 찾는 것입니다.
이 단계에서는 Excel VBA로 구축한 자동매매 시스템에서 전략별 필터 조건을 설정하고, 이를 자동으로 비교 분석하여 최적 전략을 도출하는 방법을 설명합니다.


✅ 전략 최적화란?

전략 최적화란 다양한 매매 조건(전략)을 동시에 시뮬레이션하고,
그 중 수익률, 승률, MDD(최대 손실) 등이 가장 우수한 전략 조합을 찾는 과정을 말합니다.


📊 예시 전략 조건 리스트

전락코드 조건1 조건2 설명
S1 고가 돌파 MA20 상향 돌파 공격형 추세 전략
S2 저가 이탈 거래량 급증 반전+공매도 전략
S3 볼린저밴드 하단 이탈 RSI < 30 저점 매수 전략
S4 MA5 > MA20 고가 근접 중기 모멘텀 전략

🧠 전략 필터링을 위한 VBA 구조 설계

📌 1. 전략 조건별로 시그널 구분하기

vba(module1.bas)

Sub 조건매매시그널_감지(r As Long)
    Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
    Dim currClose As Double: currClose = ws.Cells(r, 5).Value
    Dim prevHigh As Double: prevHigh = ws.Cells(r - 1, 16).Value
    Dim prevLow As Double: prevLow = ws.Cells(r - 1, 17).Value
    Dim prevVols As Range: Set prevVols = ws.Range("I" & r - 5 & ":I" & r - 1)
    
    Dim volAvg As Double: volAvg = WorksheetFunction.Average(prevVols)
    Dim currVol As Double: currVol = ws.Cells(r, 9).Value

	'추가부분
    Dim ma20 As Double: ma20 = ws.Cells(r, 37).Value    ' MA20
    Dim ma60 As Double: ma60 = ws.Cells(r, 38).Value    ' MA60
    Dim bbLow As Double: bbLow = ws.Cells(r, 42).Value  ' 볼린저 하단
    Dim rsi As Double: rsi = ws.Cells(r, 55).Value      ' RSI는 별도 계산되어 있어야 함

    ' 🎯 전략별 조건 시그널 기록(추가/변경부분)
    If currClose > prevHigh And ma20 > ma60 Then
        ws.Cells(r, 50).Value = "📥 매수 시그널 - S1"
    ElseIf currClose < prevLow And currVol > volAvg * 2 Then
        ws.Cells(r, 50).Value = "📤 매도 시그널 - S2"
    ElseIf currClose < bbLow And rsi < 30 Then
        ws.Cells(r, 50).Value = "📥 매수 시그널 - S3"
    End If

End Sub

📌 전략별 구분 텍스트가 핵심입니다. (- S1, - S2, - S3 등)


✅ 요약: 이 함수의 성격

항목 설명
함수명 Sub 전략별_성과분석()
목적 Sheet1의 시그널 로그를 분석해 전략별 거래 수, 승률, 평균 수익률을 계산
실행 방식 수동 실행 (버튼 또는 매크로에서 직접 호출)
실행 빈도 매매일 종료 후 1회 실행 또는 수시 실행

 

 

 

 

📌 2. 전략별 성과 분석 자동화및 절차

전략별로 수익률, 승률, 거래횟수를 구분 분석하는 함수 예시:

  1. 엑셀에서 Alt + F11 눌러 VBA 편집기 열기
  2. 메뉴 → 삽입 → 모듈 클릭 → 기존 ReportModule에 추가함
  3. 그 안에 아래 코드를 붙여넣기:
vba(ReportModule.bas)

Sub 전략별_성과분석()
    Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
    Dim rpt As Worksheet
    Set rpt = ThisWorkbook.Sheets.Add(After:=ws)
    rpt.Name = "전략분석"

    Dim 전략들 As Variant: 전략들 = Array("S1", "S2", "S3")
    Dim i As Long, r As Long, lastRow As Long: lastRow = ws.Cells(ws.Rows.Count, 50).End(xlUp).Row

    rpt.Range("A1:D1").Value = Array("전략코드", "거래횟수", "승률", "평균수익률")
    
    For i = 0 To UBound(전략들)
        Dim countAll As Long, countWin As Long, sumProfit As Double

        For r = 7 To lastRow
            If ws.Cells(r, 50).Value Like "*" & 전략들(i) Then
                countAll = countAll + 1
                Dim p As Variant: p = ws.Cells(r, 54).Value
                If IsNumeric(p) Then
                    sumProfit = sumProfit + p
                    If p > 0 Then countWin = countWin + 1
                End If
            End If
        Next r

        rpt.Cells(i + 2, 1).Value = 전략들(i)
        rpt.Cells(i + 2, 2).Value = countAll
        rpt.Cells(i + 2, 3).Value = Format(countWin / countAll, "0.00%")
        rpt.Cells(i + 2, 4).Value = Format(sumProfit / countAll, "0.00%")
    Next i

    MsgBox "전략별 성과 분석 완료!"
End Sub

✅ 실행 방법

  • 엑셀로 돌아가 Alt + F8 → 전략별_성과분석 선택 → 실행하면
  • 새로운 시트 전략분석이 자동 생성되고, 전략별 통계가 정리됩니다.

❗주의할 점

체크포인트 설명
Sheet1에 매매 기록이 누적돼 있어야 함 특히 50열(시그널), 54열(수익률)
시그널에 반드시 - S1, - S2 등 전략명이 포함되어 있어야 매핑 가능  
같은 전략이 많아질수록 Array("S1", "S2", "S3") 확장 가능  

📂 결과 시트 예시

전략코드 거래횟수 승률 평균수익률
S1 23 65.2% 0.83%
S2 17 52.9% -0.12%
S3 19 78.9% 1.11%

📈 전략 최적화 실전 팁

전략 테스트 방식 설명
조건 A+B 조합 vs A 단독 복합 전략이 더 효과적인지 비교
성과 기준 정렬 평균 수익률, 승률, MDD 기준으로 랭킹
조건별 시트 분리 저장 전략별 성과 시트를 별도로 만들어 관리
전략 타임필터 적용 오전/오후 시간대에 따라 전략 분리 (예: S1_AM, S1_PM)

✅ 결론

전략별_성과분석() 함수는 리포트 자동 생성 전용 함수이기 때문에, 반드시 전용 모듈로 따로 분리하는 것이 안전하고 유지보수에 유리합니다.

 

전략 최적화는 단일 조건식에 의존하지 않고, 다양한 전략 조건을 필터링 및 조합하여 성과를 비교함으로써
가장 유효한 전략을 찾아내고 실전 매매에 반영할 수 있도록 만드는 핵심 과정입니다.

Excel VBA 기반 자동화 시스템으로 이 과정을 구성하면:

  • 전략별 수익률을 정량적으로 비교
  • 시뮬레이션을 반복하면서 조건을 최적화
  • 결국 실전에서 승률 높은 전략 조합을 확보할 수 있습니다.

📘전체 Excel VBA 소스 코드

Source Code Icon

 

 

vba(Module1.bas)

' 모듈 전체: 실시간 수집 + 기술분석 계산 + 버튼 제어
Dim isRunning As Boolean
Dim startTime As Double
Dim nextRunTime As Date
Dim rStart As Long, rr As Long
Dim priceRange As Range, volRange As Range
Dim functionType As Variant
'시작
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
    
    ' 장 종료 여부 확인
    If Time > TimeSerial(15, 45, 0) Then
        isRunning = False
        MsgBox "장이 종료되었습니다. 수집을 자동 중지합니다.", vbExclamation
        Exit Sub
    End If
    
    ' 실시간 데이터 저장
    기록저장
    
    ' 다음 예약
    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, 29).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
    
        
    ' --- 봉 차트 계산 영역 추가 ---
    Dim minuteNow As Date: minuteNow = Int(Now * 24 * 60) / (24 * 60)

    ' Helper function: 봉 생성 함수
    For Each functionType In Array(1, 5, 10) ' 1분봉, 5분봉, 10분봉
        rStart = 7
        For rr = r - 1 To 7 Step -1
            If ws.Cells(rr, 2).Value = "" Then Exit For
            If IsDate(ws.Cells(rr, 2).Value) Then
                If TimeValue(ws.Cells(rr, 1).Value) <= TimeSerial(Hour(Now), Minute(Now) - functionType, 0) Then
                    rStart = rr + 1
                    Exit For
                End If
            End If
        Next rr

        ' 시가, 종가, 고가, 저가 계산
        If r >= rStart Then
            Set priceRange = ws.Range("E" & rStart & ":E" & r)
            Set volRange = ws.Range("I" & rStart & ":I" & r)
            Dim o As Double, h As Double, l As Double, c As Double, v As Double
            o = ws.Cells(rStart, 5).Value
            h = WorksheetFunction.Max(priceRange)
            l = WorksheetFunction.Min(priceRange)
            c = ws.Cells(r, 5).Value
            v = WorksheetFunction.Sum(volRange)
            
            ' 결과 셀 위치: 1분봉(열 43), 5분봉(열 44), 10분봉(열 45)
            Select Case functionType
                Case 1: ws.Cells(r, 43).Value = c ' 1분봉 종가로 표시
                Case 5: ws.Cells(r, 44).Value = c
                Case 10: ws.Cells(r, 45).Value = c
            End Select
        End If
    Next
        
'        ' --- 1/5/10분봉 생성 ---
'
'    For Each functionType In Array(1, 5, 10)
'        rStart = 7
'        For rr = r - 1 To 7 Step -1
'            If TimeValue(ws.Cells(rr, 1).Value) <= TimeSerial(Hour(Now), Minute(Now) - functionType, 0) Then
'                rStart = rr + 1
'                Exit For
'            End If
'        Next rr
'
'        If r >= rStart Then
'            Set priceRange = ws.Range("E" & rStart & ":E" & r)
'            c = ws.Cells(r, 5).Value
'
'            Select Case functionType
'                Case 1: ws.Cells(r, 43).Value = c
'                Case 5: ws.Cells(r, 44).Value = c
'                Case 10: ws.Cells(r, 45).Value = c
'            End Select
'        End If
'    Next
    
    ' 조건 시그널 감지
    조건매매시그널_감지 r
    
    ' ? 매수/매도 조건 처리 추가
    조건매매_매수매도판단 r


End Sub


' 조건 시그널 감지 예시
'Sub 조건매매시그널_감지(r As Long)
'    Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
'
'    Dim currClose As Double: currClose = ws.Cells(r, 5).Value ' 현재가
'    Dim prevHigh As Double: prevHigh = ws.Cells(r - 1, 16).Value ' 이전봉 고가
'    Dim prevLow As Double: prevLow = ws.Cells(r - 1, 17).Value ' 이전봉 저가
'    Dim prevVols As Range: Set prevVols = ws.Range("I" & r - 5 & ":I" & r - 1)
'
'    Dim volAvg As Double: volAvg = WorksheetFunction.Average(prevVols)
'    Dim currVol As Double: currVol = ws.Cells(r, 9).Value
'
'    ' 시그널 조건
'    If currClose > prevHigh Then
'        ws.Cells(r, 50).Value = "?? 고가 돌파"
'    ElseIf currClose < prevLow Then
'        ws.Cells(r, 50).Value = "?? 저가 이탈"
'    ElseIf currVol > volAvg * 2 Then
'        ws.Cells(r, 50).Value = "?? 거래량 급증"
'    End If
'End Sub

Sub 조건매매시그널_감지(r As Long)
    Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
    Dim currClose As Double: currClose = ws.Cells(r, 5).Value
    Dim prevHigh As Double: prevHigh = ws.Cells(r - 1, 16).Value
    Dim prevLow As Double: prevLow = ws.Cells(r - 1, 17).Value
    Dim prevVols As Range: Set prevVols = ws.Range("I" & r - 5 & ":I" & r - 1)
    
    Dim volAvg As Double: volAvg = WorksheetFunction.Average(prevVols)
    Dim currVol As Double: currVol = ws.Cells(r, 9).Value
    
    Dim ma20 As Double: ma20 = ws.Cells(r, 37).Value     ' MA20
    Dim ma60 As Double: ma60 = ws.Cells(r, 38).Value     ' MA60
    Dim bbLow As Double: bbLow = ws.Cells(r, 42).Value   ' 볼린저 하단
    Dim rsi As Double: rsi = ws.Cells(r, 55).Value              ' RSI는 별도 계산되어 있어야 함

    ' ?? 전략별 조건 시그널 기록
    If currClose > prevHigh And ma20 > ma60 Then
        ws.Cells(r, 50).Value = "?? 매수 시그널 - S1"
    ElseIf currClose < prevLow And currVol > volAvg * 2 Then
        ws.Cells(r, 50).Value = "?? 매도 시그널 - S2"
    ElseIf currClose < bbLow And rsi < 30 Then
        ws.Cells(r, 50).Value = "?? 매수 시그널 - S3"
    End If

'    If currClose > prevHigh Then
'        ws.Cells(r, 50).Value = "?? 매수 시그널 - 고가 돌파"
'        ws.Cells(r, 51).Value = "?? 매수"
'        ws.Cells(r, 52).Value = currClose     ' 매수가
'    ElseIf currClose < prevLow Then
'        ws.Cells(r, 50).Value = "?? 매도 시그널 - 저가 이탈"
'        ws.Cells(r, 51).Value = "?? 매도"
'        ws.Cells(r, 52).Value = currClose     ' 매도가
'    ElseIf currVol > volAvg * 2 Then
'        ws.Cells(r, 50).Value = "?? 변동 시그널 - 거래량 급증"
'        'ws.Cells(r, 51).Value = "?? 매수"
'        'ws.Cells(r, 52).Value = currClose     ' 매수가
'    End If
End Sub

Sub 조건매매_매수매도판단(r As Long)
    Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
    Dim currClose As Double: currClose = ws.Cells(r, 5).Value
    Dim signalText As String: signalText = ws.Cells(r, 50).Value
    
    ' ?? 매수 진입 조건
    If signalText Like "*매수 시그널*" Then
        ws.Cells(r, 51).Value = "?? 매수"
        ws.Cells(r, 52).Value = currClose ' 매수가
        
    ' ?? 매도 진입 조건 (공매도)
    ElseIf signalText Like "*매도 시그널*" Then
        ws.Cells(r, 51).Value = "?? 매도"
        ws.Cells(r, 52).Value = currClose ' 매도진입가

    ' ?? 익절/손절 판별: 직전 매수 포지션 기준
    ElseIf ws.Cells(r - 5, 51).Value = "?? 매수" Then
        Dim buyPrice As Double: buyPrice = ws.Cells(r - 5, 52).Value
        If currClose >= buyPrice * 1.02 Then
            ws.Cells(r, 51).Value = "?? 매도(익절)"
            ws.Cells(r, 53).Value = currClose
            ws.Cells(r, 54).Value = Format((currClose - buyPrice) / buyPrice, "0.00%")
        ElseIf currClose <= buyPrice * 0.99 Then
            ws.Cells(r, 51).Value = "?? 매도(손절)"
            ws.Cells(r, 53).Value = currClose
            ws.Cells(r, 54).Value = Format((currClose - buyPrice) / buyPrice, "0.00%")
        End If

    ' ?? 숏포지션 기준 익절/손절 판별
    ElseIf ws.Cells(r - 5, 51).Value = "?? 매도" Then
        Dim sellPrice As Double: sellPrice = ws.Cells(r - 5, 52).Value
        If currClose <= sellPrice * 0.98 Then
            ws.Cells(r, 51).Value = "?? 환매수(익절)"
            ws.Cells(r, 53).Value = currClose
            ws.Cells(r, 54).Value = Format((sellPrice - currClose) / sellPrice, "0.00%")
        ElseIf currClose >= sellPrice * 1.01 Then
            ws.Cells(r, 51).Value = "?? 환매수(손절)"
            ws.Cells(r, 53).Value = currClose
            ws.Cells(r, 54).Value = Format((sellPrice - currClose) / sellPrice, "0.00%")
        End If
    End If
End Sub

 

vba(ReportModule.bas)

Sub 전략리포트_생성()
    Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
    Dim rpt As Worksheet
    On Error Resume Next
    Set rpt = ThisWorkbook.Sheets("리포트")
    If rpt Is Nothing Then
        Set rpt = ThisWorkbook.Sheets.Add(After:=ws)
        rpt.Name = "리포트"
    Else
        rpt.Cells.Clear
    End If
    
    Dim lastRow As Long: lastRow = ws.Cells(ws.Rows.Count, 51).End(xlUp).Row
    Dim rng As Range: Set rng = ws.Range("51:51" & lastRow)

    Dim countAll As Long, countWin As Long, countLose As Long
    Dim totalProfit As Double, maxProfit As Double, maxLoss As Double
    Dim lossStreak As Long, maxLossStreak As Long
    Dim i As Long
    
    For i = 7 To lastRow
        Dim signal As String: signal = ws.Cells(i, 51).Value
        Dim profit As Variant: profit = ws.Cells(i, 54).Value
        
        If IsNumeric(profit) Then
            countAll = countAll + 1
            totalProfit = totalProfit + profit
            If profit > 0 Then
                countWin = countWin + 1
                lossStreak = 0
            Else
                countLose = countLose + 1
                lossStreak = lossStreak + 1
                If lossStreak > maxLossStreak Then
                    maxLossStreak = lossStreak
                End If
            End If
            If profit > maxProfit Then maxProfit = profit
            If profit < maxLoss Then maxLoss = profit
        End If
    Next i
    
    With rpt
        .Range("A1").Value = "?? 조건매매 전략 리포트"
        .Range("A3").Value = "총 거래 횟수": .Range("B3").Value = countAll
        .Range("A4").Value = "승률 (%)": .Range("B4").Value = Format(countWin / countAll, "0.00%")
        .Range("A5").Value = "평균 수익률": .Range("B5").Value = Format(totalProfit / countAll, "0.00%")
        .Range("A6").Value = "최대 수익률": .Range("B6").Value = Format(maxProfit, "0.00%")
        .Range("A7").Value = "최대 손실률": .Range("B7").Value = Format(maxLoss, "0.00%")
        .Range("A8").Value = "총 누적 수익률": .Range("B8").Value = Format(totalProfit, "0.00%")
        .Range("A9").Value = "최대 연속 손실 횟수": .Range("B9").Value = maxLossStreak
    End With

    MsgBox "전략 리포트가 '리포트' 시트에 생성되었습니다.", vbInformation
End Sub

Sub 전략별_성과분석()
    Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
    Dim rpt As Worksheet
    Set rpt = ThisWorkbook.Sheets.Add(After:=ws)
    rpt.Name = "전략분석"

    Dim 전략들 As Variant: 전략들 = Array("S1", "S2", "S3")
    Dim i As Long, r As Long, lastRow As Long: lastRow = ws.Cells(ws.Rows.Count, 50).End(xlUp).Row

    rpt.Range("A1:D1").Value = Array("전략코드", "거래횟수", "승률", "평균수익률")
    
    For i = 0 To UBound(전략들)
        Dim countAll As Long, countWin As Long, sumProfit As Double

        For r = 7 To lastRow
            If ws.Cells(r, 50).Value Like "*" & 전략들(i) Then
                countAll = countAll + 1
                Dim p As Variant: p = ws.Cells(r, 54).Value
                If IsNumeric(p) Then
                    sumProfit = sumProfit + p
                    If p > 0 Then countWin = countWin + 1
                End If
            End If
        Next r

        rpt.Cells(i + 2, 1).Value = 전략들(i)
        rpt.Cells(i + 2, 2).Value = countAll
        rpt.Cells(i + 2, 3).Value = Format(countWin / countAll, "0.00%")
        rpt.Cells(i + 2, 4).Value = Format(sumProfit / countAll, "0.00%")
    Next i

    MsgBox "전략별 성과 분석 완료!"
End Sub

📝  적용해 보시고 모르는것 있으시면 댓글 달아주세요. 확인해서 알려드릴께요 !!! 

반응형