-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCryptoExMain.cpp
More file actions
243 lines (210 loc) · 6.78 KB
/
CryptoExMain.cpp
File metadata and controls
243 lines (210 loc) · 6.78 KB
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
#include "CryptoExMain.h"
#include <iostream>
#include <vector>
#include "OrderBookEntry.h"
#include "CSVReader.h"
/** Constructor */
CryptoExMain::CryptoExMain()
{
}
/** App initalisaion */
void CryptoExMain::init()
{
int input;
// starts the app at the earliest time
currentTime = orderBook.getEarliestTime();
// gives the user some currency to play around with
wallet.insertCurrency("BTC", 10);
// cycles until a user quits
bool run = true;
while(run) {
printMenu();
input = getUserOption();
run = processUserOption(input);
}
};
/** Prints a menu for the user */
void CryptoExMain::printMenu()
{
std::cout << "1: Print help" << std::endl;
std::cout << "2: Print statistics" << std::endl;
std::cout << "3: Make an offer" << std::endl;
std::cout << "4: Make a bid" << std::endl;
std::cout << "5: Print wallet" << std::endl;
std::cout << "6: Continue" << std::endl;
std::cout << "7: Exit" << std::endl;
std::cout << "====================" << std::endl;
// let's let a user know what the time is
std::cout << "Current time is " << currentTime << std::endl;
}
/** Tells user the point of the app */
void CryptoExMain::printHelp(){
std::cout << "Help - your aim is to make money. Analyze the market and make bids and offers." << std::endl;
}
/** Shows user the max and min ask for each price pair.
* Also shows how many asks have been seen.
*/
void CryptoExMain::printMarketStats(){
// iterate through products in order book
for (std::string const& p : orderBook.getKnownProducts())
{
// print the stats for each order
std::cout << "Product: " << p << std::endl;
std::vector<OrderBookEntry> entries = orderBook.getOrders(OrderBookType::ask,
p, currentTime);
std::cout << "Asks seen: " << entries.size() << std::endl;
std::cout << "Max ask : " << OrderBook::getHighPrice(entries) << std::endl;
std::cout << "Min ask : " << OrderBook::getLowPrice(entries) << std::endl;
}
}
/** Allows a user to enter an ask.
* User puts in the currency pair, the price and the amount
*/
void CryptoExMain::enterAsk() {
std::cout << "Make an ask - empty the amount: product, price, amount, eg ETH/BTC,200,0.5" << std::endl;
std::string input;
std::getline(std::cin, input);
// tokenises user input
std::vector<std::string> tokens = CSVReader::tokenise(input, ',');
if (tokens.size() != 3)
{
std::cout << "CryptoExMain::enterAsk Bad input " << input << std::endl;
}
else {
try {
// create an order book entry
OrderBookEntry obe = CSVReader::stringsToOBE(
tokens[1],
tokens[2],
currentTime,
tokens[0],
OrderBookType::ask
);
obe.username = "simuser"; // just to differentiate from the rest of the dataset
// checks if ask can be fulfulled based on wallet contents, adds it to the order book if it can
if (wallet.canFulfillOrder(obe))
{
std::cout << "Wallet looks good" << std::endl;
orderBook.insertOrder(obe);
} else {
std::cout << "Insufficient funds " << input << std::endl;
}
} catch(const std::exception& e)
{
std::cout << "CryptoExMain::enterAsk Bad input: " << input << std::endl;
}
}
// lets a user know what they typed
std::cout << "You typed " << input << std::endl;
}
/** Allows a user to enter an ask.
* User puts in the currency pair, the price and the amount
*/
void CryptoExMain::enterBid()
{
std::cout << "Make a bid - enter the amount: product,price,amount, eg: ETH/BTC,200,0.5" << std::endl;
std::string input;
std::getline(std::cin, input);
// tokenises user input
std::vector<std::string> tokens = CSVReader::tokenise(input, ',');
if (tokens.size() != 3)
{
std::cout << "CryptoExMain::enterBid Bad input! " << input << std::endl;
}
else {
try
{
// enters bid into order book
OrderBookEntry obe = CSVReader::stringsToOBE(
tokens[1],
tokens[2],
currentTime,
tokens[0],
OrderBookType::bid
);
obe.username = "simuser";
// checks if ask can be fulfulled based on wallet contents, adds it to the order book if it can
if (wallet.canFulfillOrder(obe))
{
std::cout << "Wallet looks good. " << std::endl;
orderBook.insertOrder(obe);
}
else
{
std::cout << "Wallet has insufficient funds. " << std::endl;
}
}
catch (const std::exception &e)
{
std::cout << "MerkelMain::enterBid Bad input " << std::endl;
}
};
}
/** Prints the contents of a user's wallet*/
void CryptoExMain::printWallet(){
std::cout << wallet.toString() << std::endl;
}
/** Steps forward in time. */
void CryptoExMain::gotoNextTimestamp(){
std::cout << "Going to next time frame" << std::endl;
// computes trades in the order book
std::vector<OrderBookEntry> sales = orderBook.matchAsksToBids("ETH/BTC", currentTime);
// prints the number of sales
std::cout << "Sales: " << sales.size() << std::endl;
// go through all the executed sales
for (OrderBookEntry &sale : sales)
{
std::cout << "Sale price: " << sale.price << " Amount " << sale.amount << std::endl;
if (sale.username == "simuser")
{
// updates the wallet
wallet.processSale(sale);
}
}
// moves time after computing sales
currentTime = orderBook.getNextTime(currentTime);
}
/** Takes in the user's option*/
int CryptoExMain::getUserOption() {
int userOption = 0;
std::string line;
std::cout << "Type 1-7" << std::endl;
std::getline(std::cin, line);
try
{
userOption = std::stoi(line);
}
catch(const std::exception& e)
{
std::cout << "CryptoExMain::getUserOption Bad Input: Type 1-6" << std::endl;
}
return userOption;
}
/** Decides what to execute depending on the user's option*/
bool CryptoExMain::processUserOption(int userOption) {
if (userOption == 0) { // bad input
std::cout << "CryptoExMain::processUserOption Bad Input: Type 1-7" << std::endl;
}
if (userOption == 1) {
printHelp();
}
if (userOption == 2) {
printMarketStats();
}
if (userOption == 3) {
enterAsk();
}
if (userOption == 4) {
enterBid();
}
if (userOption == 5) {
printWallet();
}
if (userOption == 6) {
gotoNextTimestamp();
}
if (userOption == 7) {
return false;
}
return true;
}