Блог им. TaurusGOLD

📊 Арбитражная стратегия Сбербанк: акции + фьючерсы

📊 Арбитражная стратегия Сбербанк: акции + фьючерсы



Структура листов:

  1. Настройки - параметры инструментов и подключения

  2. Котировки - текущие цены всех инструментов

  3. Арбитраж - расчет спредов и сигналы

  4. Торговля - отправка заявок

  5. Портфель - мониторинг позиций

  6. Графики - визуализация спредов

📈 Лист «Настройки»

A1: "АРБИТРАЖ СБЕРБАНК - НАСТРОЙКИ"

A3: "ИНСТРУМЕНТЫ АРБИТРАЖА"
A4: "Тикер"      B4: "Название"              C4: "Класс"    D4: "Тип"          E4: "Лотность"
A5: "SBER"       B5: "Сбербанк ао"           C5: "TQBR"     D5: "Акция"        E5: "10"
A6: "SBERP"      B6: "Сбербанк ап"           C6: "TQBR"     D6: "Акция"        E6: "10"  
A7: "SRM3"       B7: "Фьючерс Сбер"          C7: "SPBFUT"   D7: "Фьючерс"      E7: "100"

A9: "ПАРАМЕТРЫ АРБИТРАЖА"
A10: "Исторический спред SBER/SBERP:"     B10: "0.85"
A11: "Стандартное отклонение:"            B11: "0.05"
A12: "Уровень входа (σ):"                 B12: "2"
A13: "Уровень выхода (σ):"                B13: "0.5"
A14: "Объем сделки (лотов):"              B14: "10"

A16: "ПОДКЛЮЧЕНИЕ QUIK"
A17: "DDE Service:"       B17: "QLUA"
A18: "DDE Topic:"         B18: "QuikTrans2"
A19: "Торговый счет:"     B19: "L01-00000F00" <a name="cut"></a> <br /><br />

💹 Лист «Котировки»

A1: "ТЕКУЩИЕ КОТИРОВКИ"
A2: "Инструмент" B2: "Бид" C2: "Оффер" D2: "Послед." E2: "Время" F2: "Объем"

A3: "SBER"
A4: "SBERP" 
A5: "<span style="text-decoration: line-through;">SRM5</span>"
A6: "Спред SBER/SBERP"
A7: "Спред SBER/Фьючерс"
A8: "Спред SBERP/Фьючерс"

📊 Лист «Арбитраж»

A1: "РАСЧЕТ АРБИТРАЖНЫХ СПРЕДОВ"

A2: "ПАРА"                  B2: "Текущий спред" C2: "Историч. среднее" D2: "Отклонение (σ)" E2: "Сигнал" F2: "Действие"

A3: "SBER / SBERP"
A4: "SBER / Фьючерс"  
A5: "SBERP / Фьючерс"
A6: "Треугольный арбитраж"

B7: "ВРЕМЯ ОБНОВЛЕНИЯ:"     C7: "=NOW()"

A9: "ОТКРЫТЫЕ ПОЗИЦИИ"
A10: "Инструмент" B10: "Позиция" C10: "Средняя" D10: "P&L" E10: "Статус"

💻 VBA код для арбитражной стратегии

vba
' Модуль арбитражной стратегии Сбербанк
Option Explicit

' Константы
Private Const QUIK_DDE_SERVICE As String = "QLUA"
Private Const QUIK_DDE_TOPIC As String = "QuikTrans2"
Private ddeChannel As Long

' Данные инструментов
Private Type InstrumentData
    Ticker As String
    ClassCode As String
    BidPrice As Double
    AskPrice As Double
    LastPrice As Double
    LotSize As Long
End Type

Dim instruments(1 To 3) As InstrumentData

' ==================== ИНИЦИАЛИЗАЦИЯ ====================

Public Sub InitializeArbitrage()
    ' Инициализация инструментов
    InitializeInstruments
    ' Подключение к QUIK
    ConnectToQUIK
    ' Первое обновление данных
    UpdateAllData
End Sub

Private Sub InitializeInstruments()
    With instruments(1)
        .Ticker = "SBER"
        .ClassCode = "TQBR"
        .LotSize = 10
    End With
    
    With instruments(2)
        .Ticker = "SBERP" 
        .ClassCode = "TQBR"
        .LotSize = 10
    End With
    
    With instruments(3)
        .Ticker = "SRM3"
        .ClassCode = "SPBFUT"
        .LotSize = 100
    End With
End Sub

' ==================== РАСЧЕТ АРБИТРАЖНЫХ СПРЕДОВ ====================

