Skip to content

Commit

Permalink
remove unused code
Browse files Browse the repository at this point in the history
  • Loading branch information
ryqdev committed Jun 1, 2024
1 parent 336edd4 commit 75640a4
Show file tree
Hide file tree
Showing 13 changed files with 146 additions and 112 deletions.
4 changes: 4 additions & 0 deletions src/broker/alpaca/alpaca.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ const BASE_URL: &str = "wss://stream.data.alpaca.markets/v2/test";
fn main() {
let (mut socket, response) = connect(Url::parse(BASE_URL).unwrap()).expect("Can't connect");
println!("{:#?}", response);
}

pub async fn alpaca_trading() {
log::info!("trade with alpaca")
}
2 changes: 1 addition & 1 deletion src/broker/alpaca/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
mod alpaca;
pub mod alpaca;
1 change: 0 additions & 1 deletion src/broker/ibkr/live.rs

This file was deleted.

2 changes: 1 addition & 1 deletion src/broker/ibkr/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
mod live;
pub mod trade;
100 changes: 100 additions & 0 deletions src/broker/ibkr/trade.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
pub struct PaperTradingCommand;

use std::collections::VecDeque;

use ibapi::contracts::{Contract, SecurityType};
use ibapi::market_data::realtime::{BarSize, Bar, WhatToShow};
use ibapi::orders::{order_builder, Action, OrderNotification};
use ibapi::Client;

struct BreakoutChannel {
ticks: VecDeque<(f64, f64)>,
size: usize,
}

impl BreakoutChannel {
fn new(size: usize) -> BreakoutChannel {
BreakoutChannel {
ticks: VecDeque::with_capacity(size + 1),
size,
}
}

fn ready(&self) -> bool {
self.ticks.len() >= self.size
}

fn add_bar(&mut self, bar: &Bar) {
self.ticks.push_back((bar.high, bar.low));

if self.ticks.len() > self.size {
self.ticks.pop_front();
}
}

fn high(&self) -> f64 {
self.ticks.iter().map(|x| x.0).max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap()
}

fn low(&self) -> f64 {
self.ticks.iter().map(|x| x.1).max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap()
}
}

pub async fn ibkr_trading(){
log::info!("trade with ibkr");

let client = Client::connect("127.0.0.1:7497", 100).unwrap();

// let contract = Contract {
// symbol: "TSLA".to_string(),
// security_type: SecurityType::Stock,
// currency: "USD".to_string(),
// exchange: "SMART".to_string(),
// ..Default::default()
// };


let contract = Contract {
symbol: "USD".to_owned(),
security_type: SecurityType::ForexPair,
currency: "JPY".to_owned(),
exchange: "IDEALPRO".to_owned(),
..Default::default()
};

log::info!("{:?}", contract);

let bars = client.realtime_bars(&contract, BarSize::Sec5, WhatToShow::MidPoint, false).unwrap();
let mut channel = BreakoutChannel::new(30);
for bar in bars {
log::info!("\x1b[93m bar:\x1b[0m {:?} ", bar);
channel.add_bar(&bar);

// Ensure enough bars and no open positions.
if !channel.ready() {
continue;
}

let action = if bar.close > channel.high() {
Action::Sell
} else if bar.close < channel.low() {
Action::Buy
} else {
continue;
};

let order_id = client.next_order_id();
let order = order_builder::market_order(action, 1000.0);

let notices = client.place_order(order_id, &contract, &order).unwrap();
for notice in notices {
if let OrderNotification::ExecutionData(data) = notice {
println!("{} {} shares of {}", data.execution.side, data.execution.shares, data.contract.symbol);
} else {
println!("{:?}", notice);
}
}
}

}
2 changes: 1 addition & 1 deletion src/broker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ pub trait Broker{
fn set_cash(&mut self, cash: f64);
}

mod alpaca;
pub(crate) mod alpaca;
pub(crate) mod ibkr;
pub mod backtest;
4 changes: 1 addition & 3 deletions src/cmds/backtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ use clap::{Arg, ArgMatches, Command as ClapCommand};
use async_trait::async_trait;
pub struct BackTestCommand;
use crate::strategy::strategy::BaseStrategy;
use crate::feeds::Bar;
use crate::broker::backtest::backtest::BacktestBroker;

