algotradelib 0.0.0.9000
C++ header-only library for algorithmic trading
Loading...
Searching...
No Matches
example-kiwoom-account.cpp
1// Shows which account a Kiwoom credential drives, what it holds, and what it may spend.
2//
3// Kiwoom takes no account number on any request -- the application key *is* the account -- so
4// `ka00001` is the only way to check the credential points where you meant. The session binds an
5// empty selector for the same reason.
6
8
9#include <algotradelib/kiwoom>
10
11#include <boost/asio/ssl/context.hpp>
12
13#include <exception>
14#include <memory>
15#include <iostream>
16#include <string>
17#include <string_view>
18#include <utility>
19
20namespace net = boost::asio;
21namespace ssl = net::ssl;
22
23namespace {
24
26std::string mask_account_number(std::string_view account_number) {
27 if (account_number.size() <= 4) {
28 return std::string(account_number.size(), '*');
29 }
30 return std::string(account_number.size() - 4, '*') +
31 std::string(account_number.substr(account_number.size() - 4));
32}
33
34} // namespace
35
36int main(int argc, char** argv) {
40
41 try {
42 // `--credentials DIR [--kiwoom-account LABEL]`, else the environment (kiwoom_credentials.hpp).
43 const auto directory = kis_credentials::take_directory(argc, argv);
44 const auto label = kiwoom_credentials::take_label(argc, argv);
47 kiwoom_credentials::load(directory, label, config, std::cout);
48 // Kiwoom's balance inquiry names one venue and publishes no combined value, and whether that
49 // selects which positions are listed or only how they are valued is not stated anywhere. So
50 // there is no default and a caller states the venue deliberately.
51 config.holdings_venue_ = algotradelib::Venue::KRX;
52 // And what naming it *means* is a separate statement, which this example does not make: with
53 // both scopes left unstated the normalized holdings verb refuses and so does anything that can
54 // open a position, which is what an example should demonstrate rather than assume away. A real
55 // program asserts them once it has measured what its account returns -- and an assertion is not
56 // a measurement.
57
58 ssl::context tls(ssl::context::tls_client);
59 tls.set_default_verify_paths();
60 tls.set_verify_mode(ssl::verify_peer);
61
62 BlockingSession<KiwoomBlockingClient> session(
63 std::make_shared<KiwoomBlockingClient>(tls, std::move(config), kiwoom_credentials::paced_options()),
65 );
66
67 static_assert(
68 BrokerCaps<KiwoomBlockingClient>::has_account_discovery,
69 "Kiwoom publishes the account its credential drives"
70 );
71 const auto accounts = session.accounts();
72 if (!accounts) {
73 std::cerr << "account listing failed: " << accounts.error().message_ << '\n';
74 return 1;
75 }
76 for (const auto& account : accounts.value()) {
77 std::cout << "account: " << mask_account_number(account.display_number_) << '\n';
78 }
79
80 // **The normalized `session.holdings()` verb refuses while the scope is unstated**, because
81 // kt00018 names one venue and nothing says whether that filters the positions or only values
82 // them -- so this library will not present one venue's answer as the account's holdings unless
83 // a caller says that is what it is. The broker-specific inquiry below answers for the
84 // configured venue regardless, and running it for KRX and again for NXT is the **diagnostic**
85 // the question needs.
86 //
87 // It is not by itself a proof, and that is worth knowing before reading the output: two reads
88 // are not a snapshot, so rows that differ may record a fill between them rather than a filtered
89 // listing, and an empty account makes both answers identical. Run it on a quiet account and
90 // read it as evidence, not as an answer.
91 const auto holdings = session.client().holdings(algotradelib::kiwoom::KiwoomAccount{});
92 if (!holdings) {
93 std::cerr << "holdings failed: " << holdings.error().message_ << '\n';
94 return 1;
95 }
96 std::cout << "holdings as Kiwoom reported them for one venue:\n";
97 for (const auto& position : holdings.value().positions_) {
98 std::cout << position.instrument_.symbol_ << ' ' << position.name_ << ' '
99 << position.quantity_.str();
100 if (position.sellable_quantity_) {
101 std::cout << " (sellable " << position.sellable_quantity_->str() << ')';
102 }
103 std::cout << '\n';
104 }
105
106 const auto budget = session.buying_power(algotradelib::Currency::krw());
107 if (!budget) {
108 std::cerr << "buying power failed: " << budget.error().message_ << '\n';
109 return 1;
110 }
111 // The credit-free figure. Kiwoom's 주문가능금액 is larger and includes what margin and 대용금
112 // allow, which is why it is not what this reports; read it from `client().deposit()`.
113 std::cout << "spendable: " << budget.value().cash_.amount_.str() << ' '
114 << budget.value().cash_.currency_.str() << '\n';
115 return 0;
116 } catch (const std::exception& exception) {
117 std::cerr << "example failed: " << exception.what() << '\n';
118 return 1;
119 }
120}
A blocking broker client bound to one account, with the same broker operations as BrokerSession,...
static Currency krw()
Returns Korean won.
Definition types.hpp:262
A blocking Kiwoom client: each call runs a KiwoomClient request on a private event loop and returns i...
Definition client.hpp:3795
std::optional< std::filesystem::path > take_directory(int &argc, char **argv)
Removes --credentials DIR from the command line and returns the directory, else ATL_CREDENTIALS_DIR.
The examples' Kiwoom credentials: one JSON file per key, or the environment.
void refuse_unknown_flags(int argc, char **argv)
Refuses any flag left on the command line after the credential flags were taken, so a mistyped --kiwo...
algotradelib::network::HttpClientOptions paced_options()
Returns transport options that pace a Kiwoom client at one request a second.
std::optional< std::string > take_label(int &argc, char **argv)
Removes --kiwoom-account LABEL from the command line and returns the label.
void load(const std::optional< std::filesystem::path > &directory, const std::optional< std::string > &label, algotradelib::kiwoom::KiwoomConfig &config, std::ostream &out)
Loads the credentials from DIR/kiwoom/{demo,real}-LABEL.json (as KIWOOM_DEMO chooses; label kr by def...
What one broker client implements, as compile-time constants.
The Kiwoom account selector, which is empty: no Kiwoom endpoint takes an account number,...
Definition client.hpp:35
Kiwoom credentials (app key and secret key), demo or real account, the market-data tape,...
Definition config.hpp:154
Venue holdings_venue_
The venue holdings requests (kt00018) name: Venue::KRX or Venue::NXT. No default: holdings requests a...
Definition config.hpp:182