Блог им. TaurusGOLD

📋 Создание Excel файла для торговли на ММВБ через QUIK

🚀 Шаг 1: Создаем новый Excel файл

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

  • 📊 Котировки - текущие цены инструментов

  • 🎯 Торговля - ручная отправка заявок

  • 🤖 Автоторговля - автоматические стратегии

  • 💼 Портфель - текущие позиции

  • ⚙ Настройки - параметры подключения

  • 📈 Графики - визуализация данных



🎨 Шаг 2: Настраиваем листы

Лист «Настройки» (Settings)

A1: "НАСТРОЙКИ ПОДКЛЮЧЕНИЯ К QUIK"
A3: "DDE Service:"      B3: "QLUA"
A4: "DDE Topic:"        B4: "QuikTrans2"
A5: "Торговый счет:"    B5: "L01-00000F00"
A6: "Клиентский код:"   B6: ""

A8: "СПИСОК ИНСТРУМЕНТОВ"
A9: "Тикер"   B9: "Название"        C9: "Класс"   D9: "Лот"
A10: "GAZP"   B10: "Газпром"        C10: "TQBR"   D10: "10"
A11: "SBER"   B11: "Сбербанк"       C11: "TQBR"   D11: "10"
A12: "LKOH"   B12: "Лукойл"         C12: "TQBR"   D12: "1"
A13: "GMKN"   B13: "Норникель"      C13: "TQBR"   D13: "1"

 

Лист «Котировки» (Quotes)

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

Лист «Торговля» (Trading)

A1: "РУЧНАЯ ТОРГОВЛЯ"
A2: "Тикер"   B2: "Операция"   C2: "Кол-во лотов"   D2: "Цена"   E2: "Статус"   F2: "ID заявки"   G2: "Действие"

 

💻 Шаг 3: Добавляем VBA код

3.1. Откройте редактор VBA (ALT + F11)
3.2. Добавьте новый модуль и вставьте код:

vba
' Модуль для торговли через QUIK DDE
Option Explicit

' Константы подключения
Private Const QUIK_DDE_SERVICE As String = "QLUA"
Private Const QUIK_DDE_TOPIC As String = "QuikTrans2"
Private Const TRANS2_TABLE As String = "TRANS2"

' Глобальные переменные
Private ddeChannel As Long
Private isConnected As Boolean

' ==================== ОСНОВНЫЕ ФУНКЦИИ ====================

' Инициализация подключения к QUIK
Public Sub InitializeQUIKConnection()
    On Error GoTo ErrorHandler
    
    ' Завершаем предыдущее подключение
    If ddeChannel > 0 Then
        DDETerminate ddeChannel
    End If
    
    ' Инициируем DDE канал
    ddeChannel = DDEInitiate(QUIK_DDE_SERVICE, QUIK_DDE_TOPIC)
    
    If ddeChannel > 0 Then
        isConnected = True
        UpdateStatus "✅ Подключено к QUIK"
        ThisWorkbook.Sheets("Настройки").Range("B1").Value = "ПОДКЛЮЧЕНО"
    Else
        isConnected = False
        UpdateStatus "❌ Ошибка подключения к QUIK"
        ThisWorkbook.Sheets("Настройки").Range("B1").Value = "ОШИБКА"
    End If
    
    Exit Sub
ErrorHandler:
    UpdateStatus "Ошибка инициализации: " & Err.Description
End Sub

