-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsample_sendorder.cpp
130 lines (112 loc) · 4.38 KB
/
sample_sendorder.cpp
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
#include <netdb.h>
#include <chrono>
#include <iostream>
#include "fix_engine.h"
#include "msg_logon.h"
#include "msg_orders.h"
// #define GO_TRADER
namespace config {
#ifdef GO_TRADER
static const char *TARGET_COMP_ID = "GOX"; // GOX to talk with go-trader, or SERVER to talk with sample_server
static const int PORT = 5001; // 5001 to talk with go-trader, or 9000 to talk with sample_server
#else
static const char *TARGET_COMP_ID = "SERVER"; // GOX to talk with go-trader, or SERVER to talk with sample_server
static const int PORT = 9000; // 5001 to talk with go-trader, or 9000 to talk with sample_server
#endif
}
struct Config {
std::string symbol;
F price;
int quantity;
int timeout_seconds;
};
class MyClient : public Initiator<> {
static const int N_QUOTES = 100000;
FixBuilder fix;
Config config;
long exchangeId;
public:
MyClient(sockaddr_in &server,DefaultSessionConfig sessionConfig,Config config) : Initiator(server, sessionConfig), config(config) {};
void onConnected() {
std::cout << "client connected!, sending logon\n";
Logon::build(fix);
sendMessage(Logon::msgType, fix);
}
void onMessage(Session<DefaultSessionConfig> &session, const FixMessage &msg) {
if (msg.msgType() == ExecutionReport::msgType) {
exchangeId = msg.getLong(37);
std::cout << "received execution report:" << msg << "\n";
if(msg.getInt(Tag::ORD_STATUS)==int(OrderStatus::Filled)) {
std::cout << "status: order filled\n";
}
if(msg.getChar(20)==char(ExecType::Filled)) {
std::cout << "trade: order filled\n";
disconnect();
}
if(msg.getInt(Tag::ORD_STATUS)==int(OrderStatus::Canceled)) {
std::cout << "status: order cancelled\n";
disconnect();
}
}
}
bool validateLogon(const FixMessage &logon) { return true; }
void onLoggedOn(const Session<DefaultSessionConfig> &session) {
std::cout << "client logged in!\n";
std::cout << "sending buy order: " << config.symbol << " " << config.price << " " << config.quantity << "\n";
NewOrderSingle::build<7>(fix, config.symbol, OrderType::Limit, OrderSide::Buy, config.price, config.quantity, "MyOrder");
sendMessage(NewOrderSingle::msgType, fix);
}
void onLoggedOut(const Session<DefaultSessionConfig> &session, const std::string_view &text) {
std::cout << "client logged out " << text << "\n";
}
void cancelOrder() {
std::cout << "sending cancel\n";
OrderCancelRequest::build<7>(fix, exchangeId, config.symbol, OrderType::Limit, OrderSide::Buy, config.price, config.quantity, "MyOrder");
sendMessage(OrderCancelRequest::msgType, fix);
}
};
int main(int argc, char *argv[]) {
struct hostent *he;
struct sockaddr_in server;
if((argc > 1 && strcmp(argv[1],"-h")==0) || argc != 6) {
std::cout << "usage: " << argv[0] << " hostname symbol price quantity timeout_seconds\n";
exit(0);
}
const char *hostname = argv[1];
Config config = {
argv[2],
std::stod(argv[3]),
std::stoi(argv[4]),
std::stoi(argv[5])
};
/* resolve hostname */
if ((he = gethostbyname(hostname)) == NULL) {
std::cerr << "gethostbyname failed" << hostname << "\n";
exit(1); /* error */
}
memcpy(&server.sin_addr, he->h_addr_list[0], he->h_length);
server.sin_port = htons(config::PORT);
server.sin_family = AF_INET;
struct DefaultSessionConfig sessionConfig("SENDORDER_"+config.symbol, config::TARGET_COMP_ID);
MyClient client(server, sessionConfig, config);
std::thread clientThread([&client]() {
client.connect();
client.handle();
});
bool cancelSent = false;
auto start = std::chrono::system_clock::now();
while(true) {
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
if(!client.isConnected()) {
break;
}
auto now = std::chrono::system_clock::now();
if(!cancelSent && std::chrono::duration_cast<std::chrono::seconds>(now-start).count() > config.timeout_seconds) {
std::cout << "Timeout reached, sending cancel\n";
client.cancelOrder();
cancelSent = true;
break;
}
}
clientThread.join();
}