Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update targets #33

Merged
merged 4 commits into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions alpaca-broker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use std::error::Error;
mod cancel_trade;
mod close_trade;
mod keys;
mod modify_trade;
mod modify_stop;
mod modify_target;
mod order_mapper;
mod submit_trade;
mod sync_trade;
Expand Down Expand Up @@ -50,7 +51,16 @@ impl Broker for AlpacaBroker {
account: &Account,
new_stop_price: rust_decimal::Decimal,
) -> Result<BrokerLog, Box<dyn Error>> {
modify_trade::modify_stop(trade, account, new_stop_price)
modify_stop::modify(trade, account, new_stop_price)
}

fn modify_target(
&self,
trade: &Trade,
account: &Account,
new_target_price: rust_decimal::Decimal,
) -> Result<BrokerLog, Box<dyn Error>> {
modify_target::modify(trade, account, new_target_price)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::{error::Error, str::FromStr};
use tokio::runtime::Runtime;
use uuid::Uuid;

pub fn modify_stop(
pub fn modify(
trade: &Trade,
account: &Account,
price: Decimal,
Expand All @@ -20,7 +20,7 @@ pub fn modify_stop(
let client = Client::new(api_info);

// Modify the stop order.
let alpaca_order = Runtime::new().unwrap().block_on(modify_entry(
let alpaca_order = Runtime::new().unwrap().block_on(submit(
&client,
trade.safety_stop.broker_order_id.unwrap(),
price,
Expand All @@ -36,11 +36,7 @@ pub fn modify_stop(
Ok(log)
}

async fn modify_entry(
client: &Client,
order_id: Uuid,
price: Decimal,
) -> Result<Order, Box<dyn Error>> {
async fn submit(client: &Client, order_id: Uuid, price: Decimal) -> Result<Order, Box<dyn Error>> {
let request = ChangeReqInit {
stop_price: Some(Num::from_str(price.to_string().as_str()).unwrap()),
..Default::default()
Expand Down
54 changes: 54 additions & 0 deletions alpaca-broker/src/modify_target.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use crate::keys;
use apca::api::v2::order::{ChangeReqInit, Id, Order, Patch};
use apca::Client;
use model::BrokerLog;
use model::{Account, Trade};
use num_decimal::Num;
use rust_decimal::Decimal;
use std::{error::Error, str::FromStr};
use tokio::runtime::Runtime;
use uuid::Uuid;

pub fn modify(
trade: &Trade,
account: &Account,
price: Decimal,
) -> Result<BrokerLog, Box<dyn Error>> {
assert!(trade.account_id == account.id); // Verify that the trade is for the account

let api_info = keys::read_api_key(&account.environment, account)?;
let client = Client::new(api_info);

// Modify the stop order.
let alpaca_order = Runtime::new().unwrap().block_on(submit(
&client,
trade.target.broker_order_id.unwrap(),
price,
))?;

// 3. Log the Alpaca order.
let log = BrokerLog {
trade_id: trade.id,
log: serde_json::to_string(&alpaca_order)?,
..Default::default()
};

Ok(log)
}

async fn submit(client: &Client, order_id: Uuid, price: Decimal) -> Result<Order, Box<dyn Error>> {
let request = ChangeReqInit {
limit_price: Some(Num::from_str(price.to_string().as_str()).unwrap()),
..Default::default()
}
.init();

let result = client.issue::<Patch>(&(Id(order_id), request)).await;
match result {
Ok(log) => Ok(log),
Err(e) => {
eprintln!("Error modify stop: {:?}", e);
Err(Box::new(e))
}
}
}
7 changes: 7 additions & 0 deletions cli/src/commands/trade_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ impl TradeCommandBuilder {
self
}

pub fn modify_target(mut self) -> Self {
self.subcommands.push(
Command::new("modify-target").about("Modify the target order of a filled trade."),
);
self
}

pub fn manually_target(mut self) -> Self {
self.subcommands
.push(Command::new("manually-target").about("Execute manually the target of a trade"));
Expand Down
4 changes: 2 additions & 2 deletions cli/src/dialogs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod account_dialog;
mod keys_dialog;
mod modify_stop_dialog;
mod modify_dialog;
mod rule_dialog;
mod trade_cancel_dialog;
mod trade_close_dialog;
Expand All @@ -19,7 +19,7 @@ pub use account_dialog::AccountSearchDialog;
pub use keys_dialog::KeysDeleteDialogBuilder;
pub use keys_dialog::KeysReadDialogBuilder;
pub use keys_dialog::KeysWriteDialogBuilder;
pub use modify_stop_dialog::ModifyStopDialogBuilder;
pub use modify_dialog::ModifyDialogBuilder;
pub use rule_dialog::RuleDialogBuilder;
pub use rule_dialog::RuleRemoveDialogBuilder;
pub use trade_cancel_dialog::CancelDialogBuilder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,26 @@ use model::{Account, BrokerLog, Status, Trade};
use rust_decimal::Decimal;
use std::error::Error;

type ModifyStopDialogBuilderResult = Option<Result<(Trade, BrokerLog), Box<dyn Error>>>;
type ModifyDialogBuilderResult = Option<Result<(Trade, BrokerLog), Box<dyn Error>>>;

pub struct ModifyStopDialogBuilder {
pub struct ModifyDialogBuilder {
account: Option<Account>,
trade: Option<Trade>,
new_stop_price: Option<Decimal>,
result: ModifyStopDialogBuilderResult,
new_price: Option<Decimal>,
result: ModifyDialogBuilderResult,
}

impl ModifyStopDialogBuilder {
impl ModifyDialogBuilder {
pub fn new() -> Self {
ModifyStopDialogBuilder {
ModifyDialogBuilder {
account: None,
trade: None,
new_stop_price: None,
new_price: None,
result: None,
}
}

pub fn build(mut self, trust: &mut TrustFacade) -> ModifyStopDialogBuilder {
pub fn build_stop(mut self, trust: &mut TrustFacade) -> ModifyDialogBuilder {
let trade = self
.trade
.clone()
Expand All @@ -36,7 +36,7 @@ impl ModifyStopDialogBuilder {
.clone()
.expect("No account found, did you forget to call account?");
let stop_price = self
.new_stop_price
.new_price
.expect("No stop price found, did you forget to call stop_price?");

match trust.modify_stop(&trade, &account, stop_price) {
Expand All @@ -46,20 +46,44 @@ impl ModifyStopDialogBuilder {
self
}

pub fn build_target(mut self, trust: &mut TrustFacade) -> ModifyDialogBuilder {
let trade = self
.trade
.clone()
.expect("No trade found, did you forget to call search?");

let account = self
.account
.clone()
.expect("No account found, did you forget to call account?");
let target_price = self
.new_price
.expect("No target price found, did you forget to call stop_price?");

match trust.modify_target(&trade, &account, target_price) {
Ok((trade, log)) => self.result = Some(Ok((trade, log))),
Err(error) => self.result = Some(Err(error)),
}
self
}

pub fn display(self) {
match self
.result
.expect("No result found, did you forget to call search?")
{
Ok((trade, log)) => {
println!("Trade stop updated:");
println!("Trade updated:");
TradeView::display(&trade, &self.account.unwrap().name);

TradeOverviewView::display(&trade.overview);

println!("Stop updated:");
println!("Stop:");
OrderView::display(trade.safety_stop);

println!("Target:");
OrderView::display(trade.target);

LogView::display(&log);
}
Err(error) => println!("Error submitting trade: {:?}", error),
Expand Down Expand Up @@ -101,12 +125,9 @@ impl ModifyStopDialogBuilder {
self
}

pub fn stop_price(mut self) -> Self {
let stop_price = Input::new()
.with_prompt("New stop price")
.interact()
.unwrap();
self.new_stop_price = Some(stop_price);
pub fn new_price(mut self) -> Self {
let stop_price = Input::new().with_prompt("New price").interact().unwrap();
self.new_price = Some(stop_price);
self
}
}
18 changes: 14 additions & 4 deletions cli/src/dispatcher.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::dialogs::{
AccountDialogBuilder, AccountSearchDialog, CancelDialogBuilder, CloseDialogBuilder,
ExitDialogBuilder, FillTradeDialogBuilder, FundingDialogBuilder, KeysDeleteDialogBuilder,
KeysReadDialogBuilder, KeysWriteDialogBuilder, ModifyStopDialogBuilder, SubmitDialogBuilder,
KeysReadDialogBuilder, KeysWriteDialogBuilder, ModifyDialogBuilder, SubmitDialogBuilder,
SyncTradeDialogBuilder, TradeDialogBuilder, TradeSearchDialogBuilder,
TradingVehicleDialogBuilder, TradingVehicleSearchDialogBuilder, TransactionDialogBuilder,
};
Expand Down Expand Up @@ -79,6 +79,7 @@ impl ArgDispatcher {
Some(("sync", _)) => self.create_sync(),
Some(("search", _)) => self.search_trade(),
Some(("modify-stop", _)) => self.modify_stop(),
Some(("modify-target", _)) => self.modify_target(),
_ => unreachable!("No subcommand provided"),
},
Some((ext, sub_matches)) => {
Expand Down Expand Up @@ -269,11 +270,20 @@ impl ArgDispatcher {
}

fn modify_stop(&mut self) {
ModifyStopDialogBuilder::new()
ModifyDialogBuilder::new()
.account(&mut self.trust)
.search(&mut self.trust)
.stop_price()
.build(&mut self.trust)
.new_price()
.build_stop(&mut self.trust)
.display();
}

fn modify_target(&mut self) {
ModifyDialogBuilder::new()
.account(&mut self.trust)
.search(&mut self.trust)
.new_price()
.build_target(&mut self.trust)
.display();
}
}
Expand Down
1 change: 1 addition & 0 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ fn main() {
.manually_target()
.manually_close()
.modify_stop()
.modify_target()
.build(),
)
.get_matches();
Expand Down
14 changes: 14 additions & 0 deletions cli/tests/integration_test_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,18 @@ impl Broker for MockBroker {
new_stop_price
)
}

fn modify_target(
&self,
trade: &Trade,
account: &Account,
new_target_price: rust_decimal::Decimal,
) -> Result<BrokerLog, Box<dyn Error>> {
unimplemented!(
"Modify target: {:?} {:?} {:?}",
trade,
account,
new_target_price
)
}
}
14 changes: 14 additions & 0 deletions cli/tests/integration_test_cancel_trade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,18 @@ impl Broker for MockBroker {
new_stop_price
)
}

fn modify_target(
&self,
trade: &Trade,
account: &Account,
new_target_price: rust_decimal::Decimal,
) -> Result<BrokerLog, Box<dyn Error>> {
unimplemented!(
"Modify target: {:?} {:?} {:?}",
trade,
account,
new_target_price
)
}
}
Loading