### MACD Indicator Usage Example in Rust Source: https://github.com/amv-dev/yata/blob/master/README.md Shows how to use the Moving Average Convergence Divergence (MACD) indicator from the yata crate. This example initializes the indicator with custom methods for its components (MACD line and signal line) and then processes a sequence of candle data, printing the results. ```rust use yata::helpers::{RandomCandles, MA}; use yata::indicators::MACD; use yata::prelude::*; let mut candles = RandomCandles::new(); let mut macd = MACD::default(); macd.method1 = "sma-4".parse().unwrap(); // one way of defining methods inside indicators macd.signal = MA::TEMA(5); // another way of defining methods inside indicators let mut macd = macd.init(&candles.first()).unwrap(); for candle in candles.take(10) { let result = macd.next(&candle); println!("{:?}", result); } ``` -------------------------------- ### Generate Random Test Candles with Yata Source: https://context7.com/amv-dev/yata/llms.txt Demonstrates how to create a deterministic random candle generator for testing purposes using `RandomCandles`. It shows how to get the first candle and iterate over a specified number of subsequent candles, which can then be used with indicators. ```rust use yata::helpers::RandomCandles; use yata::indicators::MACD; use yata::prelude::*; // Create random candle generator let mut candles = RandomCandles::new(); // Get the first candle (useful for initialization) let first = candles.first(); println!("First candle - O:{:.2} H:{:.2} L:{:.2} C:{:.2}", first.open, first.high, first.low, first.close); // Iterate over candles for candle in candles.take(5) { println!("Candle - O:{:.2} H:{:.2} L:{:.2} C:{:.2} V:{:.2}", candle.open, candle.high, candle.low, candle.close, candle.volume); } // Use with indicators let mut candles = RandomCandles::new(); let macd = MACD::default(); let results = macd.over(&candles.take(100).collect::>()).unwrap(); ``` -------------------------------- ### EMA Method Usage Example in Rust Source: https://github.com/amv-dev/yata/blob/master/README.md Demonstrates how to use the Exponential Moving Average (EMA) method from the yata crate. It initializes an EMA with a specific length and period, then updates it with new data points, asserting the calculated EMA values. ```rust use yata::prelude::*; use yata::methods::EMA; // EMA of length=3 let mut ema = EMA::new(3, &3.0).unwrap(); ema.next(&3.0); beberapa.next(&6.0); assert_eq!(ema.next(&9.0), 6.75); assert_eq!(ema.next(&12.0), 9.375); ``` -------------------------------- ### In-Place Sequence Modification with Yata in Rust Source: https://context7.com/amv-dev/yata/llms.txt Demonstrates how to modify sequences in place using Yata's `apply` method for memory efficiency. This example shows smoothing data with an Exponential Moving Average (EMA) directly on the vector, and also using a static method for the same operation. ```rust use yata::prelude::*; use yata::methods::EMA; let mut prices = vec![100.0, 102.0, 101.0, 103.0, 105.0, 104.0, 106.0]; println!("Original: {:?}", prices); // Apply EMA in-place let mut ema = EMA::new(3, &prices[0]).unwrap(); prices.apply(&mut ema); println!("Smoothed: {:?}", prices); // Or use static method let mut prices2 = vec![100.0, 102.0, 101.0, 103.0, 105.0, 104.0, 106.0]; EMA::new_apply(3, &mut prices2).unwrap(); println!("Smoothed (static): {:?}", prices2); ``` -------------------------------- ### Weighted Moving Average (WMA) Calculation in Rust Source: https://context7.com/amv-dev/yata/llms.txt Demonstrates the Weighted Moving Average (WMA) implementation in YATA. WMA assigns linearly decreasing weights to older values, prioritizing recent data. Examples cover single value processing and streaming data. ```rust use yata::prelude::*; use yata::methods::WMA; // Create WMA with length=5 let mut wma = WMA::new(5, &20.0).unwrap(); let input_value = 34.51; let output_value = wma.next(&input_value); println!("WMA output: {}", output_value); // Process streaming data let data = vec![10.0, 11.0, 12.0, 13.0, 14.0, 15.0]; let mut wma = WMA::new(3, &data[0]).unwrap(); for value in &data { println!("Input: {}, WMA: {:.4}", value, wma.next(value)); } ``` -------------------------------- ### Exponential Moving Average (EMA) Calculation in Rust Source: https://context7.com/amv-dev/yata/llms.txt Illustrates the usage of the Exponential Moving Average (EMA) method in YATA. This method gives more weight to recent values, responding faster to price changes. Examples show stateful processing and iterating over price data. ```rust use yata::prelude::*; use yata::methods::EMA; // Create EMA with length=3 let mut ema = EMA::new(3, &3.0).unwrap(); // EMA formula: alpha = 2/(length+1), new_value = alpha * input + (1-alpha) * prev ema.next(&3.0); ema.next(&6.0); assert_eq!(ema.next(&9.0), 6.75); assert_eq!(ema.next(&12.0), 9.375); // Works with any numeric sequence let prices = vec![100.0, 102.0, 101.0, 103.0, 105.0]; let mut ema = EMA::new(3, &prices[0]).unwrap(); for price in &prices { let smoothed = ema.next(price); println!("Price: {}, EMA: {:.2}", price, smoothed); } ``` -------------------------------- ### Hull Moving Average (HMA) Calculation in Rust Source: https://context7.com/amv-dev/yata/llms.txt Provides an example of using the Hull Moving Average (HMA) method from the YATA library. HMA is designed to reduce lag while maintaining smoothness by combining weighted moving averages of different periods. ```rust use yata::prelude::*; use yata::methods::HMA; let mut hma = HMA::new(9, &100.0).unwrap(); let prices = vec![100.0, 101.5, 99.8, 102.3, 103.1, 101.9, 104.2]; for price in &prices { let smoothed = hma.next(price); println!("Price: {:.1}, HMA: {:.4}", price, smoothed); } ``` -------------------------------- ### Track Lowest Value in a Window with Yata Source: https://context7.com/amv-dev/yata/llms.txt Demonstrates how to track the lowest value within a sliding window of a specified size using the `Lowest` method in Yata. It requires an initial value and a window size, then processes each subsequent value to find the minimum within the current window. ```rust use yata::prelude::*; use yata::methods::Lowest; let values = vec![5.0, 8.0, 3.0, 9.0, 4.0, 7.0, 2.0, 10.0]; // Track lowest value in window of 3 let mut lowest = Lowest::new(3, &values[0]).unwrap(); for value in &values { let low = lowest.next(value); println!("Value: {}, Lowest in window: {}", value, low); } ``` -------------------------------- ### Calculate Bollinger Bands using Yata in Rust Source: https://context7.com/amv-dev/yata/llms.txt Demonstrates how to configure and calculate Bollinger Bands using the Yata library. It involves setting the average period and standard deviation multiplier, then processing a series of candles to output upper, middle, and lower band values. ```rust use yata::prelude::*; use yata::indicators::BollingerBands; use yata::core::{Candle, Source}; // Configure Bollinger Bands let bb = BollingerBands { avg_size: 20, // SMA period sigma: 2.0, // Standard deviation multiplier source: Source::Close, }; // Sample price data let candles = vec![ Candle { open: 100.0, high: 102.0, low: 99.0, close: 101.0, volume: 1000.0 }, Candle { open: 101.0, high: 103.0, low: 100.0, close: 102.0, volume: 1100.0 }, Candle { open: 102.0, high: 104.0, low: 101.0, close: 103.0, volume: 1200.0 }, ]; // Initialize and process let mut bb_instance = bb.init(&candles[0]).unwrap(); for candle in &candles { let result = bb_instance.next(candle); let upper = result.values()[0]; let middle = result.values()[1]; let lower = result.values()[2]; let signal = result.signals()[0]; println!("Upper: {:.2}, Middle: {:.2}, Lower: {:.2}", upper, middle, lower); } ``` -------------------------------- ### Configure and Validate Yata Indicators Dynamically Source: https://context7.com/amv-dev/yata/llms.txt Illustrates how to configure and dynamically modify parameters for Yata indicators using the `set` method. It also shows how to validate the indicator's configuration using `validate` and retrieve metadata like the indicator's name and output sizes. ```rust use yata::prelude::*; use yata::indicators::BollingerBands; use yata::core::Source; // Create and modify indicator config let mut bb = BollingerBands::default(); // Modify parameters dynamically bb.set("avg_size", "30".to_string()).unwrap(); bb.set("sigma", "2.5".to_string()).unwrap(); bb.set("source", "close".to_string()).unwrap(); // Validate configuration assert!(bb.validate()); // Get indicator metadata let (values_count, signals_count) = bb.size(); println!("Indicator produces {} values and {} signals", values_count, signals_count); println!("Indicator name: {}", bb.name()); ``` -------------------------------- ### Simple Moving Average (SMA) Calculation in Rust Source: https://context7.com/amv-dev/yata/llms.txt Demonstrates how to create and use the Simple Moving Average (SMA) method from the YATA library. It shows processing individual values and entire vectors, calculating the arithmetic mean over a sliding window. ```rust use yata::prelude::*; use yata::methods::SMA; // Create SMA with length=3 and initial value 1.0 let mut sma = SMA::new(3, &1.0).unwrap(); // Process individual values sma.next(&1.0); sma.next(&2.0); assert_eq!(sma.next(&3.0), 2.0); // (1+2+3)/3 = 2.0 assert_eq!(sma.next(&4.0), 3.0); // (2+3+4)/3 = 3.0 // Process entire vector at once let values: Vec = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]; let mut sma = SMA::new(2, &values[0]).unwrap(); let result = sma.over(&values); assert_eq!(result.as_slice(), &[1.0, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5]); ``` -------------------------------- ### Calculate Linear Volatility with Yata Source: https://context7.com/amv-dev/yata/llms.txt Demonstrates the calculation of linear volatility using the `LinearVolatility` method in Yata. It requires an initial price and processes subsequent prices to compute the rolling volatility over a specified period. ```rust use yata::prelude::*; use yata::methods::LinearVolatility; // Linear Volatility let mut vol = LinearVolatility::new(10, &100.0).unwrap(); let prices = vec![100.0, 101.0, 99.0, 102.0, 98.0, 103.0]; for price in &prices { let volatility = vol.next(price); println!("Price: {}, Volatility: {:.4}", price, volatility); } ``` -------------------------------- ### Track Highest Value in a Window with Yata Source: https://context7.com/amv-dev/yata/llms.txt Shows how to track the highest value within a sliding window of a specified size using the `Highest` method in Yata. It requires an initial value and a window size, then processes each subsequent value to find the maximum within the current window. ```rust use yata::prelude::*; use yata::methods::Highest; let values = vec![5.0, 8.0, 3.0, 9.0, 4.0, 7.0, 2.0, 10.0]; // Track highest value in window of 3 let mut highest = Highest::new(3, &values[0]).unwrap(); for value in &values { let high = highest.next(value); println!("Value: {}, Highest in window: {}", value, high); } ``` -------------------------------- ### Calculate Rate of Change with Yata Source: https://context7.com/amv-dev/yata/llms.txt Demonstrates how to calculate the Rate of Change (ROC) percentage using the `RateOfChange` method in Yata. It computes the percentage difference between the current price and the price `n` periods ago, requiring an initial price and a lookback period. ```rust use yata::prelude::*; use yata::methods::RateOfChange; let prices = vec![100.0, 102.0, 101.0, 104.0, 103.0, 106.0]; // Rate of Change: (current - past) / past let mut roc = RateOfChange::new(3, &prices[0]).unwrap(); for price in &prices { let rate = roc.next(price); println!("Price: {}, ROC: {:.4}", price, rate); } ``` -------------------------------- ### Calculate Highest-Lowest Delta with Yata Source: https://context7.com/amv-dev/yata/llms.txt Illustrates how to calculate the difference between the highest and lowest values within a sliding window using `HighestLowestDelta` in Yata. This method requires an initial value and a window size, and it computes the range for each period. ```rust use yata::prelude::*; use yata::methods::HighestLowestDelta; let values = vec![5.0, 8.0, 3.0, 9.0, 4.0, 7.0, 2.0, 10.0]; // Get the difference between highest and lowest let mut delta = HighestLowestDelta::new(3, &values[0]).unwrap(); for value in &values { let d = delta.next(value); println!("Value: {}, High-Low Delta: {}", value, d); } ``` -------------------------------- ### Calculate Relative Strength Index (RSI) using Yata in Rust Source: https://context7.com/amv-dev/yata/llms.txt Shows how to set up and compute the Relative Strength Index (RSI) with Yata. It allows configuration of the smoothing period and overbought/oversold zones, processing candle data to output RSI values and signals. ```rust use yata::prelude::*; use yata::indicators::RelativeStrengthIndex; use yata::helpers::MA; use yata::core::{Candle, Source}; // Configure RSI let rsi = RelativeStrengthIndex { ma: MA::EMA(14), // Smoothing method zone: 0.3, // Overbought/oversold zone (0.3 = 70/30) source: Source::Close, }; let candles = vec![ Candle { open: 44.0, high: 44.5, low: 43.5, close: 44.3, volume: 100.0 }, Candle { open: 44.3, high: 45.0, low: 44.0, close: 44.8, volume: 110.0 }, Candle { open: 44.8, high: 45.2, low: 44.5, close: 45.0, volume: 120.0 }, ]; let mut rsi_instance = rsi.init(&candles[0]).unwrap(); for candle in &candles { let result = rsi_instance.next(candle); let rsi_value = result.values()[0]; // Range [0.0, 1.0] let enter_signal = result.signals()[0]; // Signal on entering overzone let exit_signal = result.signals()[1]; // Signal on leaving overzone println!("RSI: {:.2}% ({:?}, {:?})", rsi_value * 100.0, enter_signal, exit_signal); } ``` -------------------------------- ### Process Sequences with Method::over in Rust Source: https://context7.com/amv-dev/yata/llms.txt Illustrates using the `over` method to process entire sequences of data at once with Yata. This method returns a vector of results, and alternatives using the `Sequence` trait for calling and applying methods are also shown. ```rust use yata::prelude::*; use yata::methods::SMA; let values: Vec = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]; // Create method and process all values let mut sma = SMA::new(2, &values[0]).unwrap(); let results = sma.over(&values); println!("Input: {:?}", values); println!("Output: {:?}", results); // Alternative: use Sequence trait on the vector let mut sma2 = SMA::new(3, &values[0]).unwrap(); let results2 = values.call(&mut sma2); // In-place modification let mut mutable_values = values.clone(); let mut sma3 = SMA::new(2, &mutable_values[0]).unwrap(); mutable_values.apply(&mut sma3); println!("Modified in-place: {:?}", mutable_values); ``` -------------------------------- ### Calculate Momentum with Yata Source: https://context7.com/amv-dev/yata/llms.txt Explains how to measure price momentum using the `Momentum` method in Yata. This method calculates the difference between the current price and the price `n` periods ago, requiring an initial price and a lookback period. ```rust use yata::prelude::*; use yata::methods::Momentum; let prices = vec![100.0, 102.0, 101.0, 104.0, 103.0, 106.0]; // Momentum: current - past let mut momentum = Momentum::new(3, &prices[0]).unwrap(); for price in &prices { let mom = momentum.next(price); println!("Price: {}, Momentum: {:.2}", price, mom); } ``` -------------------------------- ### Convert Candles to Heikin-Ashi in Rust Source: https://context7.com/amv-dev/yata/llms.txt Demonstrates how to convert regular OHLCV candles to Heikin-Ashi candles using the YATA library. This method smooths price action for better trend visualization. It requires the `yata` crate and its `HeikinAshi` method. ```rust use yata::prelude::*; use yata::methods::HeikinAshi; use yata::core::Candle; let candles = vec![ Candle { open: 100.0, high: 102.0, low: 98.0, close: 101.0, volume: 1000.0 }, Candle { open: 101.0, high: 104.0, low: 100.0, close: 103.0, volume: 1100.0 }, Candle { open: 103.0, high: 105.0, low: 101.0, close: 102.0, volume: 1200.0 }, ]; let mut ha = HeikinAshi::new((), &candles[0]).unwrap(); for candle in &candles { let ha_candle = ha.next(candle); println!("Regular - O:{:.1} H:{:.1} L:{:.1} C:{:.1}", candle.open, candle.high, candle.low, candle.close); println!("Heikin-A - O:{:.1} H:{:.1} L:{:.1} C:{:.1}\n", ha_candle.open, ha_candle.high, ha_candle.low, ha_candle.close); } ``` -------------------------------- ### Double and Triple Exponential Moving Average (DEMA, TEMA) in Rust Source: https://context7.com/amv-dev/yata/llms.txt Shows how to implement Double Exponential Moving Average (DEMA) and Triple Exponential Moving Average (TEMA) using YATA. These methods reduce lag compared to standard EMA by applying multiple smoothing passes. ```rust use yata::core::Method; use yata::methods::{DEMA, TEMA}; // Double Exponential Moving Average let mut dema = DEMA::new(3, &1.0).unwrap(); dema.next(&1.0); dema.next(&2.0); assert_eq!(dema.next(&3.0), 2.75); assert_eq!(dema.next(&4.0), 3.8125); // Triple Exponential Moving Average - even less lag let mut tema = TEMA::new(3, &1.0).unwrap(); tema.next(&1.0); tema.next(&2.0); assert_eq!(tema.next(&3.0), 2.9375); assert_eq!(tema.next(&4.0), 4.0); ``` -------------------------------- ### Calculate Standard Deviation with Yata Source: https://context7.com/amv-dev/yata/llms.txt Shows how to calculate the standard deviation of a series of values using the `StDev` method in Yata. It initializes `StDev` with a window size and an initial value, then processes each subsequent value to compute the rolling standard deviation. ```rust use yata::prelude::*; use yata::methods::StDev; // Standard Deviation let values = vec![10.0, 12.0, 11.0, 13.0, 12.0, 14.0, 13.0]; let mut stdev = StDev::new(5, &values[0]).unwrap(); for value in &values { let sd = stdev.next(value); println!("Value: {}, StDev: {:.4}", value, sd); } ``` -------------------------------- ### Add YATA Dependency to Cargo.toml Source: https://github.com/amv-dev/yata/blob/master/README.md This snippet shows how to add the YATA library as a dependency in your Rust project's Cargo.toml file. Ensure you are using a compatible version of YATA. ```toml [dependencies] yata = "0.6" ``` -------------------------------- ### Handling Candlestick Data with Candle struct and OHLCV Trait Source: https://context7.com/amv-dev/yata/llms.txt The Candle struct and OHLCV trait standardize candlestick data (Open, High, Low, Close, Volume) and provide built-in calculations like Typical Price (TP), True Range (TR), and HL2. It allows for dynamic access to source values and validation of candle data. ```rust use yata::prelude::*; use yata::core::{Candle, Source}; // Create candle from struct let candle = Candle { open: 100.0, high: 105.0, low: 98.0, close: 103.0, volume: 1000.0, }; // Built-in calculations println!("Typical Price (TP): {}", candle.tp()); // (H+L+C)/3 println!("HL2: {}", candle.hl2()); // (H+L)/2 println!("OHLC4: {}", candle.ohlc4()); // (O+H+L+C)/4 println!("CLV: {}", candle.clv()); // Close Location Value println!("Is Rising: {}", candle.is_rising()); // close > open // Create from tuple let candle: Candle = (100.0, 105.0, 98.0, 103.0, 1000.0).into(); // Access source values dynamically let close = candle.source(Source::Close); let tp = candle.source(Source::TP); // Validate candle data assert!(candle.validate()); // Calculate True Range let prev_candle = Candle { close: 99.0, ..Candle::default() }; let tr = candle.tr(&prev_candle); println!("True Range: {}", tr); ``` -------------------------------- ### Calculate True Range (TR) with Yata Source: https://context7.com/amv-dev/yata/llms.txt Shows how to calculate the True Range (TR) for a series of candles using the `TR` method in Yata. TR accounts for price gaps between periods and is a key component for calculating Average True Range (ATR). It requires the previous candle's close price. ```rust use yata::prelude::*; use yata::methods::TR; use yata::core::Candle; let candles = vec![ Candle { open: 100.0, high: 102.0, low: 98.0, close: 101.0, volume: 1000.0 }, Candle { open: 101.0, high: 105.0, low: 100.0, close: 104.0, volume: 1100.0 }, Candle { open: 104.0, high: 106.0, low: 102.0, close: 103.0, volume: 1200.0 }, ]; // TR considers: max(high-low, |high-prev_close|, |low-prev_close|) let mut tr = TR::new((), &candles[0]).unwrap(); for candle in &candles { let true_range = tr.next(candle); println!("Candle C:{:.1}, TR: {:.2}", candle.close, true_range); } ``` -------------------------------- ### Moving Average Constructor (MA Enum) in Yata Rust Source: https://context7.com/amv-dev/yata/llms.txt Explains the `MA` enum in Yata for a unified moving average interface. It covers creating MAs from enum variants, parsing them from string formats like 'sma-14', and initializing/using them, along with retrieving the period. ```rust use yata::helpers::MA; use yata::core::MovingAverageConstructor; // Create from enum variants let ma1 = MA::SMA(10); let ma2 = MA::EMA(20); let ma3 = MA::TEMA(5); // Parse from string format "type-period" let ma4: MA = "sma-14".parse().unwrap(); let ma5: MA = "ema-26".parse().unwrap(); let ma6: MA = "tema-9".parse().unwrap(); // Initialize and use let mut instance = ma1.init(100.0).unwrap(); let result = instance.next(&101.0); // Get period println!("Period: {}", ma1.ma_period()); // 10 // Available types: sma, wma, hma, rma, ema, dma, dema, tma, tema, // wsma, smm, swma, trima, linreg, vidya ``` -------------------------------- ### Detecting Specific Directional Crosses with CrossAbove and CrossUnder Source: https://context7.com/amv-dev/yata/llms.txt CrossAbove detects only upward crosses (bullish signals), while CrossUnder detects only downward crosses (bearish signals). These methods are useful for pinpointing specific directional trend changes. ```rust use yata::core::Method; use yata::methods::{CrossAbove, CrossUnder}; // Detect only upward crosses let mut cross_above = CrossAbove::new((), &(0.0, 5.0)).unwrap(); let fast = vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]; let slow = vec![5.0, 3.0, 1.8, 2.9, 4.1, 5.6]; for i in 0..fast.len() { let signal = cross_above.next(&(fast[i], slow[i])).analog(); if signal == 1 { println!("Index {}: Bullish crossover detected", i); } } // Detect only downward crosses let mut cross_under = CrossUnder::new((), &(0.0, 5.0)).unwrap(); for i in 0..fast.len() { let signal = cross_under.next(&(fast[i], slow[i])).analog(); if signal == 1 { println!("Index {}: Bearish crossover detected", i); } } ``` -------------------------------- ### Detecting Time Series Crosses with Yata::methods::Cross Source: https://context7.com/amv-dev/yata/llms.txt The Cross method detects when two time series lines cross each other. It returns buy signals (1) for upward crosses and sell signals (-1) for downward crosses. This method is useful for identifying potential trend changes. ```rust use yata::prelude::*; use yata::methods::Cross; let mut cross = Cross::default(); let t1 = vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]; // Fast line let t2 = vec![5.0, 3.0, 1.8, 2.9, 4.1, 5.6]; // Slow line let expected = vec![0, 0, 1, 0, -1, 0]; // 1=cross up, -1=cross down for i in 0..t1.len() { let signal = cross.next(&(t1[i], t2[i])).analog(); assert_eq!(signal, expected[i]); match signal { 1 => println!("Index {}: BUY signal (crossed above)", i), -1 => println!("Index {}: SELL signal (crossed below)", i), _ => println!("Index {}: No signal", i), } } ``` -------------------------------- ### Calculating MACD Indicator with Yata::indicators::MACD Source: https://context7.com/amv-dev/yata/llms.txt The MACD indicator calculates the Moving Average Convergence Divergence, a trend-following momentum indicator. It shows the relationship between two moving averages and provides signals for MACD/Signal line crosses and MACD/Zero crosses. The indicator can be configured with different moving average types and periods. ```rust use yata::helpers::{RandomCandles, MA}; use yata::indicators::MACD; use yata::prelude::*; // Create candle data let mut candles = RandomCandles::new(); // Configure MACD (default: EMA 12, 26, 9) let mut macd = MACD::default(); // Customize moving average typesmacd.ma1 = "sma-4".parse().unwrap(); // String parsingmacd.signal = MA::TEMA(5); // Direct enum // Initialize with first candle let mut macd_instance = macd.init(&candles.first()).unwrap(); // Process candles for candle in candles.take(10) { let result = macd_instance.next(&candle); // result contains 2 values: MACD line, Signal line // and 2 signals: MACD/Signal cross, MACD/Zero cross let macd_value = result.values()[0]; let signal_line = result.values()[1]; let cross_signal = result.signals()[0]; println!("MACD: {:.4}, Signal: {:.4}, Action: {:?}", macd_value, signal_line, cross_signal); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.