parent
e3dbe48ee8
commit
42e4597117
@ -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; |
||||
} |
||||
} |
||||
Loading…
Reference in new issue