Блог им. 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
552 | ★3
3 комментария
а зачем?)
avatar
Йонатан Берсон, 
avatar

Читайте на SMART-LAB:
Фото
BRENT: Дипломатия Трампа против "бычьего десанта" — кто блефует?
После сенсационного заявления Трампа о достижении двухнедельного перемирия с Ираном нефть открыла торги в среду с мощным гэпом вниз. Цена...
Группа Позитив почти удвоила чистую прибыль в 2025 году
Акции Группы Позитив на торгах 8 апреля прибавляют 0,74%, до 1010 руб., отыгрывая сильные результаты по МСФО за 2025 год, опубликованные...
Фото
Трейдинг по ролям: права и контроль доступа в командах
Утечка конфиденциальных стратегий, перегрузка системы, доступ к чужим ордерам без разрешения, изменение данных в алгоритмах и ботах коллег —...
Фото
Кто сейчас самый дешевый сбыт? Сводный пост по сбытовым компаниям по отчетам РСБУ за 2025г.
Волгоградэнергосбыт Ставропольэнергосбыт Самараэнерго Мордовэнергосбыт Пермэнергосбыт Новосибирскэнергосбыт...

теги блога TaurusGOLD

....все тэги



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