1use chrono::NaiveDateTime;
2
3use crate::{
4 messages::ResponseMessage,
5 types::{
6 Error, ExecutionReport, ExecutionType, Field, OrderReport, OrderStatus, OrderType,
7 PositionReport, Side, SymbolInformation,
8 },
9};
10
11pub fn parse_security_list(res: &ResponseMessage) -> Result<Vec<SymbolInformation>, Error> {
12 let sec_list = res.get_repeating_groups(Field::NoRelatedSym, Field::Symbol, None);
13 let mut result = Vec::new();
14 for symbol in sec_list.into_iter() {
15 if symbol.len() < 3 {
16 continue;
17 }
18 result.push(SymbolInformation {
19 name: symbol
20 .get(&Field::SymbolName)
21 .ok_or(Error::FieldNotFoundError(Field::SymbolName))?
22 .clone(),
23 id: symbol
24 .get(&Field::Symbol)
25 .ok_or(Error::FieldNotFoundError(Field::Symbol))?
26 .parse::<u32>()
27 .unwrap(),
28 digits: symbol
29 .get(&Field::SymbolDigits)
30 .ok_or(Error::FieldNotFoundError(Field::SymbolDigits))?
31 .parse::<u32>()
32 .unwrap(),
33 });
34 }
35 Ok(result)
36}
37
38pub fn parse_positions(res: Vec<ResponseMessage>) -> Result<Vec<PositionReport>, Error> {
39 Ok(res
40 .into_iter()
41 .filter(|res| res.get_field_value(Field::PosReqResult).unwrap() == "0")
42 .filter(|res| {
43 res.get_field_value(Field::NoPositions)
44 .map(|v| v == "1")
45 .unwrap_or(false)
46 })
47 .map(|res| PositionReport {
48 symbol_id: res
49 .get_field_value(Field::Symbol)
50 .unwrap()
51 .parse::<u32>()
52 .unwrap(),
53 position_id: res.get_field_value(Field::PosMaintRptID).unwrap(),
54 long_qty: res
55 .get_field_value(Field::LongQty)
56 .unwrap()
57 .parse::<f64>()
58 .unwrap(),
59 short_qty: res
60 .get_field_value(Field::ShortQty)
61 .unwrap()
62 .parse::<f64>()
63 .unwrap(),
64 settle_price: res
65 .get_field_value(Field::SettlPrice)
66 .unwrap()
67 .parse::<f64>()
68 .unwrap(),
69 absolute_tp: res
70 .get_field_value(Field::AbsoluteTP)
71 .map(|v| v.parse::<f64>().unwrap()),
72 absolute_sl: res
73 .get_field_value(Field::AbsoluteSL)
74 .map(|v| v.parse::<f64>().unwrap()),
75 trailing_sl: res.get_field_value(Field::TrailingSL).map(|v| v == "Y"),
76 trigger_method_sl: res
77 .get_field_value(Field::TriggerMethodSL)
78 .map(|v| v.parse::<u32>().unwrap()),
79 guaranteed_sl: res.get_field_value(Field::GuaranteedSL).map(|v| v == "Y"),
80 })
81 .collect())
82}
83
84pub fn parse_execution_report(res: ResponseMessage) -> Result<ExecutionReport, Error> {
88 Ok(ExecutionReport {
89 exec_type: res
90 .get_field_value(Field::ExecType)
91 .unwrap()
92 .parse::<ExecutionType>()
93 .unwrap(),
94 order_report: OrderReport {
95 symbol: res
96 .get_field_value(Field::Symbol)
97 .unwrap_or("0".into())
98 .parse::<u32>()
99 .unwrap(),
100 order_id: res.get_field_value(Field::OrderID).unwrap(),
101 cl_ord_id: res.get_field_value(Field::ClOrdId).unwrap(),
102 pos_main_rept_id: res.get_field_value(Field::PosMaintRptID).unwrap(),
103 designation: res.get_field_value(Field::Designation),
104
105 order_status: res
106 .get_field_value(Field::OrdStatus)
107 .map(|v| v.parse::<OrderStatus>().unwrap())
108 .unwrap(),
109 order_type: res
110 .get_field_value(Field::OrdType)
111 .map(|v| v.parse::<OrderType>().unwrap())
112 .unwrap(),
113 side: res
114 .get_field_value(Field::Side)
115 .map(|v| Side::try_from(v.parse::<u32>().unwrap()).unwrap())
116 .unwrap(),
117
118 price: res
119 .get_field_value(Field::Price)
120 .map(|v| v.parse::<f64>().unwrap()),
121 stop_px: res
122 .get_field_value(Field::StopPx)
123 .map(|v| v.parse::<f64>().unwrap()),
124 avx_px: res
125 .get_field_value(Field::AvgPx)
126 .map(|v| v.parse::<f64>().unwrap()),
127
128 absolute_tp: res
129 .get_field_value(Field::AbsoluteTP)
130 .map(|v| v.parse::<f64>().unwrap()),
131 reltative_tp: res
132 .get_field_value(Field::RelativeTP)
133 .map(|v| v.parse::<f64>().unwrap()),
134 absolute_sl: res
135 .get_field_value(Field::AbsoluteSL)
136 .map(|v| v.parse::<f64>().unwrap()),
137 reltative_sl: res
138 .get_field_value(Field::RelativeSL)
139 .map(|v| v.parse::<f64>().unwrap()),
140 trailing_sl: res.get_field_value(Field::TrailingSL).map(|v| v == "Y"),
141 trigger_method_sl: res
142 .get_field_value(Field::TriggerMethodSL)
143 .map(|v| v.parse::<u32>().unwrap()),
144 guaranteed_sl: res.get_field_value(Field::GuaranteedSL).map(|v| v == "Y"),
145
146 cum_qty: res
147 .get_field_value(Field::CumQty)
148 .map(|v| v.parse::<f64>().unwrap()),
149 order_qty: res
150 .get_field_value(Field::OrderQty)
151 .unwrap_or("0.0".into())
152 .parse::<f64>()
153 .unwrap(),
154 leaves_qty: res
155 .get_field_value(Field::LeavesQty)
156 .unwrap_or("0.0".into())
157 .parse::<f64>()
158 .unwrap(),
159 last_qty: res
160 .get_field_value(Field::OrderQty)
161 .map(|v| v.parse::<f64>().unwrap()),
162
163 time_in_force: res.get_field_value(Field::TimeInForce).unwrap(),
164 transact_time: res
165 .get_field_value(Field::TransactTime)
166 .map(|v| NaiveDateTime::parse_from_str(v.as_str(), "%Y%m%d-%H:%M:%S%.3f").unwrap())
167 .unwrap(),
168 expire_time: res
169 .get_field_value(Field::ExpireTime)
170 .map(|v| NaiveDateTime::parse_from_str(v.as_str(), "%Y%m%d-%H:%M:%S%.3f").unwrap()),
171
172 text: res.get_field_value(Field::Text),
173 },
174 })
175}
176
177pub fn parse_order_mass_status(res: Vec<ResponseMessage>) -> Result<Vec<ExecutionReport>, Error> {
178 Ok(res
179 .into_iter()
180 .map(|res| parse_execution_report(res).unwrap())
181 .collect::<Vec<_>>())
182}