Public Sub CalculateArbitrageSpreads()
    Dim wsArb As Worksheet
    Set wsArb = ThisWorkbook.Sheets("Арбитраж")
    
    ' Обновляем цены
    UpdateAllPrices
    
    ' 1. Спред SBER / SBERP
    Dim spread_SBER_SBERP As Double
    If instruments(1).LastPrice > 0 And instruments(2).LastPrice > 0 Then
        spread_SBER_SBERP = instruments(1).LastPrice / instruments(2).LastPrice
        CalculateSBER_SBERP_Arbitrage spread_SBER_SBERP, wsArb
    End If
    
    ' 2. Спред SBER / Фьючерс
    If instruments(1).LastPrice > 0 And instruments(3).LastPrice > 0 Then
        CalculateSBER_Futures_Arbitrage wsArb
    End If
    
    ' 3. Треугольный арбитраж
    CalculateTriangularArbitrage wsArb
    
    ' Обновляем время
    wsArb.Range("C7").Value = Now
End Sub

' Арбитраж между обычными и привилегированными акциями
Private Sub CalculateSBER_SBERP_Arbitrage(ByVal currentSpread As Double, ws As Worksheet)
    Dim histSpread As Double, stdDev As Double
    Dim entryLevel As Double, exitLevel As Double
    
    histSpread = ThisWorkbook.Sheets("Настройки").Range("B10").Value
    stdDev = ThisWorkbook.Sheets("Настройки").Range("B11").Value
    entryLevel = ThisWorkbook.Sheets("Настройки").Range("B12").Value
    exitLevel = ThisWorkbook.Sheets("Настройки").Range("B13").Value
    
    Dim deviation As Double
    deviation = (currentSpread - histSpread) / stdDev
    
    ' Записываем данные
    ws.Range("B3").Value = currentSpread
    ws.Range("C3").Value = histSpread
    ws.Range("D3").Value = deviation
    
    ' Определяем сигнал
    If deviation > entryLevel Then
        ' SBER перекуплен относительно SBERP - продаем SBER, покупаем SBERP
        ws.Range("E3").Value = "SELL SBER / BUY SBERP"
        ws.Range("F3").Value = "ВХОД"
        If CheckNoOpenPositions() Then
            ExecuteSBER_SBERP_Arbitrage "SELL_BUY", currentSpread
        End If
    ElseIf deviation < -entryLevel Then
        ' SBER перепродан относительно SBERP - покупаем SBER, продаем SBERP
        ws.Range("E3").Value = "BUY SBER / SELL SBERP" 
        ws.Range("F3").Value = "ВХОД"
        If CheckNoOpenPositions() Then
            ExecuteSBER_SBERP_Arbitrage "BUY_SELL", currentSpread
        End If
    ElseIf Abs(deviation) < exitLevel And CheckOpenPositions() Then
        ' Выход из позиции
        ws.Range("E3").Value = "ЗАКРЫТИЕ"
        ws.Range("F3").Value = "ВЫХОД"
        CloseAllPositions
    Else
        ws.Range("E3").Value = "ОЖИДАНИЕ"
        ws.Range("F3").Value = "НЕТ СИГНАЛА"
    End If
    
    ' Раскрашиваем ячейку сигнала
    If deviation > 1 Then
        ws.Range("E3").Interior.Color = RGB(255, 200, 200) ' Красный
    ElseIf deviation < -1 Then
        ws.Range("E3").Interior.Color = RGB(200, 255, 200) ' Зеленый
    Else
        ws.Range("E3").Interior.Color = RGB(255, 255, 200) ' Желтый
    End If
End Sub

' Арбитраж между акциями и фьючерсом
Private Sub CalculateSBER_Futures_Arbitrage(ws As Worksheet)
    Dim futuresPrice As Double, spotPrice As Double
    Dim theoreticalPrice As Double, actualPrice As Double
    
    spotPrice = instruments(1).LastPrice
    futuresPrice = instruments(3).LastPrice
    
    ' Теоретическая цена фьючерса (упрощенная формула)
    Dim riskFreeRate As Double, daysToExpiry As Double
    riskFreeRate = 0.08 ' 8% годовых
    daysToExpiry = 90   ' дней до экспирации
    
    theoreticalPrice = spotPrice * (1 + riskFreeRate * daysToExpiry / 365)
    actualPrice = futuresPrice
    
    Dim basis As Double
    basis = actualPrice - theoreticalPrice
    
    ' Записываем данные
    ws.Range("B4").Value = basis
    ws.Range("C4").Value = 0 ' Теоретический базис должен быть 0
    ws.Range("D4").Value = basis / (spotPrice * 0.01) ' В процентах от спота
    
    If basis > spotPrice * 0.02 Then ' Базис > 2%
        ws.Range("E4").Value = "BUY SBER / SELL FUTURES"
        ws.Range("F4").Value = "ВХОД"
    ElseIf basis < -spotPrice * 0.02 Then ' Базис < -2%
        ws.Range("E4").Value = "SELL SBER / BUY FUTURES" 
        ws.Range("F4").Value = "ВХОД"
    Else
        ws.Range("E4").Value = "ОЖИДАНИЕ"
        ws.Range("F4").Value = "НЕТ СИГНАЛА"
    End If
