Skip to content

Commit f5fd8c8

Browse files
committed
tick util
1 parent f4125f0 commit f5fd8c8

File tree

9 files changed

+166
-14
lines changed

9 files changed

+166
-14
lines changed

changlog.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
1-
## 0.1.0 (2023-02-15)
1+
## 0.1.6 (2024-03-08)
22
### New
3-
- Beta版本,支持交易、行情接口
3+
- 新增根据ticksize调整下单价格的工具 PriceUtil
4+
45

56
## 0.1.5 (2024-02-04)
67
### Modify
7-
- 交易接口支持 `secret_key`
8+
- 交易接口支持 `secret_key`
9+
10+
11+
## 0.1.0 (2023-02-15)
12+
### New
13+
- Beta版本,支持交易、行情接口
14+

demo/openapi_cpp_test/openapi_cpp_test.cpp

Lines changed: 13 additions & 3 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;
@@ -167,10 +168,17 @@ class TestTradeClient {
167168
ucout << U("place forex order: ") << res << endl;
168169
}
169170

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+
}
170177

171178
static void test_trade(const std::shared_ptr<TradeClient>& trade_client) {
172-
TestTradeClient::test_place_option_order(trade_client);
179+
TestTradeClient::test_price_util(trade_client);
173180
}
181+
174182
};
175183

176184

@@ -192,7 +200,7 @@ class TestQuoteClient {
192200

193201
static void test_get_symbols_names(const std::shared_ptr<QuoteClient> quote_client) {
194202
// value result = quote_client->get_all_symbol_names(U("HK"));
195-
value result = quote_client->get_all_symbol_names(Market::HK);
203+
value result = quote_client->get_all_symbol_names(Market::HK, false);
196204
ucout << U("result: ") << result << endl;
197205
}
198206

@@ -228,7 +236,8 @@ class TestQuoteClient {
228236
value symbols = value::array();
229237
symbols[0] = value::string(U("AAPL"));
230238
symbols[1] = value::string(U("JD"));
231-
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);
232241
ucout << U("result: ") << result.at(0).to_string() << endl;
233242
}
234243

@@ -437,6 +446,7 @@ int main()
437446

438447

439448

449+
440450
//config.lang = U("en_US");
441451

442452

include/tigerapi/constants.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ static utility::string_t P_SECRET_KEY = U("secret_key");
2727
static utility::string_t P_MARKET = U("market");
2828
static utility::string_t P_SYMBOLS = U("symbols");
2929
static utility::string_t P_SYMBOL = U("symbol");
30+
static utility::string_t P_INCLUDE_OTC = U("include_otc");
3031
static utility::string_t P_CONTRACT_CODES = U("contract_codes");
3132
static utility::string_t P_CONTRACT_CODE = U("contract_code");
3233
static utility::string_t P_PERIOD = U("period");
@@ -51,6 +52,9 @@ static utility::string_t P_SEG_TYPE = U("seg_type");
5152
static utility::string_t P_CURRENCY = U("currency");
5253
static utility::string_t P_EXCHANGE = U("exchange");
5354
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");
5458
static utility::string_t P_EXCHANGE_CODE = U("exchange_code");
5559
static utility::string_t P_PAGE = U("page");
5660
static utility::string_t P_PAGE_SIZE = U("page_size");

include/tigerapi/enums.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,23 @@ namespace TIGER_API {
365365
return U("");
366366
}
367367
}
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+
};
368385
}
369386

370387

include/tigerapi/model.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ 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;
8890
utility::string_t s_limit_price;
@@ -117,6 +119,8 @@ namespace TIGER_API {
117119
time_t update_time;
118120
// 成交数量
119121
long long filled_quantity;
122+
// 成交金额偏移位数
123+
long filled_quantity_scale;
120124
// 包含佣金的平均成交价
121125
double avg_fill_price;
122126
// 实现盈亏
@@ -125,6 +129,7 @@ namespace TIGER_API {
125129
web::json::value sub_ids;
126130
utility::string_t algo_strategy;
127131
double commission;
132+
double gst;
128133

129134
utility::string_t to_string() {
130135
utility::stringstream_t ss;
@@ -215,12 +220,25 @@ namespace TIGER_API {
215220
if (json.has_field(U("commission"))) {
216221
commission = json.at(U("commission")).as_double();
217222
}
223+
if (json.has_field(U("gst"))) {
224+
gst = json.at(U("gst")).as_double();
225+
}
218226
if (json.has_field(U("subIds"))) {
219227
sub_ids = json.at(U("subIds"));
220228
}
221229
if (json.has_field(U("algoStrategy"))) {
222230
algo_strategy = json.at(U("algoStrategy")).as_string();
223231
}
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+
224242
};
225243

226244
};

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/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#ifndef TIGERAPI_VERSION_H
66
#define TIGERAPI_VERSION_H
77

8-
#define PROJECT_VERSION "0.1.5"
8+
#define PROJECT_VERSION "0.1.6"
99
#include "easylogging++.h"
1010
INITIALIZE_EASYLOGGINGPP
1111
#endif //TIGERAPI_VERSION_H

src/quote_client.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ namespace TIGER_API {
1919
return post(GRAB_QUOTE_PERMISSION, obj);
2020
}
2121

22-
value QuoteClient::get_symbols(Market market) {
22+
value QuoteClient::get_symbols(Market market, bool include_otc) {
2323
value obj = value::object(true);
2424
obj[P_MARKET] = value::string(enum_to_str(market));
25+
obj[P_INCLUDE_OTC] = value::boolean(include_otc);
2526
return post(ALL_SYMBOLS, obj);
2627
}
2728

@@ -31,13 +32,14 @@ namespace TIGER_API {
3132
return post(QUOTE_STOCK_TRADE, obj);
3233
}
3334

34-
value QuoteClient::get_all_symbol_names(Market market) {
35-
return get_all_symbol_names(enum_to_str(market));
35+
value QuoteClient::get_all_symbol_names(Market market, bool include_otc) {
36+
return get_all_symbol_names(enum_to_str(market), include_otc);
3637
}
3738

38-
value QuoteClient::get_all_symbol_names(utility::string_t market) {
39+
value QuoteClient::get_all_symbol_names(utility::string_t market, bool include_otc) {
3940
value obj = value::object(true);
4041
obj[P_MARKET] = value::string(market);
42+
obj[P_INCLUDE_OTC] = value::boolean(include_otc);
4143
return post(ALL_SYMBOL_NAMES, obj);
4244
}
4345

0 commit comments

Comments
 (0)