Skip to content

Commit abe7ccc

Browse files
author
JiaWen Li
committed
Merge branch 'dev' into 'master'
fix limit_price; secret_key support See merge request server/openapi/openapi-cpp-sdk!8
2 parents 32df22c + 827683c commit abe7ccc

File tree

14 files changed

+236
-24
lines changed

14 files changed

+236
-24
lines changed

changlog.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
## 0.1.6 (2024-03-08)
2+
### New
3+
- 新增根据ticksize调整下单价格的工具 PriceUtil
4+
5+
6+
## 0.1.5 (2024-02-04)
7+
### Modify
8+
- 交易接口支持 `secret_key`
9+
10+
111
## 0.1.0 (2023-02-15)
212
### New
3-
- Beta版本,支持交易、行情接口
13+
- Beta版本,支持交易、行情接口
14+

demo/openapi_cpp_test/openapi_cpp_test.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "tigerapi/order_util.h"
88
#include "tigerapi/utils.h"
99
#include "cpprest/details/basic_types.h"
10+
#include "tigerapi/price_util.h"
1011

1112
using namespace std;
1213
using namespace web;
@@ -104,11 +105,12 @@ class TestTradeClient {
104105
}
105106

106107
static void test_place_option_order(const std::shared_ptr<TradeClient>& trade_client) {
107-
Contract contract = ContractUtil::option_contract(U("AAPL"), U("20230721"), U("185.0"), U("CALL"), U("USD"));
108+
Contract contract = ContractUtil::option_contract(U("TQQQ"), U("20230915"), U("43.0"), U("CALL"), U("USD"));
108109
//Contract contract = ContractUtil::option_contract(U("AAPL"), U("20230721"), U("185.0"), U("PUT"), U("USD"));
109110
//Contract contract = ContractUtil::option_contract(U("AAPL 230721C00185000"));
110111
//Contract contract = ContractUtil::option_contract(U("AAPL 230721P00185000"));
111-
Order order = OrderUtil::limit_order(contract, U("BUY"), 1, 1.5);
112+
Order order = OrderUtil::limit_order(contract, U("BUY"), 3, U("0.18"));
113+
// order.adjust_limit = 0.01;
112114
value res = trade_client->place_order(order);
113115
//unsigned long long id = res[U("id")].as_number().to_uint64();
114116
ucout << U("order id: ") << order.id << endl;
@@ -166,10 +168,17 @@ class TestTradeClient {
166168
ucout << U("place forex order: ") << res << endl;
167169
}
168170

171+
static void test_price_util(const std::shared_ptr<TradeClient>& trade_client) {
172+
value contract = trade_client->get_contract(U("AAPL"));
173+
value tick_sizes = contract.at( U("tickSizes") );
174+
double res = PriceUtil::fix_price_by_tick_size(1.111, tick_sizes);
175+
ucout << U("fix price by tick size: ") << res << endl;
176+
}
169177

170178
static void test_trade(const std::shared_ptr<TradeClient>& trade_client) {
171-
TestTradeClient::test_get_contract(trade_client);
179+
TestTradeClient::test_price_util(trade_client);
172180
}
181+
173182
};
174183

175184