#[async_trait]
impl Command for BackTestCommand {
Expand All @@ -29,7 +27,7 @@ impl Command for BackTestCommand {
BackTestGolden::new()
.set_broker(100_000.0)
.set_data_feed(symbol)
.set_strategy(BaseStrategy{ name: "test".to_string() })
.set_strategy(BaseStrategy{})
.run()
.set_analyzer()
.plot();
Expand Down
2 changes: 1 addition & 1 deletion src/cmds/live.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ impl Command for LiveTradingCommand {
.visible_alias("l")
}

async fn handler(m: &ArgMatches) -> anyhow::Result<()> {
async fn handler(_m: &ArgMatches) -> anyhow::Result<()> {
log::info!("handle live trading");
Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion src/cmds/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ impl Golden for BackTestGolden {
eframe::run_native(
&format!("backtest {:?}", self.strategy),
native_options,
Box::new(|cc| Box::new(visualization::vis::App{
Box::new(|_| Box::new(visualization::vis::App{
candle_data,
cash_data,
net_assets_data,
Expand Down
131 changes: 33 additions & 98 deletions src/cmds/paper.rs
Original file line number Diff line number Diff line change
@@ -1,106 +1,28 @@
use async_trait::async_trait;
use clap::{ArgMatches, Command as ClapCommand};
use clap::{Arg, ArgMatches, Command as ClapCommand};
use crate::cmds::Command;

pub struct PaperTradingCommand;

use std::collections::VecDeque;
use crate::broker::{
ibkr::trade::ibkr_trading,
alpaca::alpaca::alpaca_trading
};
use anyhow::Result;

use ibapi::contracts::{Contract, SecurityType};
use ibapi::market_data::realtime::{BarSize, Bar, WhatToShow};
use ibapi::orders::{order_builder, Action, OrderNotification};
use ibapi::Client;

struct BreakoutChannel {
ticks: VecDeque<(f64, f64)>,
size: usize,
enum BrokerType {
IBKR,
ALPACA
}

impl BreakoutChannel {
fn new(size: usize) -> BreakoutChannel {
BreakoutChannel {
ticks: VecDeque::with_capacity(size + 1),
size,
}
}

fn ready(&self) -> bool {
self.ticks.len() >= self.size
}

fn add_bar(&mut self, bar: &Bar) {
self.ticks.push_back((bar.high, bar.low));

if self.ticks.len() > self.size {
self.ticks.pop_front();
impl BrokerType {
fn from_str(s: &str) -> Option<Self> {
match s.to_uppercase().as_str() {
"IBKR" => Option::from(BrokerType::IBKR),
"ALPACA" => Option::from(BrokerType::ALPACA),
_ => None
}
}

fn high(&self) -> f64 {
self.ticks.iter().map(|x| x.0).max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap()
}

fn low(&self) -> f64 {
self.ticks.iter().map(|x| x.1).max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap()
}
}

async fn paper_trading(){
log::info!("Paper trading...");

let client = Client::connect("127.0.0.1:7497", 100).unwrap();

// let contract = Contract {
// symbol: "TSLA".to_string(),
// security_type: SecurityType::Stock,
// currency: "USD".to_string(),
// exchange: "SMART".to_string(),
// ..Default::default()
// };


let contract = Contract {
symbol: "USD".to_owned(),
security_type: SecurityType::ForexPair,
currency: "JPY".to_owned(),
exchange: "IDEALPRO".to_owned(),
..Default::default()
};

log::info!("{:?}", contract);

let bars = client.realtime_bars(&contract, BarSize::Sec5, WhatToShow::MidPoint, false).unwrap();
let mut channel = BreakoutChannel::new(30);
for bar in bars {
log::info!("\x1b[93m bar:\x1b[0m {:?} ", bar);
channel.add_bar(&bar);

// Ensure enough bars and no open positions.
if !channel.ready() {
continue;
}

let action = if bar.close > channel.high() {
Action::Sell
} else if bar.close < channel.low() {
Action::Buy
} else {
continue;
};

let order_id = client.next_order_id();
let order = order_builder::market_order(action, 1000.0);

let notices = client.place_order(order_id, &contract, &order).unwrap();
for notice in notices {
if let OrderNotification::ExecutionData(data) = notice {
println!("{} {} shares of {}", data.execution.side, data.execution.shares, data.contract.symbol);
} else {
println!("{:?}", notice);
}
}
}

}

#[async_trait]
Expand All @@ -109,11 +31,24 @@ impl Command for PaperTradingCommand {
ClapCommand::new("paper")
.about("Paper trading")
.visible_alias("p")
}

async fn handler(m: &ArgMatches) -> anyhow::Result<()> {
log::info!("handle paper trading");
paper_trading().await;
.arg(
Arg::new("broker")
.long("broker")
.value_parser(clap::value_parser!(String))
.help("broker")
.num_args(1),
)

}

async fn handler(m: &ArgMatches) -> Result<()> {
let broker = m.get_one::<String>("broker").unwrap();
log::info!("Paper trading on {broker}");
match BrokerType::from_str(broker) {
Some(BrokerType::IBKR) => ibkr_trading().await,
Some(BrokerType::ALPACA) => alpaca_trading().await,
_ => {}
};
Ok(())
}
}
2 changes: 1 addition & 1 deletion src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ pub enum GoldenColor {}
impl GoldenColor {
pub const RED: &'static str = "\x1b[41m";
pub const GREEN: &'static str = "\x1b[42m";
pub const YELLOW: &'static str = "\x1b[43m";
// pub const YELLOW: &'static str = "\x1b[43m";
pub const RESET: &'static str = "\x1b[0m";
}
4 changes: 1 addition & 3 deletions src/strategy/strategy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ use crate::broker::backtest::backtest::{
use crate::feeds::Bar;

#[derive(Debug,Default)]
pub struct BaseStrategy{
pub(crate) name: String,
}
pub struct BaseStrategy{}

impl BaseStrategy {
pub fn next(&self, data: &Bar) -> Order {
Expand Down
2 changes: 1 addition & 1 deletion src/visualization/vis.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use egui::{Stroke, Color32, ViewportClass};
use egui::{Stroke, Color32};
use egui_plot::{Plot, BoxPlot, BoxElem, BoxSpread, Legend, Line};
use crate::feeds::Bar;
use crate::broker::backtest::backtest::Order;
Expand Down

0 comments on commit 75640a4

Please sign in to comment.