dxFeed Graal CXX API v7.0.0
Loading...
Searching...
No Matches
OptionSeries.hpp
1// Copyright (c) 2025 Devexperts LLC.
2// SPDX-License-Identifier: MPL-2.0
3
4#pragma once
5
6#include "../../internal/Conf.hpp"
7
9
10#include "../../internal/Common.hpp"
11
12#include <algorithm>
13#include <cstdint>
14#include <map>
15#include <memory>
16#include <set>
17#include <sstream>
18#include <string>
19#include <utility>
20#include <vector>
21
22/**
23 * \addtogroup dxfcpp_ipf
24 * @{
25 */
26
28
29template <typename T> class OptionChainsBuilder;
30
31/**
32 * Series of call and put options with different strike sharing the same attributes of expiration, last trading day,
33 * spc, multiplies, etc.
34 *
35 * <h3>Threads and locks</h3>
36 * This class is <b>NOT</b> thread-safe and cannot be used from multiple threads without external synchronization.
37 *
38 * @tparam T The type of option instrument instances.
39 */
40template <typename T> class OptionSeries final {
41 friend class OptionChainsBuilder<T>;
42
43 std::int32_t expiration_ = 0;
44 std::int32_t lastTrade_ = 0;
45 double multiplier_ = 0.0;
46 double spc_ = 0.0;
47 std::string additionalUnderlyings_{};
48 std::string mmy_{};
49 std::string optionType_{};
50 std::string expirationStyle_{};
51 std::string settlementStyle_{};
52 std::string cfi_{};
53
54 std::map<double, std::shared_ptr<T>> calls_{};
55 std::map<double, std::shared_ptr<T>> puts_{};
56
57 mutable std::vector<double> strikes_{}; // Cached list of strikes
58
59 public:
60 /**
61 * Default constructor for the OptionSeries class.
62 *
63 * @return A default-initialized instance of OptionSeries.
64 */
66
67 /**
68 * Returns day id of expiration.
69 * Example: @ref day_util::#getDayIdByYearMonthDay() "dxfcpp::day_util::getDayIdByYearMonthDay"(20090117).
70 *
71 * @return day id of expiration.
72 */
74 return expiration_;
75 }
76
77 /**
78 * Returns day id of last trading day.
79 * Example: @ref day_util::#getDayIdByYearMonthDay() "dxfcpp::day_util::getDayIdByYearMonthDay"(20090116).
80 *
81 * @return The day id of last trading day.
82 */
84 return lastTrade_;
85 }
86
87 /**
88 * Returns market value multiplier.
89 * Example: 100, 33.2.
90 *
91 * @return The market value multiplier.
92 */
93 double getMultiplier() const {
94 return multiplier_;
95 }
96
97 /**
98 * Returns shares per contract for options.
99 * Example: 1, 100.
100 *
101 * @return The shares per contract for options.
102 */
103 double getSPC() const {
104 return spc_;
105 }
106
107 /**
108 * Returns additional underlyings for options, including additional cash.
109 * It shall use following format:
110 * ```
111 * <VALUE> ::= <empty> | <LIST>
112 * <LIST> ::= <AU> | <AU> <semicolon> <space> <LIST>
113 * <AU> ::= <UNDERLYING> <space> <SPC>
114 * ```
115 * The list shall be sorted by <UNDERLYING>.
116 * Example: "SE 50", "FIS 53; US$ 45.46".
117 *
118 * @return The additional underlyings for options, including additional cash.
119 */
121 return additionalUnderlyings_;
122 }
123
124 /**
125 * Returns maturity month-year as provided for corresponding FIX tag (200).
126 * It can use several different formats depending on data source:
127 * <ul>
128 * <li>YYYYMM – if only year and month are specified
129 * <li>YYYYMMDD – if full date is specified
130 * <li>YYYYMMwN – if week number (within a month) is specified
131 * </ul>
132 *
133 * @return The maturity month-year as provided for corresponding FIX tag (200).
134 */
135 const std::string &getMMY() const {
136 return mmy_;
137 }
138
139 /**
140 * Returns type of option.
141 * It shall use one of following values:
142 * <ul>
143 * <li>STAN = Standard Options
144 * <li>LEAP = Long-term Equity AnticiPation Securities
145 * <li>SDO = Special Dated Options
146 * <li>BINY = Binary Options
147 * <li>FLEX = FLexible EXchange Options
148 * <li>VSO = Variable Start Options
149 * <li>RNGE = Range
150 * </ul>
151 *
152 * @return The type of option.
153 */
154 const std::string &getOptionType() const {
155 return optionType_;
156 }
157
158 /**
159 * Returns expiration cycle style, such as "Weeklys", "Quarterlys".
160 *
161 * @return The expiration cycle style.
162 */
163 const std::string &getExpirationStyle() const {
164 return expirationStyle_;
165 }
166
167 /**
168 * Returns settlement price determination style, such as "Open", "Close".
169 *
170 * @return The settlement price determination style.
171 */
172 const std::string &getSettlementStyle() const {
173 return settlementStyle_;
174 }
175
176 /**
177 * Returns Classification of Financial Instruments code.
178 * It is a mandatory field for OPTION instruments as it is the only way to distinguish Call/Put type,
179 * American/European exercise, Cash/Physical delivery.
180 * It shall use six-letter CFI code from ISO 10962 standard.
181 * It is allowed to use 'X' extensively and to omit trailing letters (assumed to be 'X').
182 * See <a href="http://en.wikipedia.org/wiki/ISO_10962">ISO 10962 on Wikipedia</a>.
183 * Example: "ESNTPB", "ESXXXX", "ES" , "OPASPS".
184 *
185 * @return The CFI code.
186 */
187 const std::string &getCFI() const {
188 return cfi_;
189 }
190
191 /**
192 * Returns a sorted map of all calls from strike to a corresponding option instrument.
193 *
194 * @return A sorted map of all calls from strike to a corresponding option instrument.
195 */
196 const std::map<double, std::shared_ptr<T>> &getCalls() const {
197 return calls_;
198 }
199
200 /**
201 * Returns a sorted map of all puts from strike to a corresponding option instrument.
202 *
203 * @return A sorted map of all puts from strike to a corresponding option instrument.
204 */
205 const std::map<double, std::shared_ptr<T>> &getPuts() const {
206 return puts_;
207 }
208
209 /**
210 * Returns a list of all strikes in ascending order.
211 *
212 * @return A list of all strikes in ascending order.
213 */
214 const std::vector<double> &getStrikes() const {
215 if (strikes_.empty()) {
216 std::set<double> strikesSet{};
217
218 for (const auto &call : calls_) {
219 strikesSet.insert(call.first);
220 }
221
222 for (const auto &put : puts_) {
223 strikesSet.insert(put.first);
224 }
225
226 strikes_.assign(strikesSet.begin(), strikesSet.end());
227 }
228
229 return strikes_;
230 }
231
232 /**
233 * Returns n strikes which are centered around a specified strike value.
234 *
235 * @param n The maximal number of strikes to return.
236 * @param strike The center strike.
237 * @return n strikes which are centered around a specified strike value.
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);
245
246 return std::vector<double>(strikesVector.begin() + fromIndex, strikesVector.begin() + toIndex);
247 }
248
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_;
255 }
256
257 bool operator!=(const OptionSeries &other) const {
258 return !(*this == other);
259 }
260
261 bool operator<(const OptionSeries &other) const {
262 if (expiration_ != other.expiration_) {
263 return expiration_ < other.expiration_;
264 }
265
266 if (lastTrade_ != other.lastTrade_) {
267 return lastTrade_ < other.lastTrade_;
268 }
269
270 if (multiplier_ != other.multiplier_) {
271 return multiplier_ < other.multiplier_;
272 }
273
274 if (spc_ != other.spc_) {
275 return spc_ < other.spc_;
276 }
277
278 if (additionalUnderlyings_ != other.additionalUnderlyings_) {
279 return additionalUnderlyings_ < other.additionalUnderlyings_;
280 }
281
282 if (mmy_ != other.mmy_) {
283 return mmy_ < other.mmy_;
284 }
285
286 if (optionType_ != other.optionType_) {
287 return optionType_ < other.optionType_;
288 }
289
290 if (expirationStyle_ != other.expirationStyle_) {
291 return expirationStyle_ < other.expirationStyle_;
292 }
293
294 if (settlementStyle_ != other.settlementStyle_) {
295 return settlementStyle_ < other.settlementStyle_;
296 }
297
298 return cfi_ < other.cfi_;
299 }
300
301 void addOption(bool isCall, double strike, std::shared_ptr<T> option) {
302 if (auto &map = isCall ? calls_ : puts_; map.emplace(strike, option).second) {
303 strikes_.clear();
304 }
305 }
306
307 /**
308 * Returns a string representation of the current object.
309 *
310 * @return A string representation.
311 */
312 std::string toString() const {
313 std::ostringstream ss{};
314
315 ss << "expiration=" << expiration_;
316
317 if (lastTrade_ != 0) {
318 ss << ", lastTrade=" << lastTrade_;
319 }
320
321 if (multiplier_ != 0) {
322 ss << ", multiplier=" << multiplier_;
323 }
324
325 if (spc_ != 0) {
326 ss << ", spc=" << spc_;
327 }
328
329 if (!additionalUnderlyings_.empty()) {
330 ss << ", additionalUnderlyings=" << additionalUnderlyings_;
331 }
332
333 if (!mmy_.empty()) {
334 ss << ", mmy=" << mmy_;
335 }
336
337 if (!optionType_.empty()) {
338 ss << ", optionType=" << optionType_;
339 }
340
341 if (!expirationStyle_.empty()) {
342 ss << ", expirationStyle=" << expirationStyle_;
343 }
344
345 if (!settlementStyle_.empty()) {
346 ss << ", settlementStyle=" << settlementStyle_;
347 }
348
349 ss << ", cfi=" << cfi_;
350
351 return ss.str();
352 }
353
354 friend std::ostream &operator<<(std::ostream &os, const OptionSeries &series) {
355 os << series.toString();
356
357 return os;
358 }
359
360 std::size_t hashCode() const {
361 auto result = static_cast<std::size_t>(expiration_);
362
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_);
372
373 return result;
374 }
375};
376
378
379/// @}
380
381template <typename T> struct std::hash<dxfcpp::OptionSeries<T>> {
382 std::size_t operator()(const dxfcpp::OptionSeries<T> &optionSeries) const noexcept {
383 return optionSeries.hashCode();
384 }
385};
386
#define DXFCXX_DISABLE_MSC_WARNINGS_POP()
Definition Conf.hpp:31
#define DXFCPP_END_NAMESPACE
Definition Conf.hpp:97
#define DXFCPP_BEGIN_NAMESPACE
Definition Conf.hpp:94
#define DXFCXX_DISABLE_MSC_WARNINGS_PUSH(warnings)
Definition Conf.hpp:30
Builder class for a set of option chains grouped by product or underlying symbol.
Definition OptionChainsBuilder.hpp:32
OptionSeries()
Default constructor for the OptionSeries class.
Definition OptionSeries.hpp:65
const std::string & getCFI() const
Returns Classification of Financial Instruments code.
Definition OptionSeries.hpp:187
const std::string & getMMY() const
Returns maturity month-year as provided for corresponding FIX tag (200).
Definition OptionSeries.hpp:135
std::int32_t getExpiration() const
Returns day id of expiration.
Definition OptionSeries.hpp:73
const std::string & getOptionType() const
Returns type of option.
Definition OptionSeries.hpp:154
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
double getSPC() const
Returns shares per contract for options.
Definition OptionSeries.hpp:103
double getMultiplier() const
Returns market value multiplier.
Definition OptionSeries.hpp:93
std::int32_t getLastTrade() const
Returns day id of last trading day.
Definition OptionSeries.hpp:83
const std::string & getAdditionalUnderlyings() const
Returns additional underlyings for options, including additional cash.
Definition OptionSeries.hpp:120