This repository has been archived by the owner on Feb 21, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 174
/
market_records.hpp
276 lines (237 loc) · 9.85 KB
/
market_records.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#pragma once
#include <bts/blockchain/asset.hpp>
#include <bts/blockchain/config.hpp>
#include <bts/blockchain/types.hpp>
#include <fc/exception/exception.hpp>
#include <fc/io/enum_type.hpp>
#include <fc/time.hpp>
#include <tuple>
namespace bts { namespace blockchain {
struct market_index_key
{
market_index_key( const price& price_arg = price(),
const address& owner_arg = address() )
:order_price(price_arg),owner(owner_arg){}
price order_price;
address owner;
friend bool operator == ( const market_index_key& a, const market_index_key& b )
{
return a.order_price == b.order_price && a.owner == b.owner;
}
friend bool operator < ( const market_index_key& a, const market_index_key& b )
{
return std::tie(a.order_price, a.owner) < std::tie(b.order_price, b.owner);
}
};
struct market_history_key
{
enum time_granularity_enum {
each_block,
each_hour,
each_day
};
market_history_key( asset_id_type quote_id = 0,
asset_id_type base_id = 1,
time_granularity_enum granularity = each_block,
fc::time_point_sec timestamp = fc::time_point_sec())
: quote_id(quote_id),
base_id(base_id),
granularity(granularity),
timestamp(timestamp)
{}
asset_id_type quote_id;
asset_id_type base_id;
time_granularity_enum granularity;
fc::time_point_sec timestamp;
bool operator < ( const market_history_key& other ) const
{
return std::tie(base_id, quote_id, granularity, timestamp) < std::tie(other.base_id, other.quote_id, other.granularity, other.timestamp);
}
bool operator == ( const market_history_key& other ) const
{
return quote_id == other.quote_id
&& base_id == other.base_id
&& granularity == other.granularity
&& timestamp == other.timestamp;
}
};
struct market_history_record
{
market_history_record(price highest_bid = price(),
price lowest_ask = price(),
price opening_price = price(),
price closing_price = price(),
share_type volume = 0,
fc::optional<price> recent_average_price = fc::optional<price>())
: highest_bid(highest_bid),
lowest_ask(lowest_ask),
opening_price(opening_price),
closing_price(closing_price),
volume(volume),
recent_average_price(recent_average_price)
{}
price highest_bid;
price lowest_ask;
price opening_price;
price closing_price;
share_type volume;
fc::optional<price> recent_average_price;
bool operator == ( const market_history_record& other ) const
{
return highest_bid == other.highest_bid
&& lowest_ask == other.lowest_ask
&& volume == other.volume;
}
};
typedef fc::optional<market_history_record> omarket_history_record;
struct market_history_point
{
fc::time_point_sec timestamp;
double highest_bid;
double lowest_ask;
double opening_price;
double closing_price;
share_type volume;
fc::optional<double> recent_average_price;
};
typedef vector<market_history_point> market_history_points;
struct order_record
{
order_record():balance(0){}
order_record( share_type b )
:balance(b){}
bool is_null() const { return 0 == balance; }
share_type balance;
};
typedef fc::optional<order_record> oorder_record;
enum order_type_enum
{
null_order,
bid_order,
ask_order,
short_order,
cover_order
};
struct market_order
{
market_order( order_type_enum t, market_index_key k, order_record s )
:type(t),market_index(k),state(s){}
market_order( order_type_enum t, market_index_key k, order_record s, share_type c )
:type(t),market_index(k),state(s),collateral(c){}
market_order():type(null_order){}
order_id_type get_id()const;
asset get_balance()const; // funds available for this order
price get_price()const;
price get_highest_cover_price()const; // the price that consumes all collateral
asset get_quantity()const;
asset get_quote_quantity()const;
address get_owner()const { return market_index.owner; }
fc::enum_type<uint8_t, order_type_enum> type = null_order;
market_index_key market_index;
order_record state;
optional<share_type> collateral;
};
struct market_transaction
{
address bid_owner;
address ask_owner;
price bid_price;
price ask_price;
asset bid_paid;
asset bid_received;
asset ask_paid;
asset ask_received;
fc::enum_type<uint8_t, order_type_enum> bid_type = null_order;
fc::enum_type<uint8_t, order_type_enum> ask_type = null_order;
asset fees_collected;
};
typedef optional<market_order> omarket_order;
struct order_history_record : public market_transaction
{
order_history_record(const market_transaction& market_trans = market_transaction(), fc::time_point_sec timestamp = fc::time_point_sec())
: market_transaction(market_trans),
timestamp(timestamp)
{}
fc::time_point_sec timestamp;
};
struct collateral_record
{
collateral_record(share_type c = 0, share_type p = 0):collateral_balance(c),payoff_balance(p){}
bool is_null() const { return 0 == payoff_balance && 0 == collateral_balance; }
share_type collateral_balance;
share_type payoff_balance;
};
typedef fc::optional<collateral_record> ocollateral_record;
struct market_status
{
market_status():bid_depth(-BTS_BLOCKCHAIN_MAX_SHARES),ask_depth(-BTS_BLOCKCHAIN_MAX_SHARES){}
market_status( asset_id_type quote, asset_id_type base, share_type biddepth, share_type askdepth )
:quote_id(quote),base_id(base),bid_depth(biddepth),ask_depth(askdepth){}
bool is_null()const { return bid_depth == ask_depth && bid_depth == -BTS_BLOCKCHAIN_MAX_SHARES; }
asset_id_type quote_id;
asset_id_type base_id;
price minimum_ask()const
{
auto avg = avg_price_1h;
avg.ratio *= 9;
avg.ratio /= 10;
return avg;
}
price maximum_bid()const
{
auto avg = avg_price_1h;
avg.ratio *= 10;
avg.ratio /= 9;
return avg;
}
share_type bid_depth;
share_type ask_depth;
/**
* Calculated as the average of the highest bid and lowest ask
* every time the market executes. The new is weighted against
* the old value with a factor of 1:BLOCKS_PER_DAY. In a very
* active market this will be a 24 hour moving average, in
* less active markets this will be a longer window.
*
* No shorts or covers will execute at prices more 30% +/- this
* number which serves as a natural rate limitor on price movement
* and thus limits the potential manipulation.
*/
price avg_price_1h;
optional<fc::exception> last_error;
};
typedef optional<market_status> omarket_status;
struct api_market_status : public market_status {
api_market_status(const market_status& market_stat = market_status())
: market_status(market_stat)
{}
double avg_price_1h;
};
} } // bts::blockchain
FC_REFLECT_ENUM( bts::blockchain::order_type_enum, (null_order)(bid_order)(ask_order)(short_order)(cover_order) )
FC_REFLECT_ENUM( bts::blockchain::market_history_key::time_granularity_enum, (each_block)(each_hour)(each_day) )
FC_REFLECT( bts::blockchain::market_status, (quote_id)(base_id)(bid_depth)(ask_depth)(avg_price_1h)(last_error) )
FC_REFLECT_DERIVED( bts::blockchain::api_market_status, (bts::blockchain::market_status), (avg_price_1h) )
FC_REFLECT( bts::blockchain::market_index_key, (order_price)(owner) )
FC_REFLECT( bts::blockchain::market_history_record, (highest_bid)(lowest_ask)(opening_price)(closing_price)(volume)(recent_average_price) )
FC_REFLECT( bts::blockchain::market_history_key, (quote_id)(base_id)(granularity)(timestamp) )
FC_REFLECT( bts::blockchain::market_history_point, (timestamp)(highest_bid)(lowest_ask)(opening_price)(closing_price)(volume)(recent_average_price) )
FC_REFLECT( bts::blockchain::order_record, (balance) )
FC_REFLECT( bts::blockchain::collateral_record, (collateral_balance)(payoff_balance) )
FC_REFLECT( bts::blockchain::market_order, (type)(market_index)(state)(collateral) )
FC_REFLECT_TYPENAME( std::vector<bts::blockchain::market_transaction> )
FC_REFLECT_TYPENAME( bts::blockchain::market_history_key::time_granularity_enum ) // http://en.wikipedia.org/wiki/Voodoo_programminqg
FC_REFLECT( bts::blockchain::market_transaction,
(bid_owner)
(ask_owner)
(bid_price)
(ask_price)
(bid_paid)
(bid_received)
(ask_paid)
(ask_received)
(bid_type)
(ask_type)
(fees_collected)
)
FC_REFLECT_DERIVED( bts::blockchain::order_history_record, (bts::blockchain::market_transaction), (timestamp) )