Skip to main content

futu_rest/routes/trd/
position_action.rs

1//! REST adapters for guarded v1.8 position actions.
2
3use 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);