配对交易 VBA 循环

Pairs Trading VBA Loop

当我想使用 Excel VBA.

构建配对交易自动化时遇到问题

我的策略是在两只股票的价差触及+/- 2个标准差时开仓(OTC_Sell或OTC_Buy),平仓(CTC_buy或 CTC_sell) 当两只股票的价差达到 +/- 4 个标准差或回到均值时。仓位关闭后,我可以在收到另一个未平仓交易条件 (OTC) 后开设另一个仓位。

但是,当我 运行 代码时,似乎循环只 运行 一次,因为我只能获得一笔交易(以黄色突出显示)。在这个单元格之后,我可以只得到零但没有其他交易信号。我重新 运行 从原始列旁边的那个单元格开始的代码并进行另一笔交易(以绿色突出显示)。不过,之后我得到的都是零。而我想在一列中获取所有交易信号。

Function SignalCTC(Price1, Price2, Mean, SD, StopLoss)
Dim i, j, k, m, n, o, p, numRows, numOTC, order, list, flag, finish
numRows = Price1.Rows.Count
Dim SignalColOTC()
ReDim SignalColOTC(numRows, 1)
Dim Price1Col()
ReDim Price1Col(numRows)
Dim Price2Col()
ReDim Price2Col(numRows)
Dim P_Ratio()
ReDim P_Ratio(numRows)
'Loop 1
For i = 1 To numRows
    P_Ratio(i) = Price1(i) / Price2(i)
Next i
UpperLim = Mean + (2 * SD)
LowerLim = Mean - (2 * SD)
Count = 0
flag = 0
For i = 1 To numRows
    If (Count = 0 And (P_Ratio(i) < UpperLim) And (P_Ratio(i) > LowerLim)) Then
    Count = 0
    flag = 0
    SignalColOTC(i, 1) = "Wait&See"
    ElseIf (Count = 0 And (P_Ratio(i) > UpperLim)) Then
        Count = 1
        flag = 1
        SignalColOTC(i, 1) = "Wait&See"
        ElseIf (Count = 0 And (P_Ratio(i) < LowerLim)) Then
            Count = 1
            flag = -1
            SignalColOTC(i, 1) = "Wait&See"
            ElseIf (Count = 1 And flag = 1 And (P_Ratio(i) < UpperLim) And (P_Ratio(i) > Mean)) Then
                Count = 0
                flag = 0
                SignalColOTC(i, 1) = "OTC_Sell"
                ElseIf (Count = 1 And flag = -1 And (P_Ratio(i) > LowerLim) And (P_Ratio(i) < Mean)) Then
                    Count = 0
                    flag = 0
                    SignalColOTC(i, 1) = "OTC_Buy"
                    Else: SignalColOTC(i, 1) = "Wait&See"
    End If
Next i
numOTC = 0
order = 0
list = 0
For i = 1 To numRows
    If (SignalColOTC(i, 1) = "OTC_Sell") Or (SignalColOTC(i, 1) = "OTC_Buy") Then
    numOTC = numOTC + 1
    Else: numOTC = numOTC
    End If
Next i
'Dim x
'Loop 2
    Dim SignalColCTC()
    ReDim SignalColCTC(numRows, numOTC)
    For n = 1 To numRows
        If (SignalColOTC(n, 1) = "OTC_Sell") Then
        list = list + 1
        SignalColCTC(n, list) = "OTC_Sell"
        For j = n + 1 To numRows
            If ((P_Ratio(j) < Mean) Or (Abs(P_Ratio(j)) > (1 + StopLoss) * Abs(P_Ratio(n)))) Then
            SignalColCTC(j, list) = "CTC_Buy"
            Else: SignalColCTC(j, list) = "Wait&See"
            End If
        Next j
        ElseIf (SignalColOTC(n, 1) = "OTC_Buy") Then
            list = list + 1
            SignalColCTC(n, list) = "OTC_Buy"
            For k = n + 1 To numRows
                If ((P_Ratio(k) > Mean) Or (Abs(P_Ratio(k)) < (1 - StopLoss) * Abs(P_Ratio(n)))) Then
                SignalColCTC(k, list) = "CTC_Sell"
                Else: SignalColCTC(k, list) = "Wait&See"
                End If
            Next k
        End If
    Next n
'Loop 3
    For o = 1 To numRows
        For list = 1 To numOTC
            If (SignalColCTC(o, list) = "CTC_Buy") Or (SignalColCTC(o, list) = "CTC_Sell") Then
                For p = o + 1 To numRows
                SignalColCTC(p, list) = "0"
                Next p
            End If
        Next list
    Next o
SignalCTC = SignalColCTC
End Function

