| 13 | //! - Allocations are de-levered by the sum of their absolute values. Holdings chosen at a |
| 14 | //! rebalance on bar `t` use bar `t`'s allocation, `K_t` and FX, are sized at the **next** |
| 15 | //! bar's open `o_{t+1}`, and earn from bar `t + 1` on; that bar earns open-to-close only. |
| 16 | //! The first bar of the series counts as a rebalance. |
| 17 | //! - `costs` holds carry or dividends in price units with the sign of a credit: it is |
| 18 | //! **added** to the price change. Transaction costs are not modelled, so `K_t` is gross. |
| 19 | //! - A rebalance is detected by exact equality of consecutive allocation rows. |
| 20 | //! |
| 21 | //! This module is Rust-only; there is no Python binding. |
| 22 | //! |
| 23 | //! ``` |
| 24 | //! use openquant::etf_trick::{EtfTrick, Table}; |
| 25 | //! |
| 26 | //! # fn main() -> Result<(), openquant::etf_trick::EtfTrickError> { |
| 27 | //! let table = |values: [[f64; 2]; 6]| Table { |
| 28 | //! index: ["01-02", "01-03", "01-04", "01-05", "01-08", "01-09"].map(String::from).to_vec(), |
| 29 | //! columns: vec!["CL".to_string(), "NG".to_string()], |
| 30 | //! values: values.iter().map(|row| row.to_vec()).collect(), |
| 31 | //! }; |
| 32 | //! let open = [[70.0, 2.50], [70.5, 2.52], [71.4, 2.49], [71.0, 2.55], [72.2, 2.60], [72.0, 2.58]]; |
| 33 | //! let close = |
| 34 | //! [[70.4, 2.51], [71.2, 2.50], [71.1, 2.54], [72.0, 2.61], [72.1, 2.57], [72.6, 2.59]]; |
| 35 | //! let alloc = [[0.5, 0.5], [0.5, 0.5], [0.5, 0.5], [0.8, 0.2], [0.8, 0.2], [0.8, 0.2]]; |
| 36 | //! |
| 37 | //! let etf = EtfTrick::from_tables( |
| 38 | //! table(open), |
| 39 | //! table(close), |
| 40 | //! table(alloc), |
| 41 | //! table([[0.0; 2]; 6]), // no carry |
| 42 | //! None, // no FX |
| 43 | //! )?; |
| 44 | //! let series = etf.get_etf_series(100)?; |
| 45 | //! // Six rows give four values: the series starts on the second row, and the last row lacks a |
| 46 | //! // next open. |
| 47 | //! assert_eq!(series.len(), 4); |
| 48 | //! assert_eq!(series[0], ("01-03".to_string(), 1.0)); |