' Отправка лимитной заявки
Public Sub SendLimitOrder()
    On Error GoTo ErrorHandler
    
    If Not isConnected Then
        InitializeQUIKConnection
        If Not isConnected Then Exit Sub
    End If
    
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Торговля")
    
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    
    Dim i As Long
    For i = 3 To lastRow ' Начинаем с строки 3 (после заголовков)
        
        ' Проверяем кнопку отправки
        If ws.Cells(i, "G").Value = "ОТПРАВИТЬ" Then
            
            Dim ticker As String, operation As String
            Dim quantity As Long, price As Double
            Dim classCode As String, account As String
            
            ' Получаем данные из строки
            ticker = Trim(ws.Cells(i, "A").Value)
            operation = UCase(Trim(ws.Cells(i, "B").Value))
            quantity = ws.Cells(i, "C").Value
            price = ws.Cells(i, "D").Value
            
            ' Получаем дополнительные параметры из настроек
            classCode = GetClassCode(ticker)
            account = GetSetting("Торговый счет")
            
            If ticker = "" Or quantity <= 0 Or price <= 0 Then
                ws.Cells(i, "E").Value = "ОШИБКА: Неверные данные"
                ws.Cells(i, "G").Value = "ПОВТОРИТЬ"
                GoTo NextRow
            End If
            
            ' Отправляем транзакцию
            Dim transId As String
            transId = SendTransaction(ticker, classCode, operation, quantity, price, account)
            
            If transId <> "" Then
                ws.Cells(i, "E").Value = "ОТПРАВЛЕНО"
                ws.Cells(i, "F").Value = transId
                ws.Cells(i, "G").Value = "✅ ОТПРАВЛЕНО"
                UpdateStatus "Заявка отправлена: " & ticker & " " & operation & " " & quantity & " @ " & price
            Else
                ws.Cells(i, "E").Value = "ОШИБКА ОТПРАВКИ"
                ws.Cells(i, "G").Value = "ПОВТОРИТЬ"
            End If
        End If
        
NextRow:
    Next i
    
    Exit Sub
ErrorHandler:
    UpdateStatus "Ошибка отправки заявки: " & Err.Description
End Sub

' Функция отправки транзакции в QUIK
Private Function SendTransaction(ticker As String, classCode As String, _
                                operation As String, quantity As Long, _
                                price As Double, account As String) As String
    
    If ddeChannel <= 0 Then
        SendTransaction = ""
        Exit Function
    End If
    
    ' Генерируем уникальный ID транзакции
    Dim transId As String
    transId = "XL" & Format(Now, "yymmddhhnnss")
    
    ' Формируем строку транзакции для таблицы TRANS2
    Dim transData As String
    transData = "CLASSCODE=" & classCode & ";" & _
                "SECCODE=" & ticker & ";" & _
                "ACTION=NEW_ORDER;" & _
                "ACCOUNT=" & account & ";" & _
                "OPERATION=" & operation & ";" & _
                "PRICE=" & Format(price, "0.00") & ";" & _
                "QUANTITY=" & quantity & ";" & _
                "TYPE=L;" & _
                "TRANS_ID=" & transId & ";" & _
                "BROKERREF=EXCEL_TRADE"
    
    ' Отправляем через DDE
    DDEPoke ddeChannel, TRANS2_TABLE, transData
    
    SendTransaction = transId
End Function

' ==================== ПОЛУЧЕНИЕ ДАННЫХ ИЗ QUIK ====================

' Обновление котировок
Public Sub UpdateQuotes()
    On Error GoTo ErrorHandler
    
    If Not isConnected Then Exit Sub
    
    Dim wsSettings As Worksheet, wsQuotes As Worksheet
    Set wsSettings = ThisWorkbook.Sheets("Настройки")
    Set wsQuotes = ThisWorkbook.Sheets("Котировки")
    
    ' Очищаем старые данные (кроме заголовков)
    If wsQuotes.Cells(2, 1).Value <> "" Then
        wsQuotes.Range("A3:G100").ClearContents
    End If
    
    Dim i As Long, rowCount As Long
    rowCount = 0
    
    ' Проходим по списку инструментов из настроек
    Dim lastRow As Long
    lastRow = wsSettings.Cells(wsSettings.Rows.Count, "A").End(xlUp).Row
    
    For i = 10 To lastRow ' Начинаем с строки 10 где список инструментов
        Dim ticker As String
        ticker = Trim(wsSettings.Cells(i, "A").Value)
        
        If ticker = "" Then Exit For
        
        ' Получаем данные по инструменту
        Dim lastPrice As String, bidPrice As String, askPrice As String
        Dim volume As String, timeStamp As String
        
        lastPrice = GetDDEValue(ticker, "LAST")
        bidPrice = GetDDEValue(ticker, "BID")
        askPrice = GetDDEValue(ticker, "OFFER")
        volume = GetDDEValue(ticker, "VOLUME")
        timeStamp = Format(Now, "hh:nn:ss")
        
        ' Записываем в таблицу котировок
        rowCount = rowCount + 1
        wsQuotes.Cells(2 + rowCount, 1).Value = ticker
        wsQuotes.Cells(2 + rowCount, 2).Value = lastPrice
        wsQuotes.Cells(2 + rowCount, 3).Value = bidPrice
        wsQuotes.Cells(2 + rowCount, 4).Value = askPrice
        wsQuotes.Cells(2 + rowCount, 5).Value = volume
        wsQuotes.Cells(2 + rowCount, 6).Value = timeStamp
        
        ' Расчет изменения цены
        If IsNumeric(lastPrice) Then
            If rowCount > 1 Then
                Dim prevPrice As Double
                On Error Resume Next
                prevPrice = wsQuotes.Cells(1 + rowCount, 2).Value
                If prevPrice > 0 Then
                    Dim changePct As Double
                    changePct = (lastPrice - prevPrice) / prevPrice * 100
                    wsQuotes.Cells(2 + rowCount, 7).Value = changePct
                    ' Раскрашиваем ячейку
                    If changePct > 0 Then
                        wsQuotes.Cells(2 + rowCount, 7).Interior.Color = RGB(200, 255, 200)
                    ElseIf changePct < 0 Then
                        wsQuotes.Cells(2 + rowCount, 7).Interior.Color = RGB(255, 200, 200)
                    End If
                End If
            End If
        End If
    Next i
    
    UpdateStatus "Котировки обновлены: " & rowCount & " инструментов"
    
    Exit Sub
