algotradelib 0.0.0.9000
C++ header-only library for algorithmic trading
Loading...
Searching...
No Matches
example-tossinvest-account.cpp
1#include <algotradelib/tossinvest>
2
3#include <boost/asio/ssl/context.hpp>
4
5#include <algorithm>
6#include <cstdint>
7#include <exception>
8#include <iostream>
9#include <stdexcept>
10#include <string>
11#include <string_view>
12#include <utility>
13
14namespace ssl = boost::asio::ssl;
15
16namespace {
17
18void print_error(std::string_view operation, const algotradelib::BrokerError& error) {
19 std::cerr << operation << " failed";
20 if (!error.broker_code_.empty()) {
21 std::cerr << " [" << error.broker_code_ << ']';
22 }
23 if (!error.request_id_.empty()) {
24 std::cerr << " request=" << error.request_id_;
25 }
26 if (error.http_status_ != 0) {
27 std::cerr << " HTTP " << error.http_status_;
28 }
29 if (!error.message_.empty()) {
30 std::cerr << ": " << error.message_;
31 }
32 std::cerr << '\n';
33}
34
35std::string mask_account_number(std::string_view account_number) {
36 if (account_number.size() <= 4) {
37 return std::string(account_number.size(), '*');
38 }
39 return std::string(account_number.size() - 4, '*') +
40 std::string(account_number.substr(account_number.size() - 4));
41}
42
43void print_holdings(const algotradelib::HoldingsSnapshot& snapshot) {
44 std::cout << "positions: " << snapshot.positions_.size() << '\n';
45 for (const auto& position : snapshot.positions_) {
46 std::cout << position.instrument_.symbol_ << " " << position.name_ << '\n';
47 std::cout << " quantity: " << position.quantity_.str() << '\n';
48 std::cout << " last price: " << position.last_price_.str() << ' '
49 << position.market_value_.currency_.str() << '\n';
50 std::cout << " market value: " << position.market_value_.amount_.str() << ' '
51 << position.market_value_.currency_.str() << '\n';
52 std::cout << " unrealized P/L: " << position.unrealized_profit_loss_.amount_.str() << ' '
53 << position.unrealized_profit_loss_.currency_.str() << '\n';
54 }
55
56 std::cout << "totals: " << snapshot.totals_.size() << '\n';
57 for (const auto& total : snapshot.totals_) {
58 std::cout << total.currency_.str() << " purchase=" << total.purchase_value_.str()
59 << " market=" << total.market_value_.str()
60 << " unrealized=" << total.unrealized_profit_loss_.str() << '\n';
61 }
62}
63
64std::int64_t parse_account_sequence(const char* value) {
65 const std::string text(value);
66 std::size_t parsed = 0;
67 const auto sequence = std::stoll(text, &parsed);
68 if (parsed != text.size() || sequence <= 0) {
69 throw std::invalid_argument("account sequence must be a positive integer");
70 }
71 return sequence;
72}
73
74} // namespace
75
76int main(int argc, char* argv[]) {
77 try {
79 config.from_env();
80
81 ssl::context tls(ssl::context::tls_client);
82 tls.set_default_verify_paths();
83 tls.set_verify_mode(ssl::verify_peer);
84
85 algotradelib::tossinvest::TossBlockingClient client(tls, std::move(config));
86 auto accounts_result = client.accounts();
87 if (!accounts_result) {
88 print_error("account discovery", accounts_result.error());
89 return 1;
90 }
91
92 const auto& accounts = accounts_result.value();
93 std::cout << "accounts: " << accounts.size() << '\n';
94 for (const auto& account : accounts) {
95 std::cout << account.sequence_ << " " << mask_account_number(account.account_number_)
96 << " " << account.account_type_ << '\n';
97 }
98 if (accounts.empty()) {
99 return 0;
100 }
101
102 const std::int64_t selected_sequence =
103 argc > 1 ? parse_account_sequence(argv[1]) : accounts.front().sequence_;
104 const auto selected = std::find_if(
105 accounts.begin(),
106 accounts.end(),
107 [selected_sequence](const algotradelib::tossinvest::TossAccount& account) {
108 return account.sequence_ == selected_sequence;
109 }
110 );
111 if (selected == accounts.end()) {
112 throw std::invalid_argument("selected account sequence was not returned by discovery");
113 }
114
115 std::cout << "selected account: " << selected_sequence << '\n';
116 auto holdings_result = client.holdings(selected_sequence);
117 if (!holdings_result) {
118 print_error("holdings request", holdings_result.error());
119 return 1;
120 }
121
122 print_holdings(holdings_result.value());
123 return 0;
124 } catch (const std::exception& exception) {
125 std::cerr << "example failed: " << exception.what() << '\n';
126 return 1;
127 }
128}
void from_env()
Loads the credentials from the broker's environment variables.
Definition oauth.hpp:46
Blocking facade that drives TossClient on a private event loop.
Definition client.hpp:3994
std::string request_id_
The broker's request id for this call, if it gave one.
Definition types.hpp:763
int http_status_
The HTTP status of the reply: set for an HTTP error and for a reply whose body is not a JSON object....
Definition types.hpp:759
std::string message_
A human-readable description, for logs; do not parse it.
Definition types.hpp:772
std::string broker_code_
The broker's own error code, verbatim (for example KIS's EGW00201).
Definition types.hpp:761
std::vector< HoldingsTotals > totals_
One totals row per currency held.
Definition types.hpp:1079
std::vector< HoldingPosition > positions_
Every position row; one instrument may appear in more than one.
Definition types.hpp:1077
A Toss account, as account discovery (async_accounts) returns it.
Definition client.hpp:29
Toss Securities credentials (client id and secret). Toss has no demo environment.
Definition config.hpp:24