cfix/
parse_func.rs

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
84//
85// ORDER
86//
87pub 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}