Working API and daemon

master
Griffiths Lott 3 years ago
parent e3dbe48ee8
commit 42e4597117
  1. 359
      backend/secret_trader/Cargo.lock
  2. 6
      backend/secret_trader/Cargo.toml
  3. 6
      backend/secret_trader/TODO.txt
  4. 140
      backend/secret_trader/src/main.rs
  5. 56
      backend/secret_trader/src/order.rs
  6. 28
      backend/secret_trader/src/trade_mgmt.rs

@ -2,6 +2,30 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "actix"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "543c47e7827f8fcc9d1445bd98ba402137bfce80ee2187429de49c52b5131bd3"
dependencies = [
"actix-rt",
"actix_derive",
"bitflags",
"bytes",
"crossbeam-channel",
"futures-core",
"futures-sink",
"futures-task",
"futures-util",
"log",
"once_cell",
"parking_lot 0.11.2",
"pin-project-lite",
"smallvec",
"tokio",
"tokio-util 0.6.10",
]
[[package]]
name = "actix-codec"
version = "0.5.0"
@ -16,7 +40,7 @@ dependencies = [
"memchr",
"pin-project-lite",
"tokio",
"tokio-util",
"tokio-util 0.7.4",
]
[[package]]
@ -85,6 +109,7 @@ version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ea16c295198e958ef31930a6ef37d0fb64e9ca3b6116e6b93a8bdae96ee1000"
dependencies = [
"actix-macros",
"futures-core",
"tokio",
]
@ -181,6 +206,17 @@ dependencies = [
"syn",
]
[[package]]
name = "actix_derive"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d44b8fee1ced9671ba043476deddef739dd0959bf77030b26b738cc591737a7"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "adler"
version = "1.0.2"
@ -231,6 +267,114 @@ dependencies = [
"libc",
]
[[package]]
name = "async-attributes"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "async-channel"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833"
dependencies = [
"concurrent-queue",
"event-listener",
"futures-core",
]
[[package]]
name = "async-executor"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b"
dependencies = [
"async-lock",
"async-task",
"concurrent-queue",
"fastrand",
"futures-lite",
"slab",
]
[[package]]
name = "async-global-executor"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776"
dependencies = [
"async-channel",
"async-executor",
"async-io",
"async-lock",
"blocking",
"futures-lite",
"once_cell",
"tokio",
]
[[package]]
name = "async-io"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c374dda1ed3e7d8f0d9ba58715f924862c63eae6849c92d3a18e7fbde9e2794"
dependencies = [
"async-lock",
"autocfg",
"concurrent-queue",
"futures-lite",
"libc",
"log",
"parking",
"polling",
"slab",
"socket2",
"waker-fn",
"windows-sys",
]
[[package]]
name = "async-lock"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685"
dependencies = [
"event-listener",
"futures-lite",
]
[[package]]
name = "async-std"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d"
dependencies = [
"async-attributes",
"async-channel",
"async-global-executor",
"async-io",
"async-lock",
"crossbeam-utils",
"futures-channel",
"futures-core",
"futures-io",
"futures-lite",
"gloo-timers",
"kv-log-macro",
"log",
"memchr",
"once_cell",
"pin-project-lite",
"pin-utils",
"slab",
"wasm-bindgen-futures",
]
[[package]]
name = "async-stream"
version = "0.3.3"
@ -252,6 +396,18 @@ dependencies = [
"syn",
]
[[package]]
name = "async-task"
version = "4.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524"
[[package]]
name = "atomic-waker"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "debc29dde2e69f9e47506b525f639ed42300fc014a3e007832592448fa8e4599"
[[package]]
name = "autocfg"
version = "1.1.0"
@ -279,6 +435,20 @@ dependencies = [
"generic-array",
]
[[package]]
name = "blocking"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c67b173a56acffd6d2326fb7ab938ba0b00a71480e14902b2591c87bc5741e8"
dependencies = [
"async-channel",
"async-lock",
"async-task",
"atomic-waker",
"fastrand",
"futures-lite",
]
[[package]]
name = "brotli"
version = "3.3.4"
@ -361,6 +531,15 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "concurrent-queue"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "convert_case"
version = "0.4.0"
@ -412,6 +591,25 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
dependencies = [
"cfg-if",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
@ -422,6 +620,16 @@ dependencies = [
"typenum",
]
[[package]]
name = "ctor"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "cxx"
version = "1.0.86"
@ -498,6 +706,12 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "event-listener"
version = "2.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "fastrand"
version = "1.8.0"
@ -595,6 +809,21 @@ version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
[[package]]
name = "futures-lite"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48"
dependencies = [
"fastrand",
"futures-core",
"futures-io",
"memchr",
"parking",
"pin-project-lite",
"waker-fn",
]
[[package]]
name = "futures-macro"
version = "0.3.25"
@ -657,6 +886,18 @@ dependencies = [
"wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
name = "gloo-timers"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98c4a8d6391675c6b2ee1a6c8d06e8e2d03605c44cec1270675985a4c2a5500b"
dependencies = [
"futures-channel",
"futures-core",
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "h2"
version = "0.3.15"
@ -672,7 +913,7 @@ dependencies = [
"indexmap",
"slab",
"tokio",
"tokio-util",
"tokio-util 0.7.4",
"tracing",
]
@ -865,6 +1106,15 @@ version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd"
[[package]]
name = "kv-log-macro"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
dependencies = [
"log",
]
[[package]]
name = "language-tags"
version = "0.3.2"
@ -927,6 +1177,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
"value-bag",
]
[[package]]
@ -1060,6 +1311,23 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "parking"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
[[package]]
name = "parking_lot"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
dependencies = [
"instant",
"lock_api",
"parking_lot_core 0.8.6",
]
[[package]]
name = "parking_lot"
version = "0.12.1"
@ -1067,7 +1335,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
"parking_lot_core",
"parking_lot_core 0.9.6",
]
[[package]]
name = "parking_lot_core"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
dependencies = [
"cfg-if",
"instant",
"libc",
"redox_syscall",
"smallvec",
"winapi",
]
[[package]]
@ -1157,6 +1439,20 @@ version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
[[package]]
name = "polling"
version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22122d5ec4f9fe1b3916419b76be1e80bcb93f618d071d2edf841b137b2a2bd6"
dependencies = [
"autocfg",
"cfg-if",
"libc",
"log",
"wepoll-ffi",
"windows-sys",
]
[[package]]
name = "ppv-lite86"
version = "0.2.17"
@ -1323,12 +1619,16 @@ checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2"
name = "secret_trader"
version = "0.1.0"
dependencies = [
"actix",
"actix-rt",
"actix-web",
"async-std",
"futures",
"reqwest",
"serde",
"serde_json",
"tdapi",
"uuid",
]
[[package]]
@ -1590,7 +1890,8 @@ dependencies = [
"libc",
"memchr",
"mio",
"parking_lot",
"num_cpus",
"parking_lot 0.12.1",
"pin-project-lite",
"signal-hook-registry",
"socket2",
@ -1631,6 +1932,20 @@ dependencies = [
"tokio-stream",
]
[[package]]
name = "tokio-util"
version = "0.6.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"log",
"pin-project-lite",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.7.4"
@ -1728,6 +2043,27 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "uuid"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c"
dependencies = [
"getrandom",
"rand",
"serde",
]
[[package]]
name = "value-bag"
version = "1.0.0-alpha.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55"
dependencies = [
"ctor",
"version_check",
]
[[package]]
name = "vcpkg"
version = "0.2.15"
@ -1740,6 +2076,12 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "waker-fn"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
[[package]]
name = "want"
version = "0.3.0"
@ -1838,6 +2180,15 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "wepoll-ffi"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb"
dependencies = [
"cc",
]
[[package]]
name = "winapi"
version = "0.3.9"

@ -11,4 +11,8 @@ serde = "1.0.152"
serde_json = "1.0.91"
reqwest = "0.11.13"
futures = "0.3.25"
actix-web = "4"
actix-web = "4"
actix = "0.11.0"
actix-rt = "2.2" # <-- Runtime for actix
async-std = { version = "1.12.0", features = ["attributes", "tokio1"] }
uuid = {version= "1.2.2", features = ["serde", "fast-rng", "v4"]}

@ -6,9 +6,9 @@
# API
[ ] GET account IDs
[ ] GET open orders
[ ] POST new secret stop loss
[ ] POST cancel order
[X] GET open orders
[X] POST new secret stop loss
[X] POST cancel order
# DB
[ ] Store new account

@ -1,27 +1,137 @@
use errors::DynResult;
use futures::future::join;
use futures::{join, try_join};
use order::{MarketOrder, OffBookOrder};
use trade_mgmt::{OpenOffBookOrders, Position, get_account_ids, get_open_positions};
use tdapi::account::tda_account::ApiAccount;
use std::sync::{Arc,Mutex};
use std::time::{Duration, Instant};
use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder};
use async_std::task;
use futures::{
future::FutureExt, // for `.fuse()`
pin_mut,
select,
executor::block_on
};
use actix_rt::{spawn, time::interval};
mod trade_mgmt;
mod errors;
mod order;
#[actix_web::main]
async fn main() {
let TEST_ACT = "PNNX2GJXDTQNWY0SRCYGZMUHBFUUQHW7";
let TEST_CALLBACK_URI = "https://localhost";
#[actix_rt::main]
async fn main() -> std::io::Result<()>{
// We need to run a daemon that checks the open 'stop orders' every few seconds
// The orders need to be able to be sent to the loop from other treads
// We also need to communicate the deletion of orders
let mut tda = match ApiAccount::new(TEST_ACT, TEST_CALLBACK_URI) {
Ok(act) => act,
Err(e) => {println!("Failed to create TD act:\n{e:?}"); return;}
};
// This channel will be used to send order info the the daemon
//let (tx, rx) = mpsc::channel();
let act_nums = trade_mgmt::get_account_ids(&mut tda).await;
println!("act_nums = {:?}", act_nums);
let tda= web::Data::new(Mutex::new(ApiAccount::new("PNNX2GJXDTQNWY0SRCYGZMUHBFUUQHW7", "https://localhost").unwrap()));
let off_book_orders = web::Data::new(OpenOffBookOrders::new());
let main_act = 686092736;
// This works
let obo = off_book_orders.clone();
let tda_d = tda.clone();
let buy_order = order::MarketOrder::new("SPY", 300.0, 1.0, order::Direction::BUY);
println!("buy_order = {:?}", buy_order);
spawn(test(tda_d));
HttpServer::new(move || {
App::new()
.app_data(off_book_orders.clone())
.app_data(tda.clone())
.service(return_account_ids)
.service(open_off_book)
.service(add_ob_order)
.service(cancel_ob_order)
.route("/hey", web::get().to(manual_hello))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
let order_send = trade_mgmt::send_order(&mut tda, main_act, &buy_order).await;
println!("order_send = {:?}", order_send);
}
async fn api(off_book_orders: web::Data<OpenOffBookOrders>, tda_act: web::Data<Mutex<ApiAccount<'static>>>) -> std::io::Result<()> {
println!("Starting API..");
HttpServer::new(move || {
App::new()
.app_data(off_book_orders.clone())
.app_data(tda_act.clone())
.service(return_account_ids)
.service(open_off_book)
.service(add_ob_order)
.service(cancel_ob_order)
.route("/hey", web::get().to(manual_hello))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
#[get("/")]
async fn hello() -> impl Responder {
HttpResponse::Ok().body("Hello world!")
}
#[get("/openoffbook")]
async fn open_off_book(data: web::Data<OpenOffBookOrders>) -> impl Responder {
let mut open_off_book_orders = data.order_map.lock().unwrap();
let mut order_list = vec![];
for order in open_off_book_orders.values() {
order_list.push(serde_json::to_string(order).unwrap());
}
HttpResponse::Ok().body( serde_json::to_string(&order_list).unwrap())
}
#[get("/accountids")]
async fn return_account_ids<'a>(data: web::Data<Mutex<ApiAccount<'a>>>) -> impl Responder {
println!("HIT");
let mut tda = data.lock().unwrap();
let account_ids = get_account_ids(&mut tda).await.unwrap();
HttpResponse::Ok().body( serde_json::to_string(&account_ids).unwrap() )
}
#[post("/addorder/{target_price}")]
async fn add_ob_order(req_body: String, target_price: web::Path<f64>, data: web::Data<OpenOffBookOrders>) -> impl Responder {
let mut open_off_book_orders = data.order_map.lock().unwrap();
let position: Position = serde_json::from_str(&req_body).unwrap();
let new_order = OffBookOrder::from_position(position, target_price.into_inner());
open_off_book_orders.insert(new_order.get_uuid(), new_order);
HttpResponse::Ok().body( r#"{"success": true}"# )
}
#[post("/cancelorder/{uuid}")]
async fn cancel_ob_order(uuid: web::Path<u128>, data: web::Data<OpenOffBookOrders>) -> impl Responder {
let mut open_off_book_orders = data.order_map.lock().unwrap();
let removed = open_off_book_orders.remove(&uuid.into_inner()).is_some();
HttpResponse::Ok().body( if removed {r#"{"success": true}"#} else {r#"{"success": false}"#} )
}
#[post("/echo")]
async fn echo(req_body: String) -> impl Responder {
HttpResponse::Ok().body(req_body)
}
async fn manual_hello() -> impl Responder {
HttpResponse::Ok().body("Hey there!")
}
async fn test<'a>(data: web::Data::<Mutex<ApiAccount<'a>>>) {
let mut interval = interval(Duration::from_secs(10));
loop {
println!("Test");
{
let mut tda = data.lock().unwrap();
println!("Got mutex lock");
let act = get_account_ids(&mut tda);
println!("act = {:?}", act.await);
}
interval.tick().await;
}
}

@ -1,8 +1,11 @@
use serde::Deserialize;
use serde::Serialize;
use uuid::Uuid;
use tdapi::helpers::ToHashMap;
use crate::trade_mgmt::Position;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Direction {
BUY,
SELL
@ -15,6 +18,11 @@ impl Direction {
}
}
}
impl Default for Direction {
fn default() -> Self {
Self::BUY
}
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
@ -26,7 +34,7 @@ pub struct MarketOrder {
pub order_leg_collection: Vec<OrderLegCollection>,
}
impl MarketOrder {
pub fn new(symbol: &str, price: f64, quantity: f64, direction: Direction) -> Self {
pub fn new(symbol: &str, quantity: f64, direction: Direction) -> Self {
MarketOrder {
order_type: "MARKET".to_string(),
session: "SEAMLESS".to_string(),
@ -55,4 +63,50 @@ pub struct OrderLegCollection {
pub struct Instrument {
pub symbol: String,
pub asset_type: String,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OffBookOrder {
pub symbol: String,
pub quantity: f64,
pub asset_type: String,
pub direction: Direction,
pub target_price: f64,
uuid : u128
}
impl OffBookOrder {
pub fn new(symbol: String, quantity: f64, asset_type: String, direction: Direction, target_price: f64) -> Self {
let id = Uuid::new_v4().as_u128();
OffBookOrder { symbol: symbol, quantity: quantity, asset_type: asset_type, direction: direction, target_price: target_price, uuid: id }
}
pub fn from_position(open_position: Position, target_price: f64) -> Self {
let id = Uuid::new_v4().as_u128();
let mut quant = 0.0;
let mut dir = Direction::BUY;
let symbol = open_position.instrument.symbol;
let asset_type = open_position.instrument.asset_type;
match open_position.long_quantity > open_position.short_quantity {
true => {
quant = open_position.long_quantity;
let direction = Direction::SELL;
},
false => {
quant = open_position.short_quantity;
}
};
OffBookOrder {
symbol: symbol,
quantity: quant,
asset_type: asset_type,
direction: dir,
target_price: target_price,
uuid: id
}
}
pub fn get_uuid(&self) -> u128 {
self.uuid
}
}

@ -1,4 +1,6 @@
use std::collections::HashMap;
use actix_web::{web, App, HttpServer};
use std::sync::Mutex;
use serde::Deserialize;
use serde::Serialize;
use serde_json::Value;
@ -7,6 +9,17 @@ use tdapi::account::tda_account::ApiAccount;
use tdapi::helpers::ToHashMap;
use crate::errors::{DynResult};
use crate::order::MarketOrder;
use crate::order::OffBookOrder;
pub struct OpenOffBookOrders {
pub order_map: Mutex<HashMap<u128, OffBookOrder>>
}
impl OpenOffBookOrders {
pub fn new() -> Self {
OpenOffBookOrders { order_map: Mutex::new(HashMap::new()) }
}
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
@ -59,15 +72,26 @@ pub struct OpenOrderDetails {
pub order_id: u64
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AccountId{
id: u32,
value: f64
}
impl AccountId {
pub fn new(id: u32, value: f64) -> Self {
AccountId { id: id, value: value }
}
}
/// Returns current TD account ID's along with their current liquidation values
pub async fn get_account_ids<'a>( td_act: &mut ApiAccount<'a>) -> DynResult<Vec<(u32,f64)>>{
pub async fn get_account_ids<'a>( td_act: &mut ApiAccount<'a>) -> DynResult<Vec<AccountId>>{
let sec_acts = td_act.get_accounts().await?;
let mut act_nums = vec![];
for act in sec_acts {
act_nums.push( (act.account_id.parse::<u32>()?, act.current_balances.liquidation_value))
act_nums.push( AccountId::new(act.account_id.parse::<u32>()?, act.current_balances.liquidation_value))
}
Ok(act_nums)

Loading…
Cancel
Save