From 66cf12ddf653c1f36b1ce4571d452efabb4cba6b Mon Sep 17 00:00:00 2001 From: Mark Ross <6730333+krazkidd@users.noreply.github.com> Date: Sun, 14 Jul 2024 18:53:58 -0700 Subject: [PATCH 1/3] Add oatpp code generators for market API calls. --- include/api/_Api.hpp | 51 +++++++++++++++++++++++++++ include/api/types.hpp | 80 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) diff --git a/include/api/_Api.hpp b/include/api/_Api.hpp index 1afed55..9a23bc1 100644 --- a/include/api/_Api.hpp +++ b/include/api/_Api.hpp @@ -59,6 +59,57 @@ namespace kdeck } API_CALL("GET", "{basePath}/exchange/status", GetExchangeStatus, PATH(String, basePath)) + // market /////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////// + + API_CALL_HEADERS(GetEvents) + { + headers.put("Accept", "application/json"); + } + API_CALL("GET", "{basePath}/events", GetEvents, PATH(String, basePath), QUERY(Object, eventsRequest)) + + API_CALL_HEADERS(GetEvent) + { + headers.put("Accept", "application/json"); + } + API_CALL("GET", "{basePath}/events/{event_ticker}", GetEvent, PATH(String, basePath), PATH(String, event_ticker), QUERY(Object, eventRequest)) + + API_CALL_HEADERS(GetMarkets) + { + headers.put("Accept", "application/json"); + } + API_CALL("GET", "{basePath}/markets", GetMarkets, PATH(String, basePath), AUTHORIZATION(String, authString, "Bearer"), QUERY(Object, marketsRequest)) + + API_CALL_HEADERS(GetTrades) + { + headers.put("Accept", "application/json"); + } + API_CALL("GET", "{basePath}/markets/trades", GetTrades, PATH(String, basePath), QUERY(Object, tradesRequest)) + + API_CALL_HEADERS(GetMarket) + { + headers.put("Accept", "application/json"); + } + API_CALL("GET", "{basePath}/markets/{ticker}", GetMarket, PATH(String, basePath), PATH(String, ticker)) + + API_CALL_HEADERS(GetMarketOrderbook) + { + headers.put("Accept", "application/json"); + } + API_CALL("GET", "{basePath}/markets/{ticker}/orderbook", GetMarketOrderbook, PATH(String, basePath), AUTHORIZATION(String, authString, "Bearer"), QUERY(String, ticker), QUERY(Object, marketOrderbookRequest)) + + API_CALL_HEADERS(GetSeries) + { + headers.put("Accept", "application/json"); + } + API_CALL("GET", "{basePath}/series/{series_ticker}", GetSeries, PATH(String, basePath), PATH(String, series_ticker)) + + API_CALL_HEADERS(GetMarketCandlesticks) + { + headers.put("Accept", "application/json"); + } + API_CALL("GET", "{basePath}/series/{series_ticker}/markets/{ticker}/candlesticks", GetMarketCandlesticks, PATH(String, basePath), AUTHORIZATION(String, authString, "Bearer"), PATH(String, series_ticker), PATH(String, ticker), QUERY(Object, marketCandlesticksRequest)) + // portfolio //////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// diff --git a/include/api/types.hpp b/include/api/types.hpp index 89d6276..14326aa 100644 --- a/include/api/types.hpp +++ b/include/api/types.hpp @@ -165,6 +165,86 @@ namespace kdeck }; + // markets ////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////// + + struct EventsRequest + : public oatpp::DTO + { + + DTO_INIT(EventsRequest, DTO /* extends */) + + DTO_FIELD(String, cursor); + DTO_FIELD(Int32, limit); + DTO_FIELD(String, status); + DTO_FIELD(String, series_ticker); + DTO_FIELD(Boolean, with_nested_markets); + + }; + + struct EventRequest + : public oatpp::DTO + { + + DTO_INIT(EventRequest, DTO /* extends */) + + DTO_FIELD(Boolean, with_nested_markets); + + }; + + struct MarketsRequest + : public oatpp::DTO + { + + DTO_INIT(MarketsRequest, DTO /* extends */) + + DTO_FIELD(String, cursor); + DTO_FIELD(Int32, limit); + DTO_FIELD(String, event_ticker); + DTO_FIELD(String, series_ticker); + DTO_FIELD(Int64, max_close_ts); + DTO_FIELD(Int64, min_close_ts); + DTO_FIELD(String, status); + DTO_FIELD(String, tickers); + + }; + + struct TradesRequest + : public oatpp::DTO + { + + DTO_INIT(TradesRequest, DTO /* extends */) + + DTO_FIELD(String, cursor); + DTO_FIELD(Int32, limit); + DTO_FIELD(String, ticker); + DTO_FIELD(Int64, min_ts); + DTO_FIELD(Int64, max_ts); + + }; + + struct MarketOrderbookRequest + : public oatpp::DTO + { + + DTO_INIT(MarketOrderbookRequest, DTO /* extends */) + + DTO_FIELD(Int32, depth); + + }; + + struct MarketCandlesticksRequest + : public oatpp::DTO + { + + DTO_INIT(MarketCandlesticksRequest, DTO /* extends */) + + DTO_FIELD(Int64, start_ts); + DTO_FIELD(Int64, end_ts); + DTO_FIELD(Int32, period_interval); + + }; + // portfolio //////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// From 88fe97f441886451127267ad356cabf22fbf0e7c Mon Sep 17 00:00:00 2001 From: Mark Ross <6730333+krazkidd@users.noreply.github.com> Date: Sun, 14 Jul 2024 18:55:09 -0700 Subject: [PATCH 2/3] Add market API wrapper methods and response types. --- include/api/Api.hpp | 10 ++ include/api/types.hpp | 267 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 277 insertions(+) diff --git a/include/api/Api.hpp b/include/api/Api.hpp index 74c27a6..280f14f 100644 --- a/include/api/Api.hpp +++ b/include/api/Api.hpp @@ -31,6 +31,16 @@ namespace kdeck std::shared_ptr GetExchangeSchedule(); std::shared_ptr GetExchangeStatus(); + // market + std::shared_ptr GetEvents(); + std::shared_ptr GetEvent(); + std::shared_ptr GetMarkets(); + std::shared_ptr GetTrades(); + std::shared_ptr GetMarket(); + std::shared_ptr GetMarketOrderbook(); + std::shared_ptr GetSeries(); + std::shared_ptr GetMarketCandlesticks(); + // portfolio double GetBalance(); std::shared_ptr GetPositions(); diff --git a/include/api/types.hpp b/include/api/types.hpp index 14326aa..acb338f 100644 --- a/include/api/types.hpp +++ b/include/api/types.hpp @@ -182,6 +182,98 @@ namespace kdeck }; + struct Market + : public oatpp::DTO + { + + DTO_INIT(Market, DTO /* extends */) + + DTO_FIELD(Boolean, can_close_early); + DTO_FIELD(Float64, cap_strike); + DTO_FIELD(String, category); + DTO_FIELD(DateTime_Iso8601, close_time); + //TODO filled only if "strike_type" is "custom" + //DTO_FIELD(TODO, custom_strike); + DTO_FIELD(String, event_ticker); + DTO_FIELD(DateTime_Iso8601, expected_expiration_time); + DTO_FIELD(DateTime_Iso8601, expiration_time); + DTO_FIELD(String, expiration_value); + DTO_FIELD(DateTime_Iso8601, fee_waiver_expiration_time); + DTO_FIELD(Float64, floor_strike); + DTO_FIELD(String, functional_strike); + DTO_FIELD(Int64, last_price); + DTO_FIELD(DateTime_Iso8601, latest_expiration_time); + DTO_FIELD(Int64, liquidity); + DTO_FIELD(String, market_type); + DTO_FIELD(Int64, no_ask); + DTO_FIELD(Int64, no_bid); + DTO_FIELD(String, no_sub_title); + DTO_FIELD(Int64, notional_value); + DTO_FIELD(Int64, open_interest); + DTO_FIELD(DateTime_Iso8601, open_time); + DTO_FIELD(Int64, previous_price); + DTO_FIELD(Int64, previous_yes_ask); + DTO_FIELD(Int64, previous_yes_bid); + DTO_FIELD(String, response_price_units); + DTO_FIELD(String, result); + DTO_FIELD(Int64, risk_limit_cents); + DTO_FIELD(String, rules_primary); + DTO_FIELD(String, rules_secondary); + DTO_FIELD(Int32, settlement_timer_seconds); + DTO_FIELD(Int64, settlement_value); + DTO_FIELD(String, status); + DTO_FIELD(String, strike_type); + //DTO_FIELD(String, subtitle); // DEPRECATED + DTO_FIELD(Int64, tick_size); + DTO_FIELD(String, ticker); + DTO_FIELD(String, title); + DTO_FIELD(Int64, volume); + DTO_FIELD(Int64, volume_24h); + DTO_FIELD(Int64, yes_ask); + DTO_FIELD(Int64, yes_bid); + DTO_FIELD(String, yes_sub_title); + + }; + + struct Event + : public oatpp::DTO + { + + DTO_INIT(Event, DTO /* extends */) + + //DTO_FIELD(String, category); // DEPRECATED + DTO_FIELD(String, event_ticker); + DTO_FIELD(List>, markets); + DTO_FIELD(Boolean, mutually_exclusive); + DTO_FIELD(String, series_ticker); + DTO_FIELD(DateTime_Iso8601, strike_date); + DTO_FIELD(String, strike_period); + DTO_FIELD(String, sub_title); + DTO_FIELD(String, title); + + }; + + struct EventsResponse + : public oatpp::DTO + { + + DTO_INIT(EventsResponse, DTO /* extends */) + + DTO_FIELD(String, cursor); + DTO_FIELD(List>, events); + + }; + + struct EventResponse + : public oatpp::DTO + { + + DTO_INIT(EventResponse, DTO /* extends */) + + DTO_FIELD(Object, event); + + }; + struct EventRequest : public oatpp::DTO { @@ -192,6 +284,17 @@ namespace kdeck }; + struct MarketsResponse + : public oatpp::DTO + { + + DTO_INIT(MarketsResponse, DTO /* extends */) + + DTO_FIELD(String, cursor); + DTO_FIELD(List>, markets); + + }; + struct MarketsRequest : public oatpp::DTO { @@ -209,6 +312,33 @@ namespace kdeck }; + struct Trade + : public oatpp::DTO + { + + DTO_INIT(Trade, DTO /* extends */) + + DTO_FIELD(Int32, count); + DTO_FIELD(DateTime_Iso8601, created_time); + DTO_FIELD(Int64, no_price); + DTO_FIELD(String, taker_side); + DTO_FIELD(String, ticker); + DTO_FIELD(String, trade_id); + DTO_FIELD(Int64, yes_price); + + }; + + struct TradesResponse + : public oatpp::DTO + { + + DTO_INIT(TradesResponse, DTO /* extends */) + + DTO_FIELD(String, cursor); + DTO_FIELD(List>, trades); + + }; + struct TradesRequest : public oatpp::DTO { @@ -223,6 +353,37 @@ namespace kdeck }; + struct MarketResponse + : public oatpp::DTO + { + + DTO_INIT(MarketResponse, DTO /* extends */) + + DTO_FIELD(Object, market); + + }; + + struct MarketOrderbook + : public oatpp::DTO + { + + DTO_INIT(MarketOrderbook, DTO /* extends */) + + DTO_FIELD(List, no); + DTO_FIELD(List, yes); + + }; + + struct MarketOrderbookResponse + : public oatpp::DTO + { + + DTO_INIT(MarketOrderbookResponse, DTO /* extends */) + + DTO_FIELD(Object, orderbook); + + }; + struct MarketOrderbookRequest : public oatpp::DTO { @@ -233,6 +394,112 @@ namespace kdeck }; + struct SettlementSource + : public oatpp::DTO + { + + DTO_INIT(SettlementSource, DTO /* extends */) + + DTO_FIELD(String, name); + DTO_FIELD(String, url); + + }; + + struct Series + : public oatpp::DTO + { + + DTO_INIT(Series, DTO /* extends */) + + DTO_FIELD(String, category); + DTO_FIELD(String, contract_url); + DTO_FIELD(String, frequency); + DTO_FIELD(List>, settlement_sources); + DTO_FIELD(List, tags); + DTO_FIELD(String, ticker); + DTO_FIELD(String, title); + + }; + + struct SeriesResponse + : public oatpp::DTO + { + + DTO_INIT(SeriesResponse, DTO /* extends */) + + DTO_FIELD(Int32, series); + + }; + + struct Price + : public oatpp::DTO + { + + DTO_INIT(Price, DTO /* extends */) + + DTO_FIELD(Int64, close); + DTO_FIELD(Int64, high); + DTO_FIELD(Int64, low); + DTO_FIELD(Int64, mean); + DTO_FIELD(Int64, open); + DTO_FIELD(Int64, previous); + + }; + + struct YesAsk + : public oatpp::DTO + { + + DTO_INIT(YesAsk, DTO /* extends */) + + DTO_FIELD(Int64, close); + DTO_FIELD(Int64, high); + DTO_FIELD(Int64, low); + DTO_FIELD(Int64, open); + + }; + + struct YesBid + : public oatpp::DTO + { + + DTO_INIT(YesBid, DTO /* extends */) + + DTO_FIELD(Int64, close); + DTO_FIELD(Int64, high); + DTO_FIELD(Int64, low); + DTO_FIELD(Int64, open); + + }; + + struct MarketCandlestick + : public oatpp::DTO + { + + DTO_INIT(MarketCandlestick, DTO /* extends */) + + DTO_FIELD(Int64, end_period_ts); + DTO_FIELD(Int64, open_interest); + DTO_FIELD(Object, price); + DTO_FIELD(Int64, volume); + DTO_FIELD(Object, yes_ask); + DTO_FIELD(Object, yes_bid); + DTO_FIELD(String, ticker); + + }; + + struct MarketCandlesticksResponse + : public oatpp::DTO + { + + DTO_INIT(MarketCandlesticksResponse, DTO /* extends */) + + DTO_FIELD(Int64, start_ts); + DTO_FIELD(Int64, end_ts); + DTO_FIELD(Int32, period_interval); + + }; + struct MarketCandlesticksRequest : public oatpp::DTO { From b2563e8d9627d4a85374a6595f00effe162c74c3 Mon Sep 17 00:00:00 2001 From: Mark Ross <6730333+krazkidd@users.noreply.github.com> Date: Mon, 15 Jul 2024 22:35:30 -0700 Subject: [PATCH 3/3] Implement market API wrapper methods. This is a partial implementation. --- include/api/Api.hpp | 14 ++-- src/api/Api.market.cpp | 178 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+), 5 deletions(-) create mode 100644 src/api/Api.market.cpp diff --git a/include/api/Api.hpp b/include/api/Api.hpp index 280f14f..3b5b941 100644 --- a/include/api/Api.hpp +++ b/include/api/Api.hpp @@ -33,13 +33,13 @@ namespace kdeck // market std::shared_ptr GetEvents(); - std::shared_ptr GetEvent(); + std::shared_ptr GetEvent(std::string_view eventTicker); std::shared_ptr GetMarkets(); std::shared_ptr GetTrades(); - std::shared_ptr GetMarket(); - std::shared_ptr GetMarketOrderbook(); - std::shared_ptr GetSeries(); - std::shared_ptr GetMarketCandlesticks(); + std::shared_ptr GetMarket(std::string_view marketTicker); + std::shared_ptr GetMarketOrderbook(std::string_view marketTicker); + std::shared_ptr GetSeries(std::string_view seriesTicker); + std::shared_ptr GetMarketCandlesticks(std::string_view seriesTicker, std::string_view marketTicker); // portfolio double GetBalance(); @@ -64,6 +64,10 @@ namespace kdeck std::shared_ptr schedule; std::shared_ptr status; + // market + std::shared_ptr events; + std::shared_ptr markets; + // portfolio std::shared_ptr balance; std::shared_ptr positions; diff --git a/src/api/Api.market.cpp b/src/api/Api.market.cpp new file mode 100644 index 0000000..e6220e1 --- /dev/null +++ b/src/api/Api.market.cpp @@ -0,0 +1,178 @@ +#include + +#include "api/Api.hpp" + +namespace kdeck +{ + class ErrorResponse; + + class EventsResponse; + class EventResponse; + class MarketsResponse; + class TradesResponse; + class MarketOrderbookResponse; + class SeriesResponse; + class MarketCandlesticksResponse; + + std::shared_ptr Api::GetEvents() + { + OATPP_LOGD("Api", "GetEvents"); + + auto req = EventsRequest::createShared(); + + ApiResult res = HandleResponse(_api->GetEvents(basePath, req)); + + if (std::holds_alternative>(res)) + { + events = std::get>(res); + } + else + { + throw std::runtime_error(std::get>(res)->error->message->c_str()); + } + + return events; + } + + std::shared_ptr Api::GetEvent(std::string_view eventTicker) + { + OATPP_LOGD("Api", "GetEvent"); + + auto req = EventRequest::createShared(); + + ApiResult res = HandleResponse(_api->GetEvent(basePath, std::string{eventTicker}, req)); + + if (std::holds_alternative>(res)) + { + //TODO populate events + return std::get>(res); + } + else + { + throw std::runtime_error(std::get>(res)->error->message->c_str()); + } + + //TODO return events[eventTicker]; + } + + std::shared_ptr Api::GetMarkets() + { + OATPP_LOGD("Api", "GetMarkets"); + + auto req = MarketsRequest::createShared(); + + ApiResult res = HandleResponse(_api->GetMarkets(basePath, login->token, req)); + + if (std::holds_alternative>(res)) + { + markets = std::get>(res); + } + else + { + throw std::runtime_error(std::get>(res)->error->message->c_str()); + } + + return markets; + } + + std::shared_ptr Api::GetTrades() + { + OATPP_LOGD("Api", "GetTrades"); + + auto req = TradesRequest::createShared(); + + ApiResult res = HandleResponse(_api->GetTrades(basePath, req)); + + if (std::holds_alternative>(res)) + { + //TODO populate trades + return std::get>(res); + } + else + { + throw std::runtime_error(std::get>(res)->error->message->c_str()); + } + + //TODO return trades; + } + + std::shared_ptr Api::GetMarket(std::string_view marketTicker) + { + OATPP_LOGD("Api", "GetMarket"); + + ApiResult res = HandleResponse(_api->GetMarket(basePath, std::string{marketTicker})); + + if (std::holds_alternative>(res)) + { + //TODO populate markets + return std::get>(res); + } + else + { + throw std::runtime_error(std::get>(res)->error->message->c_str()); + } + + //TODO return markets[marketTicker]; + } + + std::shared_ptr Api::GetMarketOrderbook(std::string_view marketTicker) + { + OATPP_LOGD("Api", "GetMarketOrderbook"); + + auto req = MarketOrderbookRequest::createShared(); + + ApiResult res = HandleResponse(_api->GetMarketOrderbook(basePath, login->token, std::string{marketTicker}, req)); + + if (std::holds_alternative>(res)) + { + //TODO populate orderbooks + return std::get>(res); + } + else + { + throw std::runtime_error(std::get>(res)->error->message->c_str()); + } + + //TODO return orderbooks[marketTicker]; + } + + std::shared_ptr Api::GetSeries(std::string_view seriesTicker) + { + OATPP_LOGD("Api", "GetSeries"); + + ApiResult res = HandleResponse(_api->GetSeries(basePath, std::string{seriesTicker})); + + if (std::holds_alternative>(res)) + { + //TODO populate series + return std::get>(res); + } + else + { + throw std::runtime_error(std::get>(res)->error->message->c_str()); + } + + //TODO return series[seriesTicker]; + } + + std::shared_ptr Api::GetMarketCandlesticks(std::string_view seriesTicker, std::string_view marketTicker) + { + OATPP_LOGD("Api", "GetMarketCandlesticks"); + + auto req = MarketCandlesticksRequest::createShared(); + + ApiResult res = HandleResponse(_api->GetMarketCandlesticks(basePath, login->token, std::string{seriesTicker}, std::string{marketTicker}, req)); + + if (std::holds_alternative>(res)) + { + //TODO populate candlesticks + return std::get>(res); + } + else + { + throw std::runtime_error(std::get>(res)->error->message->c_str()); + } + + //return candlesticks[seriesTicker][marketTicker]; + } +}