Появилась задача держать базу котировок с риалтайм обновлением. Поскольку в базе нужны барные данные, а не тиковые, а напрямую из Quik экспорта барных данных нет (а пляски с Qpile меня не привлекают), было решено из Quik транслировать текущую таблицу в Excel а там уже обеспечивать взаимодействие с базой с нарезкой нужной барности. Получившийся код выкладываю, вдруг еще кому пригодится.
Бары в базе получаются 15 минутные, можете поменять таймфрейм модифицировав фрагмент:
В MySQL создаем таблицу:
Чтобы Excel мог взаимодействовать с MySQL, нужно установить ODBC и включить в VBA в меню Tools/References пункт Microsoft ActiveX Data Objects 2.8 Library.
В Excel делаете лист, экспортируете туда текущую таблицу параметров с колонками "код", "цена", "время". в какой-нибудь сторонней ячейке делаете сумму по всем ячейкам содержащим цену и время, чтобы запустить событие onCalculate. Дальше модифицируем процедуру листа Worksheet_Calculate():
Бары в базе получаются 15 минутные, можете поменять таймфрейм модифицировав фрагмент:
Код:
mm = Format(15 * Fix(mm / 15), "00")
Код:
CREATE TABLE `quik` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ticker` varchar(10) DEFAULT NULL,
`date` char(8) DEFAULT NULL,
`time` char(6) DEFAULT NULL,
`open` double DEFAULT NULL,
`high` double DEFAULT NULL,
`low` double DEFAULT NULL,
`close` double DEFAULT NULL,
PRIMARY KEY (`id`)
);
В Excel делаете лист, экспортируете туда текущую таблицу параметров с колонками "код", "цена", "время". в какой-нибудь сторонней ячейке делаете сумму по всем ячейкам содержащим цену и время, чтобы запустить событие onCalculate. Дальше модифицируем процедуру листа Worksheet_Calculate():
Код:
Private Sub Worksheet_Calculate()
Const TickerColumn = 1
Const PriceColumn = 3
Const TimeColumn = 4
Const LastPriceColumn = 13
Const LastTimeColumn = 14
Const WorkbookName = "2optima.xls"
Const WorksheetName = "export"
Dim delta As Double, start As Date, morning As Date, evening As Date
morning = CDate("10:30:00")
evening = CDate("18:44:58")
If (Time < morning) Or (Time > evening) Then Exit Sub
Dim rr As Range, ticker As String, tm As Date, d As Date, price As Double, ts, ds
Dim oConn As ADODB.Connection
Dim rs As ADODB.Recordset
Set oConn = New ADODB.Connection
oConn.Open "DRIVER={MySQL ODBC 5.1 Driver};" & _
"SERVER=localhost;" & _
"DATABASE=dbname;" & _
"USER=dbuser;" & _
"PASSWORD=dbpass;" & _
"Option=3"
Dim query
Set rs = New ADODB.Recordset
For Each rr In Application.Workbooks(WorkbookName).Worksheets(WorksheetName).Rows.CurrentRegion.Rows
If ((rr.Cells(1, PriceColumn) <> rr.Cells(1, LastPriceColumn)) Or (rr.Cells(1, TimeColumn) <> rr.Cells(1, LastTimeColumn))) Then
rr.Cells(1, LastPriceColumn) = rr.Cells(1, PriceColumn)
rr.Cells(1, LastTimeColumn) = rr.Cells(1, TimeColumn)
ticker = CStr(rr.Cells(1, TickerColumn))
price = rr.Cells(1, PriceColumn)
If rr.Cells(1, TimeColumn) = "" Then
tm = Format(Time, "hhmmss")
Else
tm = CDate(rr.Cells(1, TimeColumn))
End If
ts = Format(tm, "hhmmss")
ds = Format(Date, "yyyymmdd")
Dim hh, mm, ss, starttime
hh = Mid(ts, 1, 2)
mm = Mid(ts, 3, 2)
mm = Format(15 * Fix(mm / 15), "00")
starttime = hh & mm & "00"
query = "select * from quik where ticker='" & ticker & "' and date='" & ds & "' and time='" & starttime & "'"
rs.Open query, oConn
Dim sh, so, sl, sc, cnt, pricestr As String, hs, os, ls, cs
cnt = 0
Do While Not rs.EOF
so = CDbl(Replace(rs.Fields("open").Value, ".", ","))
sh = CDbl(Replace(rs.Fields("high").Value, ".", ","))
sl = CDbl(Replace(rs.Fields("low").Value, ".", ","))
sc = CDbl(Replace(rs.Fields("close").Value, ".", ","))
rs.MoveNext
cnt = cnt + 1
Loop
If cnt = 0 Then
pricestr = Replace(price, ",", ".")
query = "insert into quik (ticker,date,time,open,high,low,close) values('" & ticker & "','" & ds & "','" & starttime & "'," & pricestr & "," & pricestr & "," & pricestr & "," & pricestr & ")"
Else
If sc <> price Then
If price > sh Then hs = Replace(price, ",", ".") Else hs = Replace(sh, ",", ".")
If price < sl Then ls = Replace(price, ",", ".") Else ls = Replace(sl, ",", ".")
cs = Replace(price, ",", ".")
query = "update quik set high=" & hs & ",low=" & ls & ",close=" & cs & " where ticker='" & ticker & "' and date='" & ds & "' and time='" & starttime & "'"
Else
query = ""
End If
End If
If query <> "" Then
'Debug.Print query
oConn.Execute query
End If
rs.Close
End If
Next rr
Set rs = Nothing
oConn.Close
Set oConn = Nothing
End Sub