futu_rest/routes/trd/
position_action.rs1use std::sync::Arc;
4
5use axum::Json;
6use axum::extract::{Extension, State};
7use serde_json::Value;
8
9use futu_auth::KeyRecord;
10
11use crate::adapter::{self, RestState};
12
13use super::ApiResult;
14use super::card_num::extract_and_resolve_card_num_into_acc_id;
15use super::validation::{authorize_trade_write, validate_header_trd_market_write};
16
17macro_rules! position_route {
18 ($fn_name:ident, $path:literal, $request:path, $response:path, $proto_id:expr) => {
19 pub async fn $fn_name(
20 State(state): State<RestState>,
21 rec: Option<Extension<Arc<KeyRecord>>>,
22 Json(mut body): Json<Value>,
23 ) -> ApiResult {
24 crate::adapter::normalize_json_keys_snake_case(&mut body);
25 authorize_trade_write(
26 &state,
27 rec.as_ref().map(|Extension(record)| record.as_ref()),
28 &body,
29 $path,
30 )?;
31 extract_and_resolve_card_num_into_acc_id(
32 &state,
33 rec.as_ref().map(|Extension(record)| record.as_ref()),
34 &mut body,
35 $path,
36 )?;
37 validate_header_trd_market_write(&body, $path)?;
38 adapter::proto_request_with_idempotency_and_caller::<$request, $response>(
39 &state,
40 $proto_id,
41 Some(body),
42 None,
43 rec.as_ref().map(|Extension(record)| record.id.clone()),
44 )
45 .await
46 }
47 };
48}
49
50position_route!(
51 reverse_position,
52 "/api/trd/reverse-position",
53 futu_proto::trd_reverse_position::Request,
54 futu_proto::trd_reverse_position::Response,
55 futu_core::proto_id::TRD_REVERSE_POSITION
56);
57position_route!(
58 roll_position,
59 "/api/trd/roll-position",
60 futu_proto::trd_roll_position::Request,
61 futu_proto::trd_roll_position::Response,
62 futu_core::proto_id::TRD_ROLL_POSITION
63);
64position_route!(
65 clear_futures_positions,
66 "/api/trd/clear-futures-positions",
67 futu_proto::trd_clear_futures_positions::Request,
68 futu_proto::trd_clear_futures_positions::Response,
69 futu_core::proto_id::TRD_CLEAR_FUTURES_POSITIONS
70);
71position_route!(
72 batch_close_positions,
73 "/api/trd/batch-close-positions",
74 futu_proto::trd_batch_close_positions::Request,
75 futu_proto::trd_batch_close_positions::Response,
76 futu_core::proto_id::TRD_BATCH_CLOSE_POSITIONS
77);