End Sub

' Треугольный арбитраж
Private Sub CalculateTriangularArbitrage(ws As Worksheet)
    Dim price_SBER As Double, price_SBERP As Double, price_FUT As Double
    
    price_SBER = instruments(1).LastPrice
    price_SBERP = instruments(2).LastPrice
    price_FUT = instruments(3).LastPrice
    
    If price_SBER > 0 And price_SBERP > 0 And price_FUT > 0 Then
        ' Проверяем различные комбинации
        Dim arbOpportunity As String
        arbOpportunity = CheckTriangularArbitrage(price_SBER, price_SBERP, price_FUT)
        
        ws.Range("B5").Value = arbOpportunity
        ws.Range("E5").Value = arbOpportunity
        ws.Range("F5").Value = IIf(arbOpportunity = "НЕТ", "НЕТ СИГНАЛА", "ВХОД")
    End If
End Sub

Private Function CheckTriangularArbitrage(SBER As Double, SBERP As Double, FUT As Double) As String
    ' Проверяем различные арбитражные возможности
    Dim threshold As Double: threshold = 0.02 ' 2%
    
    ' SBER -> SBERP -> FUT -> SBER
    Dim path1 As Double
    path1 = (SBERP / SBER) * (FUT / SBERP) * (SBER / FUT)
    
    If Abs(path1 - 1) > threshold Then
        CheckTriangularArbitrage = "ТРЕУГОЛЬНЫЙ АРБИТРАЖ"
        Exit Function
    End If
    
    CheckTriangularArbitrage = "НЕТ"
End Function

' ==================== ИСПОЛНЕНИЕ СДЕЛОК ====================

' Исполнение арбитража SBER/SBERP
Private Sub ExecuteSBER_SBERP_Arbitrage(direction As String, spread As Double)
    Dim quantity As Long
    quantity = ThisWorkbook.Sheets("Настройки").Range("B14").Value
    
    Dim wsTrade As Worksheet
    Set wsTrade = ThisWorkbook.Sheets("Торговля")
    
    If direction = "BUY_SELL" Then
        ' Покупаем SBER, продаем SBERP
        SendLimitOrder "SBER", "TQBR", "BUY", quantity, instruments(1).AskPrice
        SendLimitOrder "SBERP", "TQBR", "SELL", quantity, instruments(2).BidPrice
        
        ' Логируем сделку
        LogTrade "OPEN", "SBER/SBERP", "BUY_SELL", spread, quantity
    ElseIf direction = "SELL_BUY" Then
        ' Продаем SBER, покупаем SBERP
        SendLimitOrder "SBER", "TQBR", "SELL", quantity, instruments(1).BidPrice
        SendLimitOrder "SBERP", "TQBR", "BUY", quantity, instruments(2).AskPrice
        
        ' Логируем сделку
        LogTrade "OPEN", "SBER/SBERP", "SELL_BUY", spread, quantity
    End If
End Sub

' Закрытие всех позиций
Private Sub CloseAllPositions()
    ' Получаем текущие позиции из портфеля
    Dim wsPortfolio As Worksheet
    Set wsPortfolio = ThisWorkbook.Sheets("Портфель")
    
    ' Закрываем позиции встречными сделками
    ' (реализация зависит от структуры данных портфеля)
    UpdateStatus "Закрытие арбитражных позиций"
End Sub

' ==================== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ====================

' Проверка открытых позиций
Private Function CheckOpenPositions() As Boolean
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Портфель")
    
    ' Проверяем есть ли ненулевые позиции
    CheckOpenPositions = (ws.Range("B11").Value <> 0 Or _
                         ws.Range("B12").Value <> 0 Or _
                         ws.Range("B13").Value <> 0)
End Function

Private Function CheckNoOpenPositions() As Boolean
    CheckNoOpenPositions = Not CheckOpenPositions
End Function

' Логирование сделок
Private Sub LogTrade(action As String, pair As String, direction As String, _
                    spread As Double, quantity As Long)
    
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Торговля")
    
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row + 1
    
    ws.Cells(lastRow, 1).Value = Now
    ws.Cells(lastRow, 2).Value = action
    ws.Cells(lastRow, 3).Value = pair
    ws.Cells(lastRow, 4).Value = direction
    ws.Cells(lastRow, 5).Value = spread
    ws.Cells(lastRow, 6).Value = quantity
    ws.Cells(lastRow, 7).Value = "АРБИТРАЖ"
