-
Notifications
You must be signed in to change notification settings - Fork 163
/
Copy pathInMemoryMktSymbolList.h
205 lines (170 loc) · 7.82 KB
/
InMemoryMktSymbolList.h
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/************************************************************************
* Copyright(c) 2012, One Unified. All rights reserved. *
* email: [email protected] *
* *
* This file is provided as is WITHOUT ANY WARRANTY *
* without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* *
* This software may not be used nor distributed without proper license *
* agreement. *
* *
* See the file LICENSE.txt for redistribution information. *
************************************************************************/
#pragma once
// Started 2012/10/14
#include <string>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <fstream>
#include "SecurityType.h"
#include "MarketSymbol.h"
namespace ou { // One Unified
namespace tf { // TradeFrame
namespace iqfeed { // IQFeed
class InMemoryMktSymbolList {
public:
struct ixSymbol{};
struct ixExchange{};
struct ixSymbolClass{};
//struct ixSic{};
//struct ixNaics{};
struct ixUnderlying{};
using trd_t = ou::tf::iqfeed::MarketSymbol::TableRowDef;
using symbols_t = boost::multi_index_container<
trd_t,
boost::multi_index::indexed_by<
boost::multi_index::ordered_unique<
boost::multi_index::tag<ixSymbol>, BOOST_MULTI_INDEX_MEMBER(trd_t,std::string,sSymbol)>,
boost::multi_index::ordered_non_unique<
boost::multi_index::tag<ixExchange>, BOOST_MULTI_INDEX_MEMBER(trd_t,std::string,sExchange)>,
boost::multi_index::ordered_non_unique<
boost::multi_index::tag<ixSymbolClass>, BOOST_MULTI_INDEX_MEMBER(trd_t,ESecurityType,sc)>,
// boost::multi_index::ordered_non_unique<
// boost::multi_index::tag<ixSic>, BOOST_MULTI_INDEX_MEMBER(trd_t,boost::uint32_t,nSIC)>,
// boost::multi_index::ordered_non_unique<
// boost::multi_index::tag<ixNaics>, BOOST_MULTI_INDEX_MEMBER(trd_t,boost::uint32_t,nNAICS)>,
boost::multi_index::ordered_non_unique< // IQFeed file doesn't provide good info, and option symbology sucks
boost::multi_index::tag<ixUnderlying>, BOOST_MULTI_INDEX_MEMBER(trd_t,std::string,sUnderlying)>
>
>;
using iterator = symbols_t::iterator;
iterator begin(){return m_symbols.begin();}
iterator end(){return m_symbols.end();}
symbols_t::size_type Size( void ) const { return m_symbols.size(); }
bool Exists( const std::string& sName ) {
using ixSymbol_t = symbols_t::index<ixSymbol>::type;
ixSymbol_t::const_iterator endSymbols = m_symbols.get<ixSymbol>().end();
ixSymbol_t::const_iterator iter = m_symbols.get<ixSymbol>().find( sName );
return ( endSymbols != iter );
}
bool HandleSymbolHasOption( const std::string& s ) {
using SymbolsByName_t = symbols_t::index<ixSymbol>::type;
SymbolsByName_t::iterator iter = m_symbols.get<ixSymbol>().find( s );
bool bReturn = false;
if ( m_symbols.get<ixSymbol>().end() != iter ) {
const_cast<bool&>( iter->bHasOptions ) = true;
bReturn = true;
}
return bReturn;
}
void HandleUpdateOptionUnderlying( const std::string& sSymbol, const std::string& sUnderlying ) {
using SymbolsByName_t = symbols_t::index<ixSymbol>::type;
SymbolsByName_t::iterator iter = m_symbols.get<ixSymbol>().find( sSymbol );
bool bReturn = false;
if ( m_symbols.get<ixSymbol>().end() != iter ) {
const_cast<std::string&>( iter->sUnderlying ) = sUnderlying;
}
}
void SaveToFile(const std::string& sFilename) const {
std::ofstream ofs( sFilename, std::ios::binary );
boost::archive::binary_oarchive oa( ofs );
oa << boost::serialization::make_nvp( "symbols", *this );
}
void LoadFromFile( const std::string& sFilename ) {
m_symbols.clear();
std::ifstream ifs( sFilename, std::ios::binary );
if ( ifs ) {
boost::archive::binary_iarchive ia(ifs);
ia >> boost::serialization::make_nvp( "symbols", *this );
}
}
const trd_t& GetTrd( const std::string& sName ) const {
using ixSymbol_t = symbols_t::index<ixSymbol>::type;
ixSymbol_t::const_iterator endSymbols = m_symbols.get<ixSymbol>().end();
ixSymbol_t::const_iterator iter = m_symbols.get<ixSymbol>().find( sName );
if ( endSymbols == iter ) {
throw std::runtime_error( "GetTrd can't find " + sName );
}
return *iter;
}
template<typename Function> // not sure if functions correctly, particularily if option list has other symbols interspersed
void SelectOptionsBySymbol( const std::string& sUnderlying, Function f ) const {
using ixSymbol_t = symbols_t::index<ixSymbol>::type;
ixSymbol_t::const_iterator endSymbols = m_symbols.get<ixSymbol>().end();
for ( ixSymbol_t::const_iterator iter = m_symbols.get<ixSymbol>().find( sUnderlying ); endSymbols != iter; ++iter ) {
if ( ou::tf::iqfeed::ESecurityType::IEOption == iter->sc ) {
if ( iter->sUnderlying != sUnderlying ) break;
f( *iter );
}
}
}
// requires index by underlying, which may be taking up mucho room, actually doesn't
template<typename Function>
void SelectOptionsByUnderlying( const std::string& sUnderlying, Function f ) const {
using SymbolsByUnderlying_t = symbols_t::index<ixUnderlying>::type;
SymbolsByUnderlying_t::const_iterator endSymbols = m_symbols.get<ixUnderlying>().end();
for ( SymbolsByUnderlying_t::const_iterator iter = m_symbols.get<ixUnderlying>().find( sUnderlying ); endSymbols != iter; ++iter ) {
if ( iter->sUnderlying != sUnderlying ) break;
f( *iter );
}
}
template<typename ExchangeIterator, typename Function>
void SelectSymbolsByExchange( ExchangeIterator beginExchange, ExchangeIterator endExchange, Function f ) const {
using SymbolsByExchange_t = symbols_t::index<ixExchange>::type;
SymbolsByExchange_t::const_iterator endSymbols = m_symbols.get<ixExchange>().end();
while ( beginExchange != endExchange ) {
SymbolsByExchange_t::const_iterator iterSymbols = m_symbols.get<ixExchange>().find( *beginExchange );
while ( endSymbols != iterSymbols ) {
if ( *beginExchange != iterSymbols->sExchange ) break;
f( *iterSymbols );
iterSymbols++;
}
beginExchange++;
}
}
template<typename Function>
void ScanSymbols( Function f ) const { // 2015/02/22 was Function& f
using Symbols_t = symbols_t::index<ixSymbol>::type;
Symbols_t::const_iterator endSymbols = m_symbols.get<ixSymbol>().end();
for ( Symbols_t::const_iterator iterSymbols = m_symbols.get<ixSymbol>().begin(); endSymbols != iterSymbols; iterSymbols++ ) {
f( *iterSymbols );
}
}
void InsertParsedStructure( const trd_t& trd ) {
auto result = m_symbols.insert( trd );
if ( !result.second ) {
assert( result.second );
}
}
void operator()( const trd_t& trd ) {
m_symbols.insert( trd );
}
void Clear( void ) { m_symbols.clear(); };
protected:
private:
symbols_t m_symbols;
void insert( trd_t& trd ) { m_symbols.insert( trd ); };
/* serialization support */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar,const unsigned int) {
ar&BOOST_SERIALIZATION_NVP(m_symbols);
}
};
} // namespace iqfeed
} // namespace tf
} // namespace ou