@@ -191,7 +200,7 @@ class TestQuoteClient {
191200

192201
static void test_get_symbols_names(const std::shared_ptr<QuoteClient> quote_client) {
193202
// value result = quote_client->get_all_symbol_names(U("HK"));
194-
value result = quote_client->get_all_symbol_names(Market::HK);
203+
value result = quote_client->get_all_symbol_names(Market::HK, false);
195204
ucout << U("result: ") << result << endl;
196205
}
197206

@@ -227,7 +236,8 @@ class TestQuoteClient {
227236
value symbols = value::array();
228237
symbols[0] = value::string(U("AAPL"));
229238
symbols[1] = value::string(U("JD"));
230-
auto result = quote_client->get_quote_real_time(symbols);
239+
auto result = quote_client->get_quote_real_time_value(symbols);
240+
vector<RealtimeQuote> result1 = quote_client->get_quote_real_time(symbols);
231241
ucout << U("result: ") << result.at(0).to_string() << endl;
232242
}
233243

@@ -428,10 +438,11 @@ class TestTigerApi {
428438
int main()
429439
{
430440
/************************** set config **********************/
431-
ClientConfig config = ClientConfig(true);
432-
config.private_key = U("MIICXQIBAAKBgQC1amZa5YsGTklry7DAsUBOwXJCgrsZZtB21PImw/yLmrbqRfsS3vawvMigLWcCwIDnHa+hpdpeze0eHIwbZzJzUDGvRALYK9t3D8pwPVxpwX1OF8RfHCM7YQvSOvPPnHHuVQvKaR7NNm1/WmvGXC9kVJdkYQ7kCmh52siFoy1MLQIDAQABAoGAVabcmIHTt7ByncBXvUJymDxhE+HhMEcImXJEueTCca8kOUu9FNXMJvmax3VoMzZsJbIwX+OMTEJxd0wHIlEA0gECjDwFK4Q42q+ptO4QABJQVSC6I+dOt2OIY28uvT3rkenOO8KRIDt4F52PFd71ZdB1aaXixORORq1MdSLi8EkCQQDiviAB+L5R/HVxwxvqZfJ530OtFd5IipZC9YZlY1CtXWCmu89LK7UUlEuNXyGsOxyz5jLqFuNRsie5AC23tfEPAkEAzNMCa8axJWfPZIH4tGrbZ1F3I41BQdgp2zBmR7AyUMBDkli86OzmJ7QUCJA/PJxK43/IYUWm4OU5Q+SvXCr3AwJBAJTBj1Y7zwES1CpSitn5EF+MbmX71t1YrsQ3OHkD80YJ4QMCbDkw75gUwox5QSoxjd8ow3Z4laJfc1gYGeZQ41kCQQCCiQwm8cceBq3W6To+iUdw7itWngRz2Ta7uXnFwFYgvpeR4jnq3GfF7+9AkeWrVBQqLtrem0xCUfQP/+N+gudPAkBFLbt78/MpQGEDc7jyu/KE5Mp4wMMDQQwch9VLvsAZwWLysB6rZWpo3jIfp9zZ7c3zOYGNMWAZjtMmNkRJ8COH");
433-
config.tiger_id = U("1");
434-
config.account = U("402901");
441+
ClientConfig config = ClientConfig();
442+
config.private_key = U("");
443+
config.tiger_id = U("");
444+
config.account = U("");
445+
435446

436447

437448

include/tigerapi/client_config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ namespace TIGER_API {
4646
utility::string_t sign_type = U("RSA");
4747
utility::string_t lang;
4848
utility::string_t device_id = Utils::get_device_id();
49+
utility::string_t secret_key;
4950

5051
void check() {
5152
if (this->tiger_id.empty()) {

include/tigerapi/constants.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ static utility::string_t P_SDK_VERSION_PREFIX = U("openapi-cpp-sdk-");
2323
static utility::string_t P_USER_AGENT = U("User-Agent");
2424
static utility::string_t P_BIZ_CONTENT = U("biz_content");
2525
static utility::string_t P_ACCOUNT = U("account");
26+
static utility::string_t P_SECRET_KEY = U("secret_key");
2627
static utility::string_t P_MARKET = U("market");
2728
static utility::string_t P_SYMBOLS = U("symbols");
2829
static utility::string_t P_SYMBOL = U("symbol");
30+
static utility::string_t P_INCLUDE_OTC = U("include_otc");
2931
static utility::string_t P_CONTRACT_CODES = U("contract_codes");
3032
static utility::string_t P_CONTRACT_CODE = U("contract_code");
3133
static utility::string_t P_PERIOD = U("period");
@@ -50,6 +52,9 @@ static utility::string_t P_SEG_TYPE = U("seg_type");
5052
static utility::string_t P_CURRENCY = U("currency");
5153
static utility::string_t P_EXCHANGE = U("exchange");
5254
static utility::string_t P_TYPE = U("type");
55+
static utility::string_t P_BEGIN = U("begin");
56+
static utility::string_t P_END = U("end");
57+
static utility::string_t P_TICK_SIZE = U("tick_size");
5358
static utility::string_t P_EXCHANGE_CODE = U("exchange_code");
5459
static utility::string_t P_PAGE = U("page");
5560
static utility::string_t P_PAGE_SIZE = U("page_size");

include/tigerapi/enums.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ namespace TIGER_API {
328328

329329
enum class OrderStatus {
330330
PendingNew,
331+
PendingSubmit,
331332
Initial,
332333
Submitted,
333334
PartiallyFilled,
@@ -342,6 +343,8 @@ namespace TIGER_API {
342343
switch (status) {
343344
case OrderStatus::PendingNew:
344345
return U("PendingNew");
346+
case OrderStatus::PendingSubmit:
347+
return U("PendingSubmit");
345348
case OrderStatus::Initial:
346349
return U("Initial");
347350
case OrderStatus::Submitted:
@@ -362,6 +365,23 @@ namespace TIGER_API {
362365
return U("");
363366
}
364367
}
368+
369+
enum class TickSizeType {
370+
OPEN,
371+
OPEN_CLOSED,
372+
CLOSED_OPEN,
373+
CLOSED
374+
};
375+
376+
inline utility::string_t enum_to_str(TickSizeType type) {
377+
switch (type) {
378+
case TickSizeType::OPEN: return U("OPEN"); break;
379+
case TickSizeType::OPEN_CLOSED: return U("OPEN_CLOSED"); break;
380+
case TickSizeType::CLOSED_OPEN: return U("CLOSED_OPEN"); break;
381+
case TickSizeType::CLOSED: return U("CLOSED"); break;
382+
default: return U(""); break;
383+
}
384+
};
365385
}
366386

367387

include/tigerapi/model.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,11 @@ namespace TIGER_API {
8383
utility::string_t action;
8484
/** 下单数量 **/
8585
long long total_quantity = 0;
86+
/** 下单数量偏移位数,如 total_quantity 为 5, total_quantity_scale 为 1, 则实际下单数量为 5 * 10^-1 = 0.5 **/
87+
long total_quantity_scale = 0;
8688
/** 限价单价格 **/
8789
double limit_price = 0;
90+
utility::string_t s_limit_price;
8891
/** 在止损单中, 表示触发止损单的价格, 在移动止损单中, 表示跟踪的价差 **/
8992
double aux_price = 0;
9093
double trail_stop_price = 0;
@@ -98,7 +101,7 @@ namespace TIGER_API {
98101
* 价格微调幅度(默认为0表示不调整,正数为向上调整,负数向下调整),对传入价格自动调整到合法价位上.
99102
例如:0.001 代表向上调整且幅度不超过 0.1%;-0.001 代表向下调整且幅度不超过 0.1%。默认 0 表示不调整
100103
*/
101-
bool adjust_limit;
104+
double adjust_limit;
102105
utility::string_t user_mark;
103106
time_t expire_time = 0;
104107

@@ -116,6 +119,8 @@ namespace TIGER_API {
116119
time_t update_time;
117120
// 成交数量
118121
long long filled_quantity;
122+
// 成交金额偏移位数
123+
long filled_quantity_scale;
119124
// 包含佣金的平均成交价
120125
double avg_fill_price;
121126
// 实现盈亏
@@ -124,6 +129,7 @@ namespace TIGER_API {
124129
web::json::value sub_ids;
125130
utility::string_t algo_strategy;
126131
double commission;
132+
double gst;
127133

128134
utility::string_t to_string() {
129135
utility::stringstream_t ss;
@@ -173,7 +179,7 @@ namespace TIGER_API {
173179
outside_rth = json.at(U("outsideRth")).as_bool();
174180
}
175181
if (json.has_field(U("adjustLimit"))) {
176-
adjust_limit = json.at(U("adjustLimit")).as_bool();
182+
adjust_limit = json.at(U("adjustLimit")).as_double();
177183
}
178184
if (json.has_field(U("userMark"))) {
179185
user_mark = json.at(U("userMark")).as_string();
@@ -214,12 +220,25 @@ namespace TIGER_API {
214220
if (json.has_field(U("commission"))) {
215221
commission = json.at(U("commission")).as_double();
216222
}
223+
if (json.has_field(U("gst"))) {
224+
gst = json.at(U("gst")).as_double();
225+
}
217226
if (json.has_field(U("subIds"))) {
218227
sub_ids = json.at(U("subIds"));
219228
}
220229
if (json.has_field(U("algoStrategy"))) {
221230
algo_strategy = json.at(U("algoStrategy")).as_string();
222231
}
232+
if (json.has_field(U("total_quantity_scale"))) {
233+
total_quantity_scale = json.at(U("total_quantity_scale")).as_number().to_int64();
234+
}
235+
if (json.has_field(U("filled_quantity_scale"))) {
236+
filled_quantity_scale = json.at(U("filled_quantity_scale")).as_number().to_int64();
237+
}
238+
if (json.has_field(U("secret_key"))) {
239+
secret_key = json.at(U("secret_key")).as_string();
240+
}
241+
223242
};
224243

225244
};

include/tigerapi/order_util.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ namespace TIGER_API {
2323
static Order
2424
limit_order(Contract &contract, const utility::string_t action, long quantity, double limit_price);
2525

26+
static Order
27+
limit_order(Contract& contract, const utility::string_t action, long quantity, const utility::string_t limit_price);
28+
29+
2630
static Order
2731
stop_order(const utility::string_t account, Contract &contract, const utility::string_t action, long quantity,
2832
double aux_price);

include/tigerapi/price_util.h

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
//
2+
// Created by sukai on 2024/3/8.
3+
//
4+
5+
#ifndef TIGERAPI_PRICEUTIL_H
6+
#define TIGERAPI_PRICEUTIL_H
7+
#include <iostream>
8+
#include <vector>
9+
#include <cmath>
10+
#include <map>
11+
#include "cpprest/json.h"
12+
#include "cpprest/details/basic_types.h"
13+
#include "constants.h"
14+
#include "enums.h"
15+
16+
namespace TIGER_API {
17+
18+
19+
class PriceUtil {
20+
public:
21+
static const std::string INF;
22+
static const double RELATIVE_TOLERANCE;
23+
static const utility::string_t TICK_SIZE;
24+
25+
static bool match_tick_size(double price, const web::json::value &tick_sizes) {
26+
if (price == 0 || tick_sizes.size() == 0) {
27+
return false;
28+
}
29+
double fixed_price = fix_price_by_tick_size(price, tick_sizes);
30+
return std::abs(price - fixed_price) <= RELATIVE_TOLERANCE;
31+
}
32+
33+
static double fix_price_by_tick_size(double price, const web::json::value tick_sizes, bool is_up = false) {
34+
if (price == 0) {
35+
return 0;
36+
}
37+
auto tick_size_item = find_tick_size_item(price, tick_sizes);
38+
if (tick_size_item.is_null()) {
39+
return price;
40+
}
41+
double min_tick = tick_size_item[TICK_SIZE].as_double();
42+
43+
double begin = stod(tick_size_item[P_BEGIN].as_string());
44+
return round_with_tick(price, begin, min_tick, is_up);
45+
}
46+
47+
static const web::json::value find_tick_size_item(double price, const web::json::value tick_sizes) {
48+
if (price == 0 || tick_sizes.size() == 0) {
49+
return {};
50+
}
51+
for (const auto& item : tick_sizes.as_array()) {
52+
utility::string_t type = item.at(P_TYPE).as_string();
53+
double begin = stod(item.at(P_BEGIN).as_string());
54+
double end = (item.at(P_END).as_string() == INF) ? INFINITY : stod(item.at(P_END).as_string());
55+
if (type == enum_to_str(TickSizeType::OPEN)) {
56+
if (begin < price && price < end) {
57+
return item;
58+
}
59+
} else if (type == enum_to_str(TickSizeType::CLOSED)) {
60+
if (begin <= price && price <= end) {
61+
return item;
62+
}
63+
} else if (type == enum_to_str(TickSizeType::CLOSED_OPEN)) {
64+
if (begin <= price && price < end) {
65+
return item;
66+
}
67+
} else if (type == enum_to_str(TickSizeType::OPEN_CLOSED)) {
68+
if (begin < price && price <= end) {
69+
return item;
70+
}
71+
}
72+
}
73+
return {};
74+
}
75+
76+
static double round_with_tick(double price, double begin, double min_tick, bool is_up) {
77+
double multiple = (price - begin) / min_tick;
78+
if (multiple <= 0) {
79+
return price;
80+
}
81+
if (is_up) {
82+
multiple += 1;
83+
}
84+
return std::floor(multiple) * min_tick + begin;
85+
}
86+
};
87+
88+
const utility::string_t PriceUtil::INF = U("Infinity");
89+
const utility::string_t PriceUtil::TICK_SIZE = U("tickSize");
90+
const double PriceUtil::RELATIVE_TOLERANCE = 1e-6;
91+
92+
} // TIGER_API
93+
94+
#endif //TIGERAPI_PRICEUTIL_H

include/tigerapi/quote_client.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ namespace TIGER_API {
2222

2323
/** 股票行情 Stock quote related api **/
2424

25-
value get_symbols(Market market = Market::ALL);
26-
value get_all_symbol_names(Market market = Market::ALL);
27-
value get_all_symbol_names(utility::string_t market=U("ALL"));
25+
value get_symbols(Market market = Market::ALL, bool include_otc=false);
26+
value get_all_symbol_names(Market market = Market::ALL, bool include_otc=false);
27+
value get_all_symbol_names(utility::string_t market = U("ALL"), bool include_otc=false);
2828
value get_market_state(utility::string_t market);
2929
value get_trading_calendar(Market market, utility::string_t begin_date, utility::string_t end_date);
3030
value get_trading_calendar(utility::string_t market, utility::string_t begin_date, utility::string_t end_date);

include/tigerapi/trade_client.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ namespace TIGER_API {
172172

173173
private:
174174
value get_account_param(const utility::string_t &account=U(""));
175+
176+
void set_secret_key(value &obj);
175177
};
176178
}
177179

0 commit comments

Comments
 (0)