End Sub

' Обновление всех цен
Private Sub UpdateAllPrices()
    Dim i As Integer
    For i = 1 To 3
        UpdateInstrumentPrice i
    Next i
End Sub

' Обновление цены инструмента
Private Sub UpdateInstrumentPrice(index As Integer)
    With instruments(index)
        .BidPrice = GetDDEValue(.Ticker, "BID")
        .AskPrice = GetDDEValue(.Ticker, "OFFER") 
        .LastPrice = GetDDEValue(.Ticker, "LAST")
    End With
End Sub

' ==================== ИНТЕРФЕЙС И УПРАВЛЕНИЕ ====================

' Запуск арбитражного робота
Public Sub StartArbitrageRobot()
    InitializeArbitrage
    UpdateStatus "Арбитражный робот запущен"
    
    ' Запускаем автоматическое обновление
    Application.OnTime Now + TimeValue("00:00:05"), "ArbitrageUpdateCycle"
End Sub

' Цикл обновления арбитража
Public Sub ArbitrageUpdateCycle()
    On Error GoTo ErrorHandler
    
    CalculateArbitrageSpreads
    UpdatePortfolioDisplay
    
    ' Следующее обновление через 10 секунд
    Application.OnTime Now + TimeValue("00:00:10"), "ArbitrageUpdateCycle"
    
    Exit Sub
ErrorHandler:
    UpdateStatus "Ошибка в цикле арбитража: " & Err.Description
    Application.OnTime Now + TimeValue("00:00:30"), "ArbitrageUpdateCycle"
End Sub

' Остановка робота
Public Sub StopArbitrageRobot()
    On Error Resume Next
    Application.OnTime EarliestTime:=Now + TimeValue("00:00:01"), _
                      Procedure:="ArbitrageUpdateCycle", Schedule:=False
    UpdateStatus "Арбитражный робот остановлен"
End Sub

' Обновление отображения портфеля
Private Sub UpdatePortfolioDisplay()
    Dim wsPortfolio As Worksheet
    Set wsPortfolio = ThisWorkbook.Sheets("Портфель")
    
    ' Здесь можно добавить логику обновления позиций
    ' из QUIK через DDE запросы
End Sub

' Функции подключения к QUIK (аналогично предыдущему примеру)
Private Sub ConnectToQUIK()
    ' Реализация подключения к QUIK через DDE
End Sub

Private Function GetDDEValue(ticker As String, param As String) As Double
    ' Реализация получения данных через DDE
End Function

Private Sub SendLimitOrder(ticker As String, classCode As String, _
                          operation As String, quantity As Long, price As Double)
    ' Реализация отправки заявки
End Sub

Private Sub UpdateStatus(message As String)
    ThisWorkbook.Sheets("Арбитраж").Range("A20").Value = message
End Sub

🎯 Как использовать:

  1. Заполните настройки в соответствующем листе

  2. Запустите подключение к QUIK

  3. Включите арбитражного робота - StartArbitrageRobot

  4. Следите за сигналами на листе «Арбитраж»

  5. Робот автоматически будет входить и выходить из арбитражных сделок

📈 Ключевые арбитражные возможности:

  1. SBER/SBERP - классический спред между акциями

  2. Базисный арбитраж - акции vs фьючерс

  3. Треугольный арбитраж - комбинация всех трех инструментов

⚠ Риски:

  • Временной риск (несинхронное исполнение)

  • Ликвидность инструментов

  • Изменение дивидендной политики

  • Комиссии и проскальзывания

Тестируйте стратегию на исторических данных перед использованием!






482 | ★2

Читайте на SMART-LAB:
Фото
DXY у ключевой поддержки: шорт-сквиз или новый этап распродажи?
Индекс доллара DXY плавно дрейфует в область месячного минимума в районе 98,50. Однако ослабление доллара на FX неравномерно: EURUSD стоит около...
Фото
🎭 За кулисами ноября: итоги
В прошлом месяце вложения физлиц в ценные бумаги выросли на 36% . В облигации было инвестировано 115,6 млрд , в паи фондов — 31,1 млрд....
Портрет клиента Займера
За 11 лет работы к нам обратилось более 20 млн россиян. Кто же является типичным заемщиком Займера? 🔎 Посмотрим данные за ноябрь этого года. 🔶...

теги блога TaurusGOLD

....все тэги



UPDONW
Новый дизайн