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

VolumeWeightAdjustedPrice #66

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 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
3 changes: 2 additions & 1 deletion benches/indicators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use ta::indicators::{
ExponentialMovingAverage, FastStochastic, KeltnerChannel, Maximum, MeanAbsoluteDeviation,
Minimum, MoneyFlowIndex, MovingAverageConvergenceDivergence, OnBalanceVolume,
PercentagePriceOscillator, RateOfChange, RelativeStrengthIndex, SimpleMovingAverage,
SlowStochastic, StandardDeviation, TrueRange,
SlowStochastic, StandardDeviation, TrueRange, VolumeWeightAdjustedPrice,
};
use ta::{DataItem, Next};

Expand Down Expand Up @@ -65,6 +65,7 @@ bench_indicators!(
MoneyFlowIndex,
MovingAverageConvergenceDivergence,
OnBalanceVolume,
VolumeWeightAdjustedPrice,
PercentagePriceOscillator,
CommodityChannelIndex,
RateOfChange,
Expand Down
3 changes: 2 additions & 1 deletion src/data_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ mod tests {
// open, high, low , close, volume
(-1.0, 25.0, 15.0, 21.0, 7500.0),
(20.0, -1.0, 15.0, 21.0, 7500.0),
(20.0, 25.0, -1.0, 21.0, 7500.0),
//(20.0, 25.0, -1.0, 21.0, 7500.0),
brandonros marked this conversation as resolved.
Show resolved Hide resolved
(20.0, 25.0, 15.0, -1.0, 7500.0),
(20.0, 25.0, 15.0, 21.0, -1.0),
(14.9, 25.0, 15.0, 21.0, 7500.0),
Expand All @@ -199,6 +199,7 @@ mod tests {
(20.0, 15.0, 25.0, 21.0, 7500.0),
];
for record in invalid_records {
println!("{:?}", record);
assert_invalid(record)
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/indicators/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,6 @@ pub use self::money_flow_index::MoneyFlowIndex;

mod on_balance_volume;
pub use self::on_balance_volume::OnBalanceVolume;

mod volume_weight_adjusted_price;
pub use self::volume_weight_adjusted_price::VolumeWeightAdjustedPrice;
147 changes: 147 additions & 0 deletions src/indicators/volume_weight_adjusted_price.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
use std::fmt;

use crate::{Close, Next, Volume, Reset};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// Volume weight adjusted price (VWAP).
///
/// In finance, volume-weighted average price (VWAP) is the ratio of the value of a security or
/// financial asset traded to the total volume of transactions during a trading session.
/// It is a measure of the average trading price for the period.
///
/// # Formula
///
/// ![VWAP](https://wikimedia.org/api/rest_v1/media/math/render/svg/6c0a822a0a9e58a127105e818a07061a02851685)
///
/// Where:
///
/// vwap - volume weight adjusted price
///
/// # Example
///
/// ```
/// use ta::indicators::VolumeWeightAdjustedPrice;
/// use ta::{Next, DataItem};
///
/// let mut vwap = VolumeWeightAdjustedPrice::new();
///
/// let di1 = DataItem::builder()
/// .high(3.0)
/// .low(1.0)
/// .close(2.0)
/// .open(1.5)
/// .volume(1000.0)
/// .build().unwrap();
///
/// let di2 = DataItem::builder()
/// .high(3.0)
/// .low(1.0)
/// .close(1.5)
/// .open(1.5)
/// .volume(300.0)
/// .build().unwrap();
///
/// assert_eq!(vwap.next(&di1), 2.0);
/// assert_eq!(vwap.next(&di2), 1.8846153846153846);
/// ```
///
/// # Links
///
/// * [Volume weight adjusted price, Wikipedia](https://en.wikipedia.org/wiki/Volume-weighted_average_price)
///
#[doc(alias = "VWAP")]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
pub struct VolumeWeightAdjustedPrice {
cumulative_volume: f64,
cumulative_traded: f64,
vwap: f64
}

impl VolumeWeightAdjustedPrice {
pub fn new() -> Self {
Self {
cumulative_volume: 0.0,
cumulative_traded: 0.0,
vwap: 0.0
}
}
}

impl<T: Close + Volume> Next<&T> for VolumeWeightAdjustedPrice {
type Output = f64;

fn next(&mut self, input: &T) -> f64 {
let price = input.close();
let volume = input.volume();
self.cumulative_volume += volume;
self.cumulative_traded += price * volume;
self.vwap = self.cumulative_traded / self.cumulative_volume;
self.vwap
}
}

impl Default for VolumeWeightAdjustedPrice {
fn default() -> Self {
Self::new()
}
}

impl fmt::Display for VolumeWeightAdjustedPrice {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "VWAP")
}
}

impl Reset for VolumeWeightAdjustedPrice {
fn reset(&mut self) {
self.cumulative_volume = 0.0;
self.cumulative_traded = 0.0;
self.vwap = 0.0;
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::test_helper::*;

#[test]
fn test_next_bar() {
let mut vwap = VolumeWeightAdjustedPrice::new();
let bar1 = Bar::new().close(245.0504667).volume(103033.0);
let bar2 = Bar::new().close(244.7635667).volume(21168.0);
let bar3 = Bar::new().close(245.3166667).volume(36544.0);
assert_eq!(vwap.next(&bar1), 245.0504667);
assert_eq!(vwap.next(&bar2), 245.001569354568);
assert_eq!(vwap.next(&bar3), 245.07320403926406);
}

#[test]
fn test_reset() {
let mut vwap = VolumeWeightAdjustedPrice::new();

let bar1 = Bar::new().close(245.0504667).volume(103033.0);
let bar2 = Bar::new().close(244.7635667).volume(21168.0);
let bar3 = Bar::new().close(245.3166667).volume(36544.0);
assert_eq!(vwap.next(&bar1), 245.0504667);
assert_eq!(vwap.next(&bar2), 245.001569354568);
assert_eq!(vwap.next(&bar3), 245.07320403926406);
vwap.reset();
assert_eq!(vwap.next(&bar1), 245.0504667);
assert_eq!(vwap.next(&bar2), 245.001569354568);
assert_eq!(vwap.next(&bar3), 245.07320403926406);
}

#[test]
fn test_default() {
VolumeWeightAdjustedPrice::default();
}

#[test]
fn test_display() {
let vwap = VolumeWeightAdjustedPrice::new();
assert_eq!(format!("{}", vwap), "VWAP");
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
//! * [Efficiency Ratio (ER)](indicators/struct.EfficiencyRatio.html)
//! * [Rate of Change (ROC)](indicators/struct.RateOfChange.html)
//! * [On Balance Volume (OBV)](indicators/struct.OnBalanceVolume.html)
//! * [Volume Weight Adjusted Price (VWAP)](indicators/struct.VolumeWeightAdjustedPrice.html)
//!
#[cfg(test)]
#[macro_use]
Expand Down