在量化時, CTP是期貨交易量化的開發(fā)平臺, 但其提供的行情時tick級別的, 常需要進行轉(zhuǎn)換.
而通過Julia實現(xiàn)時, 會很方便將tick序列轉(zhuǎn)為任意周期(包括分鐘,小時等)的Bar序列.
本方法的特點:
- 目標序列周期任意
- 源序列周期可任意, 但理應(yīng)比目標周期小
- 不需進行大量的臨時序列和內(nèi)存拷貝
本方法使用到一個Package: TimeFrames.
源數(shù)據(jù)序列應(yīng)該是Array{T,1}
類型, 其中的T
可以是Float64
,Int
或其他數(shù)值類型. 假設(shè)源數(shù)據(jù)為如下的四項基本的浮點序列:
src_length = 100
# TODO: 該處為預先準備的src_length長度時間序列, 這里不提供有效數(shù)據(jù)
src_time = Array{DateTime,1}()
src_open = rand(src_length)
src_high = rand(src_length)
src_low = rand(src_length)
src_close = rand(src_length)
事實上, 這些可以是 DataFrames
結(jié)構(gòu)或者是TimeSeries
結(jié)構(gòu)的某列.
轉(zhuǎn)換前, 先聲明一個想轉(zhuǎn)成的時間周期:
using TimeFrames
to_tf = Minute(5) # 要源序列轉(zhuǎn)成5分鐘級別的
# 或
# to_tf = TimeFrame("5T")
再定義一個臨時變量, 跟蹤源數(shù)據(jù)窗口:
cursor = [1 1]
好了, 可以開始轉(zhuǎn)換了.
這里提供 批量 方式, 如果實時增量轉(zhuǎn)換, 需稍微改動一下.
# 從頭遍歷源序列
for i = 1:src_length
# 折算當前時間所屬的目標周期的時間點
dtf = apply(to_tf, src_time[i])
cursor[2] = i
if dtf == src_time[i] # 正好處于新周期的時間點
bartime = Base.last(view(src_time, cursor[1]: cursor[2]))
# 或
# bartime = src_time[i]
baropen = first(view(src_open, cursor[1]: cursor[2]))
# 或
# baropen = src_open[cursor[1]]
barhigh = reduce(max, view(src_high, cursor[1]: cursor[2]) )
barlow = reduce(min, view(src_low, cursor[1]: cursor[2]) )
barclose = Base.last(view(src_close cursor[1]: cursor[2]))
# 或
# barclose = src_open[cursor[2]]
@show (bartime, baropen, barhigh, barlow, barclose)
cursor[1] = cursor[2]+1
end
end
- 說明
- 采用內(nèi)嵌的
view
方法, 是建立了在源序列數(shù)據(jù)上的索引引用, 不用拷貝成臨時數(shù)據(jù)再進行max
,min
等操作. - 有些細節(jié), 比如恰好的時間點屬于前一個bar的結(jié)束, 還是新bar的開始, 需要自行確定
- 在行情剛剛開始時, 通常是整點, 會滿足上述的新周期時間點的判定, 需要自行處理.
- 采用內(nèi)嵌的