Overhauled data module to revolve around traits rather than standardized models | Added timeseries/candle struct and traits
parent
1ae5eb25db
commit
4fb67445a9
@ -1,11 +1,32 @@ |
||||
mod equity; |
||||
mod crypto; |
||||
mod options; |
||||
mod price_history; |
||||
mod data_service; |
||||
|
||||
pub enum AssetDataObject { |
||||
Equity(equity::Equity), |
||||
Crypro(crypto::Crypto), |
||||
OptionContract(options::OptionContract), |
||||
pub mod quotes; |
||||
pub mod options; |
||||
pub mod timeseries; |
||||
|
||||
use chrono::{DateTime, Utc}; |
||||
use super::DynResult; |
||||
|
||||
|
||||
pub trait TimeStamp { |
||||
fn timestamp(&self) -> DateTime<Utc>; |
||||
} |
||||
pub trait Volume { |
||||
fn volume(&self) -> Option<u64>; |
||||
} |
||||
|
||||
pub fn to_datetime(timestamp: i64) { |
||||
|
||||
} |
||||
|
||||
pub enum Period { |
||||
Second, |
||||
Minute, |
||||
Hour, |
||||
Day, |
||||
TradeDay, |
||||
Week, |
||||
TradeWeek, |
||||
Month, |
||||
Year, |
||||
Ytd, |
||||
AssetLife |
||||
} |
||||
@ -1,49 +0,0 @@ |
||||
use std::fmt::Display; |
||||
use crate::DynResult; |
||||
|
||||
#[derive(Debug)] |
||||
pub struct CryptoError { |
||||
_error: String |
||||
} |
||||
impl CryptoError { |
||||
pub fn new(error_msg: &str) -> Self { |
||||
CryptoError { _error: error_msg.to_owned() } |
||||
} |
||||
} |
||||
impl Display for CryptoError { |
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
||||
write!(f, "Crypto Error Placeholder") |
||||
} |
||||
} |
||||
impl std::error::Error for CryptoError {} |
||||
|
||||
#[derive(Debug)] |
||||
pub struct Crypto { |
||||
pub symbol: String, |
||||
pub exchange: Option<String>, |
||||
pub base_crypto: String, // being purchased (top)
|
||||
pub quote_crypto: String, |
||||
pub bid: f64, |
||||
pub mid: f64, |
||||
pub ask: f64, |
||||
pub last: Option<f64>, |
||||
pub bid_size: Option<usize>, |
||||
pub ask_size: Option<usize>, |
||||
pub volume: Option<usize>, |
||||
pub high: Option<f64>, |
||||
pub open: Option<f64>, |
||||
pub low: Option<f64>, |
||||
pub close: Option<f64>, |
||||
pub marginable: Option<bool>, |
||||
pub quote_time: i64 |
||||
} |
||||
impl Crypto { |
||||
|
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
pub trait ToCrypto { |
||||
fn to_crypto(&self) -> DynResult<Crypto>; |
||||
} |
||||
@ -1,58 +0,0 @@ |
||||
use crate::data::*; |
||||
use crate::DynResult; |
||||
|
||||
/* |
||||
A data service must implement at lease one of the following traits |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Important to note that Paramaters can be typed as Option<P> during implemenation |
||||
and that the actual strucut/type passed into these is flexable. This should allow |
||||
each services library to implement a paramates trait that works for them, or
|
||||
leave paramaters as 'None' |
||||
|
||||
This way you can lock down what paramaters are required for each indiviudual service |
||||
while still allowing the RustyTrade framework to reliably obtain the expected struct |
||||
from each trait interface. |
||||
|
||||
struct ExamplePriceHistoryParams { |
||||
start_date: i64, |
||||
end_date: i64 |
||||
} |
||||
|
||||
struct ExampleDataService {}; |
||||
impl GetPriceHistory for ExampleDataService { |
||||
type Paramaters = ExamplePriceHistoryParmas; |
||||
fn get_price_history(&mut self, paramaters: Self::Paramaters)-> DynResult<PriceHistory> { |
||||
|
||||
}
|
||||
} |
||||
|
||||
*/ |
||||
pub trait GetEquity { |
||||
type Paramaters; |
||||
fn get_equity(&mut self, paramaters: Self::Paramaters) -> DynResult<equity::Equity>; |
||||
} |
||||
pub trait GetCrypto { |
||||
type Paramaters; |
||||
fn get_crypto(&mut self, paramaters: Self::Paramaters) -> DynResult<crypto::Crypto>; |
||||
} |
||||
pub trait GetOptionContract { |
||||
type Paramaters; |
||||
fn get_option_contract(&mut self, paramaters: Self::Paramaters) -> DynResult<options::OptionContract>; |
||||
} |
||||
pub trait GetOptionChain { |
||||
type Paramaters; |
||||
fn get_options_chain_vec(&mut self, paramaters: Self::Paramaters) -> DynResult<Vec<options::OptionContract>>; |
||||
fn get_options_chain_dataframe(&mut self, paramaters: Self::Paramaters) -> DynResult<options::OptionChainDataFrame>; |
||||
} |
||||
pub trait GetPriceHistory{ |
||||
type Paramaters; |
||||
fn get_price_history(&mut self, paramaters: Self::Paramaters)-> DynResult<price_history::PriceHistory>; |
||||
} |
||||
|
||||
@ -1,51 +0,0 @@ |
||||
use std::fmt::Display; |
||||
use crate::DynResult; |
||||
|
||||
#[derive(Debug)] |
||||
pub struct EquityError { |
||||
error: String |
||||
} |
||||
impl EquityError { |
||||
pub fn new(error_msg: &str) -> Self { |
||||
EquityError { error: error_msg.to_owned() } |
||||
} |
||||
} |
||||
impl Display for EquityError { |
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
||||
write!(f, "Equity Error Placeholder") |
||||
} |
||||
} |
||||
impl std::error::Error for EquityError {} |
||||
|
||||
#[derive(Debug)] |
||||
pub struct Equity { |
||||
pub symbol: String, |
||||
pub cusip : Option<String>, |
||||
pub exchange: Option<String>, |
||||
pub bid: f64, |
||||
pub mid: f64, |
||||
pub ask: f64, |
||||
pub last: Option<f64>, |
||||
pub bid_size: Option<usize>, |
||||
pub ask_size: Option<usize>, |
||||
pub volume: Option<usize>, |
||||
pub high: Option<f64>, |
||||
pub open: Option<f64>, |
||||
pub low: Option<f64>, |
||||
pub close: Option<f64>, |
||||
pub shortable: Option<bool>, |
||||
pub marginable: Option<bool>, |
||||
pub quote_time: i64 |
||||
} |
||||
impl Equity { |
||||
|
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
pub trait ToEquity { |
||||
fn to_equity(&self) -> DynResult<Equity>; |
||||
} |
||||
@ -1,56 +0,0 @@ |
||||
use polars::{prelude::DataFrame, df, prelude::{NamedFrom}}; |
||||
|
||||
use crate::DynResult; |
||||
|
||||
|
||||
|
||||
pub struct Candle { |
||||
pub high: f64, |
||||
pub open: f64, |
||||
pub low: f64, |
||||
pub close: f64, |
||||
pub volume: Option<u64>, |
||||
pub timestamp: i64 // mls since epoch
|
||||
} |
||||
impl Candle { |
||||
pub fn new(high: f64, open: f64, low: f64, close: f64, volume: Option<u64>, timestamp: i64) -> Self { |
||||
Candle { high, open, low, close, volume, timestamp } |
||||
} |
||||
} |
||||
|
||||
pub struct PriceHistory { |
||||
symbol: String, |
||||
candles: Vec<Candle> |
||||
} |
||||
|
||||
pub trait ToPriceHistory { |
||||
fn to_pricehistorty(&self) -> DynResult<PriceHistory>; |
||||
} |
||||
|
||||
pub fn create_timeseries_dataframe(timeseries_data: &Vec<Candle>) -> DynResult<DataFrame> { |
||||
let mut high = vec![]; |
||||
let mut open = vec![]; |
||||
let mut low = vec![]; |
||||
let mut close = vec![]; |
||||
let mut volume = vec![]; |
||||
let mut timestamp = vec![]; |
||||
|
||||
for candle in timeseries_data { |
||||
high.push(candle.high); |
||||
open.push(candle.open); |
||||
low.push(candle.low); |
||||
close.push(candle.close); |
||||
volume.push(candle.volume); |
||||
timestamp.push(candle.timestamp); |
||||
} |
||||
|
||||
Ok(df!( |
||||
"High" => &high, |
||||
"Open" => &open, |
||||
"Low" => &low, |
||||
"Close"=> &close, |
||||
"Volume"=> &volume, |
||||
"TimeStamp" => ×tamp |
||||
)?) |
||||
|
||||
} |
||||
@ -0,0 +1,60 @@ |
||||
use chrono::{Utc, DateTime}; |
||||
use super::Period; |
||||
use super::options::OptionKind; |
||||
|
||||
pub enum AssetIdentifier{ |
||||
Ticker(String), |
||||
Cusip(String), |
||||
Other(String) |
||||
} |
||||
|
||||
|
||||
///Information about what this quote it, where it came from and when
|
||||
///
|
||||
pub trait QuoteData { |
||||
/// Gives the symbol/ticker/cusip of this asset
|
||||
fn asset_symbol(&self) -> AssetIdentifier; |
||||
/// Gives the timestamp of when the quote data is valid
|
||||
fn quote_time(&self) -> DateTime<Utc>; |
||||
/// Gives the timestamp of when the quote was created
|
||||
fn retrieve_time(&self) ->DateTime<Utc>; |
||||
/// Gives the exchange which the data was sources from
|
||||
fn exchange(&self) -> Option<String>; |
||||
// TO DO: Gives the datasource used
|
||||
} |
||||
///Standard volume information
|
||||
///
|
||||
pub trait VolumeData { |
||||
/// Gives the period over which this volume is valid
|
||||
fn volume_period(&self) -> Period; |
||||
/// Total volume seem in that period
|
||||
fn total_volume(&self) -> u64; |
||||
/// Gives the current bid size of the asset
|
||||
fn bid_size(&self) -> u64; |
||||
// Gives the current as size of the asset
|
||||
fn ask_size(&self) -> u64; |
||||
// Gives the size of the last trade
|
||||
fn last_size(&self) -> Option<u64>; |
||||
} |
||||
///Standard information about price spread
|
||||
///
|
||||
pub trait PriceSpreadData { |
||||
/// Give the bid price of an asset
|
||||
fn bid(&self) -> f64; |
||||
/// Gives the mid price of an asset
|
||||
fn mid(&self) -> f64; |
||||
/// Gives the ask price of an asset
|
||||
fn ask(&self) -> f64; |
||||
} |
||||
pub trait Marginable { |
||||
/// Gives the margin cost as a yearly interest cost. Returns none if not marginable
|
||||
fn margin_cost(&self) -> Option<f64>; |
||||
/// Returns true if we can use margin on this instrument
|
||||
fn is_marginable(&self) -> bool; |
||||
} |
||||
|
||||
|
||||
pub trait CryptoData { |
||||
fn base_crypto(&self) -> String; |
||||
fn quote_crypto(&self) -> String; |
||||
} |
||||
@ -0,0 +1,78 @@ |
||||
use chrono::{DateTime, Utc}; |
||||
use super::{Volume, TimeStamp, DynResult}; |
||||
use polars::{prelude::DataFrame, df, prelude::{NamedFrom}}; |
||||
|
||||
|
||||
pub struct Candle { |
||||
pub high: f64, |
||||
pub open: f64, |
||||
pub low: f64, |
||||
pub close: f64, |
||||
pub volume: Option<u64>, |
||||
pub timestamp: DateTime<Utc> |
||||
} |
||||
impl Candle { |
||||
fn from<SourceData>(data: SourceData) -> Self |
||||
where SourceData: HOLC + TimeStamp + Volume { |
||||
Candle { high: data.high(), |
||||
open: data.open(),
|
||||
low: data.low(),
|
||||
close: data.close(),
|
||||
volume: data.volume(),
|
||||
timestamp: data.timestamp(),
|
||||
} |
||||
} |
||||
} |
||||
|
||||
pub trait HOLC { |
||||
fn high(&self) -> f64; |
||||
fn open(&self) -> f64; |
||||
fn low(&self) -> f64; |
||||
fn close(&self) -> f64; |
||||
} |
||||
|
||||
pub struct TimeSeries { |
||||
candles: Vec<Candle> |
||||
} |
||||
impl TimeSeries { |
||||
fn new(candles: Vec<Candle>) -> Self { |
||||
TimeSeries { candles: candles } |
||||
} |
||||
fn from<C>(data: Vec<C>) -> Self |
||||
where C: HOLC + TimeStamp + Volume |
||||
{ |
||||
let mut candles: Vec<Candle> = Vec::new(); |
||||
for d in data { |
||||
candles.push(Candle::from(d)) |
||||
} |
||||
TimeSeries::new(candles) |
||||
} |
||||
} |
||||
|
||||
pub fn create_timeseries_dataframe(timeseries_data: &Vec<Candle>) -> DynResult<DataFrame> { |
||||
let mut high = vec![]; |
||||
let mut open = vec![]; |
||||
let mut low = vec![]; |
||||
let mut close = vec![]; |
||||
let mut volume = vec![]; |
||||
let mut timestamp = vec![]; |
||||
|
||||
for candle in timeseries_data { |
||||
high.push(candle.high); |
||||
open.push(candle.open); |
||||
low.push(candle.low); |
||||
close.push(candle.close); |
||||
volume.push(candle.volume); |
||||
timestamp.push(candle.timestamp.timestamp_millis()); |
||||
} |
||||
|
||||
Ok(df!( |
||||
"High" => &high, |
||||
"Open" => &open, |
||||
"Low" => &low, |
||||
"Close"=> &close, |
||||
"Volume"=> &volume, |
||||
"TimeStamp" => ×tamp |
||||
)?) |
||||
|
||||
} |
||||
@ -1,47 +0,0 @@ |
||||
use crate::data::AssetDataObject; |
||||
|
||||
|
||||
pub enum Direction { |
||||
Buy, |
||||
Sell |
||||
} |
||||
impl ToString for Direction { |
||||
fn to_string(&self) -> String { |
||||
match &self { |
||||
Self::Buy => "Buy".to_string(), |
||||
Self::Sell => "Sell".to_string() |
||||
} |
||||
} |
||||
} |
||||
|
||||
pub enum OrderType { |
||||
Market, |
||||
Limit, |
||||
Stop, |
||||
TrailingStop |
||||
}
|
||||
impl ToString for OrderType { |
||||
fn to_string(&self) -> String { |
||||
match &self { |
||||
Self::Market => "Market".to_string(), |
||||
Self::Limit => "Limit".to_string(), |
||||
Self::Stop => "Stop".to_string(), |
||||
Self::TrailingStop => "TrailingStop".to_string() |
||||
} |
||||
} |
||||
} |
||||
|
||||
pub struct SimpleOrder { |
||||
pub asset: AssetDataObject, |
||||
pub price_to_pay: f64, |
||||
pub direction: Direction, |
||||
pub order_type: OrderType, |
||||
pub good_until: i64, |
||||
pub approved: bool |
||||
} |
||||
|
||||
pub struct CompoundOrder { |
||||
pub orders: Vec<SimpleOrder>, |
||||
pub approved: bool |
||||
|
||||
} |
||||
Loading…
Reference in new issue