这应该是循环 3 的问题吗?我试图将循环 2 和循环 3 都放在一个循环下,但这次我什至没有收到一个交易信号,而是全部为零。

 Function SignalCTC(Price1, Price2, Mean, SD, StopLoss)
    Dim i, j, k, m, n, o, p, numRows, numOTC, order, list, flag, finish
    numRows = Price1.Rows.Count
    Dim SignalColOTC()
    ReDim SignalColOTC(numRows, 1)
    Dim Price1Col()
    ReDim Price1Col(numRows)
    Dim Price2Col()
    ReDim Price2Col(numRows)
    Dim P_Ratio()
    ReDim P_Ratio(numRows)
    'Loop 1
    For i = 1 To numRows
        P_Ratio(i) = Price1(i) / Price2(i)
    Next i
    UpperLim = Mean + (2 * SD)
    LowerLim = Mean - (2 * SD)
    Count = 0
    flag = 0
    For i = 1 To numRows
        If (Count = 0 And (P_Ratio(i) < UpperLim) And (P_Ratio(i) > LowerLim)) Then
        Count = 0
        flag = 0
        SignalColOTC(i, 1) = "Wait&See"
        ElseIf (Count = 0 And (P_Ratio(i) > UpperLim)) Then
            Count = 1
            flag = 1
            SignalColOTC(i, 1) = "Wait&See"
            ElseIf (Count = 0 And (P_Ratio(i) < LowerLim)) Then
                Count = 1
                flag = -1
                SignalColOTC(i, 1) = "Wait&See"
                ElseIf (Count = 1 And flag = 1 And (P_Ratio(i) < UpperLim) And (P_Ratio(i) > Mean)) Then
                    Count = 0
                    flag = 0
                    SignalColOTC(i, 1) = "OTC_Sell"
                    ElseIf (Count = 1 And flag = -1 And (P_Ratio(i) > LowerLim) And (P_Ratio(i) < Mean)) Then
                        Count = 0
                        flag = 0
                        SignalColOTC(i, 1) = "OTC_Buy"
                        Else: SignalColOTC(i, 1) = "Wait&See"
        End If
    Next i
    numOTC = 0
    order = 0
    list = 0
    For i = 1 To numRows
        If (SignalColOTC(i, 1) = "OTC_Sell") Or (SignalColOTC(i, 1) = "OTC_Buy") Then
        numOTC = numOTC + 1
        Else: numOTC = numOTC
        End If
    Next i
    'Dim x
    x=1
    For Y=x to numRows
    'Loop 2
        Dim SignalColCTC()
        ReDim SignalColCTC(numRows, numOTC)
        For n = x To numRows
            If (SignalColOTC(n, 1) = "OTC_Sell") Then
            list = list + 1
            SignalColCTC(n, list) = "OTC_Sell"
            For j = n + 1 To numRows
                If ((P_Ratio(j) < Mean) Or (Abs(P_Ratio(j)) > (1 + StopLoss) * Abs(P_Ratio(n)))) Then
                SignalColCTC(j, list) = "CTC_Buy"
                Else: SignalColCTC(j, list) = "Wait&See"
                End If
            Next j
            ElseIf (SignalColOTC(n, 1) = "OTC_Buy") Then
                list = list + 1
                SignalColCTC(n, list) = "OTC_Buy"
                For k = n + 1 To numRows
                    If ((P_Ratio(k) > Mean) Or (Abs(P_Ratio(k)) < (1 - StopLoss) * Abs(P_Ratio(n)))) Then
                    SignalColCTC(k, list) = "CTC_Sell"
                    Else: SignalColCTC(k, list) = "Wait&See"
                    End If
                Next k
            End If
        Next n
    'Loop 3
        For o = x To numRows
            For list = 1 To numOTC
                If (SignalColCTC(o, list) = "CTC_Buy") Or (SignalColCTC(o, list) = "CTC_Sell") Then
                    For p = o + 1 To numRows
                    SignalColCTC(p, list) = "0"
                    Next p
                End If
                x = p
            Next list
        Next o
    Next Y
    SignalCTC = SignalColCTC
    End Function

这里有一个有趣的问题。快速浏览了您的代码,没有发现任何问题。循环 3 对我来说似乎很好,而且似乎并不重要。

也许您正在实施的逻辑不是您想要的?我已经添加了我的评论版本(除了标签之外没有真正的变化)。对你来说可能是一个很好的方法来做类似于检查循环 1 和 2 正在做你想要他们做的事情。

另外,我假设均值和 SD 输入是价格比率?为什么不直接在函数中解决它们?

最后,确保您在以后声明变量时指定数据类型。可以避免错误和混乱。例如'dim i as integer'

