1#include <algotradelib/tossinvest>
3#include <boost/asio/ssl/context.hpp>
14namespace ssl = boost::asio::ssl;
18void print_error(std::string_view operation,
const algotradelib::BrokerError& error) {
19 std::cerr << operation <<
" failed";
35std::string mask_account_number(std::string_view account_number) {
36 if (account_number.size() <= 4) {
37 return std::string(account_number.size(),
'*');
39 return std::string(account_number.size() - 4,
'*') +
40 std::string(account_number.substr(account_number.size() - 4));
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';
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';
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");
76int main(
int argc,
char* argv[]) {
81 ssl::context tls(ssl::context::tls_client);
82 tls.set_default_verify_paths();
83 tls.set_verify_mode(ssl::verify_peer);
86 auto accounts_result = client.accounts();
87 if (!accounts_result) {
88 print_error(
"account discovery", accounts_result.error());
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';
98 if (accounts.empty()) {
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(
108 return account.sequence_ == selected_sequence;
111 if (selected == accounts.end()) {
112 throw std::invalid_argument(
"selected account sequence was not returned by discovery");
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());
122 print_holdings(holdings_result.value());
124 }
catch (
const std::exception& exception) {
125 std::cerr <<
"example failed: " << exception.what() <<
'\n';
void from_env()
Loads the credentials from the broker's environment variables.
Blocking facade that drives TossClient on a private event loop.
std::string request_id_
The broker's request id for this call, if it gave one.
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....
std::string message_
A human-readable description, for logs; do not parse it.
std::string broker_code_
The broker's own error code, verbatim (for example KIS's EGW00201).
std::vector< HoldingsTotals > totals_
One totals row per currency held.
std::vector< HoldingPosition > positions_
Every position row; one instrument may appear in more than one.
A Toss account, as account discovery (async_accounts) returns it.
Toss Securities credentials (client id and secret). Toss has no demo environment.