ErrorHandler:
    UpdateStatus "Ошибка обновления котировок: " & Err.Description
End Sub

' Получение значения через DDE
Private Function GetDDEValue(ticker As String, param As String) As String
    On Error Resume Next
    
    Dim value As String
    value = DDERequest(ddeChannel, ticker & "|" & param)
    
    If Err.Number <> 0 Then
        GetDDEValue = "N/A"
    Else
        GetDDEValue = value
    End If
End Function

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

' Получение класса инструмента
Private Function GetClassCode(ticker As String) As String
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Настройки")
    
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    
    Dim i As Long
    For i = 10 To lastRow
        If Trim(ws.Cells(i, "A").Value) = ticker Then
            GetClassCode = ws.Cells(i, "C").Value
            Exit Function
        End If
    Next i
    
    GetClassCode = "TQBR" ' По умолчанию для акций
End Function

' Получение настройки
Private Function GetSetting(settingName As String) As String
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Настройки")
    
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    
    Dim i As Long
    For i = 3 To lastRow
        If ws.Cells(i, "A").Value = settingName Then
            GetSetting = ws.Cells(i, "B").Value
            Exit Function
        End If
    Next i
    
    GetSetting = ""
End Function

' Обновление статуса
Private Sub UpdateStatus(message As String)
    ThisWorkbook.Sheets("Торговля").Range("H1").Value = message
    Debug.Print Format(Now, "hh:nn:ss") & " - " & message
End Sub

' ==================== АВТОМАТИЗАЦИЯ ====================

' Запуск автоматического обновления
Public Sub StartAutoUpdate()
    UpdateStatus "Запуск автоматического обновления..."
    
    ' Обновляем котировки сразу
    UpdateQuotes
    
    ' Запускаем периодическое обновление (каждые 10 секунд)
    Application.OnTime Now + TimeValue("00:00:10"), "ScheduledUpdate"
End Sub

' Плановое обновление
Public Sub ScheduledUpdate()
    On Error GoTo ErrorHandler
    
    If ThisWorkbook.Sheets("Настройки").Range("B2").Value = "ДА" Then
        UpdateQuotes
        UpdatePortfolio
    End If
    
    ' Планируем следующее обновление
    Application.OnTime Now + TimeValue("00:00:10"), "ScheduledUpdate"
    
    Exit Sub
ErrorHandler:
    UpdateStatus "Ошибка планового обновления: " & Err.Description
    Application.OnTime Now + TimeValue("00:00:30"), "ScheduledUpdate"
End Sub

' Остановка автоматического обновления
Public Sub StopAutoUpdate()
    On Error Resume Next
    Application.OnTime EarliestTime:=Now + TimeValue("00:00:01"), _
                      Procedure:="ScheduledUpdate", Schedule:=False
    UpdateStatus "Автообновление остановлено"
