-
Notifications
You must be signed in to change notification settings - Fork 138
/
Copy pathbar_collector.cpp
130 lines (114 loc) · 3.99 KB
/
bar_collector.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <QDataStream>
#include <QDebug>
#include <QMetaEnum>
#include <QDateTime>
#include <QFile>
#include <QDir>
#include "bar.h"
#include "bar_collector.h"
extern int barCollector_enumIdx;
QString BarCollector::collector_dir;
BarCollector::BarCollector(const QString& instrumentID, const TimeFrames &time_frame_flags, QObject *parent) :
QObject(parent),
instrument(instrumentID)
{
QSet<TimeFrame> key_set;
uint mask = 0x80;
while (mask != 0x00) {
int result = time_frame_flags & mask;
if (result != 0) {
key_set.insert(static_cast<TimeFrame>(result));
}
mask >>= 1;
}
key_set.insert(TimeFrame::MIN1);
keys = key_set.toList();
foreach (const auto key, keys) {
bar_list_map.insert(key, QList<Bar>());
current_bar_map.insert(key, Bar());
// Check if the directory is already created for collected bars
QString time_frame_str = BarCollector::staticMetaObject.enumerator(barCollector_enumIdx).valueToKey(key);
QString path_for_this_key = collector_dir + "/" + instrument + "/" + time_frame_str;
QDir dir(path_for_this_key);
if (!dir.exists()) {
bool ret = dir.mkpath(path_for_this_key);
if (!ret) {
qDebug() << "Create directory failed!";
}
}
}
lastVolume = 0;
}
BarCollector::~BarCollector()
{
saveBars();
}
Bar* BarCollector::getCurrentBar(const QString &time_frame_str)
{
int time_frame_value = BarCollector::staticMetaObject.enumerator(barCollector_enumIdx).keyToValue(time_frame_str.trimmed().toLatin1().data());
TimeFrame time_frame = static_cast<BarCollector::TimeFrame>(time_frame_value);
return ¤t_bar_map[time_frame];
}
#define MIN_UNIT 60
#define HOUR_UNIT 3600
static const auto g_time_table = []() -> QMap<BarCollector::TimeFrame, uint> {
QMap<BarCollector::TimeFrame, uint> timeTable;
timeTable.insert(BarCollector::MIN1, 1 * MIN_UNIT);
timeTable.insert(BarCollector::MIN5, 5 * MIN_UNIT);
timeTable.insert(BarCollector::MIN15, 15 * MIN_UNIT);
timeTable.insert(BarCollector::MIN60, 1 * HOUR_UNIT);
return timeTable;
}();
bool BarCollector::onMarketData(uint time, double lastPrice, int volume)
{
bool isNewTick = (volume == lastVolume);
foreach (const auto key, keys) {
Bar & bar = current_bar_map[key];
const uint time_unit = g_time_table[key]; // TODO optimize, use time_unit as key
if ((time / time_unit) != (bar.time / time_unit)) {
if (bar.tick_volume > 0) {
bar_list_map[key].append(bar);
emit collectedBar(instrument, key, bar);
qDebug() << instrument << ": " << bar;
bar.init();
}
}
if (isNewTick) {
continue;
}
if (bar.isNewBar()) {
bar.open = lastPrice;
// TODO add data, save as time_t format
bar.time = time / time_unit * time_unit;
}
if (lastPrice > bar.high) {
bar.high = lastPrice;
}
if (lastPrice < bar.low) {
bar.low = lastPrice;
}
bar.close = lastPrice;
bar.tick_volume ++;
bar.volume += (volume - lastVolume);
}
lastVolume = volume;
return isNewTick;
}
void BarCollector::saveBars()
{
foreach (const auto key, keys) {
auto & barList = bar_list_map[key];
if (barList.size() == 0) {
continue;
}
QString time_frame_str = BarCollector::staticMetaObject.enumerator(barCollector_enumIdx).valueToKey(key);
QString file_name = collector_dir + "/" + instrument + "/" + time_frame_str + "/" + QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss_zzz") + ".bars";
QFile barFile(file_name);
barFile.open(QFile::WriteOnly);
QDataStream wstream(&barFile);
wstream.setFloatingPointPrecision(QDataStream::DoublePrecision);
wstream << barList;
barFile.close();
barList.clear();
}
}