40template <
typename T>
class OptionSeries final {
43 std::int32_t expiration_ = 0;
44 std::int32_t lastTrade_ = 0;
45 double multiplier_ = 0.0;
47 std::string additionalUnderlyings_{};
49 std::string optionType_{};
50 std::string expirationStyle_{};
51 std::string settlementStyle_{};
54 std::map<
double, std::shared_ptr<T>> calls_{};
55 std::map<
double, std::shared_ptr<T>> puts_{};
57 mutable std::vector<
double> strikes_{};
61
62
63
64
68
69
70
71
72
78
79
80
81
82
88
89
90
91
92
98
99
100
101
102
108
109
110
111
112
113
114
115
116
117
118
119
121 return additionalUnderlyings_;
125
126
127
128
129
130
131
132
133
134
140
141
142
143
144
145
146
147
148
149
150
151
152
153
159
160
161
162
164 return expirationStyle_;
168
169
170
171
173 return settlementStyle_;
177
178
179
180
181
182
183
184
185
186
192
193
194
195
196 const std::map<
double, std::shared_ptr<T>> &getCalls()
const {
201
202
203
204
205 const std::map<
double, std::shared_ptr<T>> &getPuts()
const {
210
211
212
213
214 const std::vector<
double> &getStrikes()
const {
215 if (strikes_.empty()) {
216 std::set<
double> strikesSet{};
218 for (
const auto &call : calls_) {
219 strikesSet.insert(call.first);
222 for (
const auto &put : puts_) {
223 strikesSet.insert(put.first);
226 strikes_.assign(strikesSet.begin(), strikesSet.end());
233
234
235
236
237
238
239 std::vector<
double> getNStrikesAround(std::size_t n,
double strike)
const {
240 const auto &strikesVector = getStrikes();
241 const auto it = std::lower_bound(strikesVector.begin(), strikesVector.end(), strike);
242 const std::size_t index = std::distance(strikesVector.begin(), it);
243 const std::size_t fromIndex = (index < n / 2) ? 0 : (index - n / 2);
244 const std::size_t toIndex = std::min(strikesVector.size(), fromIndex + n);
246 return std::vector<
double>(strikesVector.begin() + fromIndex, strikesVector.begin() + toIndex);
249 bool operator==(
const OptionSeries &other)
const {
250 return expiration_ == other.expiration_ && lastTrade_ == other.lastTrade_ &&
251 math::equals(multiplier_, other.multiplier_) && math::equals(spc_, other.spc_) &&
252 additionalUnderlyings_ == other.additionalUnderlyings_ && expirationStyle_ == other.expirationStyle_ &&
253 mmy_ == other.mmy_ && optionType_ == other.optionType_ && cfi_ == other.cfi_ &&
254 settlementStyle_ == other.settlementStyle_;
257 bool operator!=(
const OptionSeries &other)
const {
258 return !(*
this == other);
261 bool operator<(
const OptionSeries &other)
const {
262 if (expiration_ != other.expiration_) {
263 return expiration_ < other.expiration_;
266 if (lastTrade_ != other.lastTrade_) {
267 return lastTrade_ < other.lastTrade_;
270 if (multiplier_ != other.multiplier_) {
271 return multiplier_ < other.multiplier_;
274 if (spc_ != other.spc_) {
275 return spc_ < other.spc_;
278 if (additionalUnderlyings_ != other.additionalUnderlyings_) {
279 return additionalUnderlyings_ < other.additionalUnderlyings_;
282 if (mmy_ != other.mmy_) {
283 return mmy_ < other.mmy_;
286 if (optionType_ != other.optionType_) {
287 return optionType_ < other.optionType_;
290 if (expirationStyle_ != other.expirationStyle_) {
291 return expirationStyle_ < other.expirationStyle_;
294 if (settlementStyle_ != other.settlementStyle_) {
295 return settlementStyle_ < other.settlementStyle_;
298 return cfi_ < other.cfi_;
301 void addOption(
bool isCall,
double strike, std::shared_ptr<T> option) {
302 if (
auto &map = isCall ? calls_ : puts_; map.emplace(strike, option).second) {
308
309
310
311
312 std::string toString()
const {
313 std::ostringstream ss{};
315 ss <<
"expiration=" << expiration_;
317 if (lastTrade_ != 0) {
318 ss <<
", lastTrade=" << lastTrade_;
321 if (multiplier_ != 0) {
322 ss <<
", multiplier=" << multiplier_;
326 ss <<
", spc=" << spc_;
329 if (!additionalUnderlyings_.empty()) {
330 ss <<
", additionalUnderlyings=" << additionalUnderlyings_;
334 ss <<
", mmy=" << mmy_;
337 if (!optionType_.empty()) {
338 ss <<
", optionType=" << optionType_;
341 if (!expirationStyle_.empty()) {
342 ss <<
", expirationStyle=" << expirationStyle_;
345 if (!settlementStyle_.empty()) {
346 ss <<
", settlementStyle=" << settlementStyle_;
349 ss <<
", cfi=" << cfi_;
354 friend std::ostream &operator<<(std::ostream &os,
const OptionSeries &series) {
355 os << series.toString();
360 std::size_t hashCode()
const {
361 auto result =
static_cast<std::size_t>(expiration_);
363 hashCombine(result, lastTrade_);
364 hashCombine(result, multiplier_);
365 hashCombine(result, spc_);
366 hashCombine(result, additionalUnderlyings_);
367 hashCombine(result, mmy_);
368 hashCombine(result, optionType_);
369 hashCombine(result, expirationStyle_);
370 hashCombine(result, settlementStyle_);
371 hashCombine(result, cfi_);
const std::string & getExpirationStyle() const
Returns expiration cycle style, such as "Weeklys", "Quarterlys".
Definition OptionSeries.hpp:163
const std::string & getSettlementStyle() const
Returns settlement price determination style, such as "Open", "Close".
Definition OptionSeries.hpp:172