Function SignalCTC(Price1, Price2, Mean, SD, StopLoss)

    Dim i, j, k, m, n, o, p, numRows, numOTC, order, list, flag, finish

    numRows = Price1.Rows.Count

    Dim SignalColOTC()
    ReDim SignalColOTC(numRows, 1)
    Dim Price1Col()
    ReDim Price1Col(numRows)
    Dim Price2Col()
    ReDim Price2Col(numRows)
    Dim P_Ratio()
    ReDim P_Ratio(numRows)

    'calculate ratios
    For i = 1 To numRows
        P_Ratio(i) = Price1(i) / Price2(i)
    Next i

    UpperLim = Mean + (2 * SD)
    LowerLim = Mean - (2 * SD)
    Count = 0
    flag = 0

    'Loop 1
    'identify possible opening events
    For i = 1 To numRows
        'if no events (within limits), reset
        If (Count = 0 And (P_Ratio(i) < UpperLim) And (P_Ratio(i) > LowerLim)) Then
            Count = 0
            flag = 0
            SignalColOTC(i, 1) = "Wait&See"
        'if exceeds for the first time
        ElseIf (Count = 0 And (P_Ratio(i) > UpperLim)) Then
            Count = 1
            flag = 1
            SignalColOTC(i, 1) = "Wait&See"
        'if under limit for the first time
        ElseIf (Count = 0 And (P_Ratio(i) < LowerLim)) Then
            Count = 1
            flag = -1
            SignalColOTC(i, 1) = "Wait&See"
        'if already exceeded once and now within limits
        ElseIf (Count = 1 And flag = 1 And (P_Ratio(i) < UpperLim) And (P_Ratio(i) > Mean)) Then
            Count = 0
            flag = 0
            SignalColOTC(i, 1) = "OTC_Sell"
        'if were under limit once and now within limits
        ElseIf (Count = 1 And flag = -1 And (P_Ratio(i) > LowerLim) And (P_Ratio(i) < Mean)) Then
            Count = 0
            flag = 0
            SignalColOTC(i, 1) = "OTC_Buy"
        Else
            SignalColOTC(i, 1) = "Wait&See"
        End If
    Next i

    numOTC = 0
    order = 0
    list = 0

    'count opening events
    For i = 1 To numRows
        If (SignalColOTC(i, 1) = "OTC_Sell") Or (SignalColOTC(i, 1) = "OTC_Buy") Then
            numOTC = numOTC + 1
        Else
            'numOTC = numOTC 'redundant, don't need
        End If
    Next i

    'Loop 2
    'identify closing events
    Dim SignalColCTC()
    ReDim SignalColCTC(numRows, numOTC)

    For n = 1 To numRows
        If (SignalColOTC(n, 1) = "OTC_Sell") Then
            list = list + 1 'scroll to next column
            SignalColCTC(n, list) = "OTC_Sell" 'we know this is the sale event
            For j = n + 1 To numRows 'remaining rows
                'if hits mean, or makes a big loss
                If ((P_Ratio(j) < Mean) Or (Abs(P_Ratio(j)) > (1 + StopLoss) * Abs(P_Ratio(n)))) Then
                    SignalColCTC(j, list) = "CTC_Buy" 'close position
                Else
                    SignalColCTC(j, list) = "Wait&See"
                End If
            Next j
        ElseIf (SignalColOTC(n, 1) = "OTC_Buy") Then 'logic repeated for sale
            list = list + 1
            SignalColCTC(n, list) = "OTC_Buy"
            For k = n + 1 To numRows
                If ((P_Ratio(k) > Mean) Or (Abs(P_Ratio(k)) < (1 - StopLoss) * Abs(P_Ratio(n)))) Then
                    SignalColCTC(k, list) = "CTC_Sell"
                Else
                    SignalColCTC(k, list) = "Wait&See"
                End If
            Next k
        End If
    Next n

    'Loop 3
    'just filling zeros after position is closed
    For o = 1 To numRows
        For list = 1 To numOTC
            If (SignalColCTC(o, list) = "CTC_Buy") Or (SignalColCTC(o, list) = "CTC_Sell") Then
                For p = o + 1 To numRows
                    SignalColCTC(p, list) = "0"
                Next p
            End If
        Next list
    Next o

    SignalCTC = SignalColCTC

End Function

编辑:

查看整个过程,我希望输出矩阵类似于:

SignalColCTC:

OTC_Buy     Null        Null
Wait&See    Null        Null
Wait&See    OTC_Sell    Null
Wait&See    Wait&See    Null
CTC_Sell    Wait&See    Null
0           CTC_Buy     OTC_Buy
0           0           Wait&See

(N.B。我认为空值稍后会变成零)

这对我来说似乎很合理。也许您想要做的是将这些对转换为单个列?从你上传的图片来看,这就是你想要的。