End Sub

' Обновление портфеля
Public Sub UpdatePortfolio()
    ' Здесь можно добавить логику обновления позиций
    ' через DDE запросы к таблицам QUIK (depo_limits, money_limits)
End Sub

' ==================== ОБРАБОТЧИКИ СОБЫТИЙ ====================

' Автозапуск при открытии файла
Private Sub Workbook_Open()
    UpdateStatus "Файл открыт. Для подключения к QUIK нажмите 'Подключиться'"
    
    ' Инициализируем интерфейс
    InitializeInterface
End Sub

' Инициализация интерфейса
Private Sub InitializeInterface()
    ' Добавляем кнопки на лист торговли
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Торговля")
    
    ' Создаем заголовки если их нет
    If ws.Range("A1").Value = "" Then
        ws.Range("A1:G1").Value = Array("Тикер", "Операция", "Кол-во лотов", "Цена", "Статус", "ID заявки", "Действие")
    End If
    
    UpdateStatus "Готов к работе"
End Sub

🎯 Шаг 4: Добавляем кнопки управления

4.1. На листе «Торговля» создаем кнопки:

vba
' В редакторе VBA добавьте этот код в модуль листа "Торговля"

' Кнопка "Подключиться к QUIK"
Private Sub btnConnect_Click()
    InitializeQUIKConnection
End Sub

' Кнопка "Обновить котировки"  
Private Sub btnUpdateQuotes_Click()
    UpdateQuotes
End Sub

' Кнопка "Отправить заявки"
Private Sub btnSendOrders_Click()
    SendLimitOrder
End Sub

' Кнопка "Автообновление ВКЛ"
Private Sub btnAutoOn_Click()
    ThisWorkbook.Sheets("Настройки").Range("B2").Value = "ДА"
    StartAutoUpdate
End Sub

' Кнопка "Автообновление ВЫКЛ"
Private Sub btnAutoOff_Click()
    ThisWorkbook.Sheets("Настройки").Range("B2").Value = "НЕТ" 
    StopAutoUpdate
End Sub

📋 Шаг 5: Инструкция по использованию

5.1. Первый запуск:

  1. Откройте QUIK и подключитесь к брокеру

  2. Откройте Excel файл

  3. Нажмите «Подключиться к QUIK»

  4. Проверьте статус подключения

5.2. Ручная торговля:

  1. На листе «Торговля» введите:

    • Тикер (GAZP, SBER и т.д.)

    • Операция (BUY/SELL)

    • Кол-во лотов

    • Цену

  2. Нажмите «ОТПРАВИТЬ» в столбце G

  3. Следите за статусом в столбце E

5.3. Автоматическое обновление:

  • Включите автообновление для получения котировок каждые 10 секунд

🔧 Шаг 6: Настройка безопасности Excel

  1. Файл → Параметры → Центр управления безопасностью

  2. Параметры макросов → Включить все макросы

  3. Надежные издатели → Доверять доступ к объектной модели VBA

💾 Шаг 7: Сохранение файла

Сохраните как «Торговля ММВБ.xlsm» (с поддержкой макросов)

 🚀 Тестируйте на демо-счете перед реальной торговлей.

 






  • обсудить на форуме:
  • QUIK
452 | ★3
2 комментария
а зачем?)
avatar
Йонатан Берсон, 
avatar

Читайте на SMART-LAB:
Инвестиции без спешки: торгуем в выходные
Рынок часто движется импульсами, и тем важнее оценивать активы без спешки, не отвлекаясь на инфошум. В конце недели разбираем самые заметные...
Налоговая льгота ЛДВ-РИИ в 2025: новые правила и бумаги
Для инвесторов, ориентированных на высокотехнологичный сектор, льгота по долгосрочному владению ценными бумагами инновационных компаний (п. 17.2-1...
Фото
📝 Еженедельный дайджест от ГК «А101» с комментариями экспертов
Рост ставок по депозитам, инвестиции в недвижимость и меморандум РФ и Саудовской Аравии 📊 Новости в мире финансов и...

теги блога TaurusGOLD

....все тэги



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