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
Indicator
s use RegularMethods
instead of Method
#16
Comments
Yes, it is a real issue for now. But there were bunch of reasons and decisions behind First of all, we can't just use
Second reason is that sometimes we need one method result to initialize another method inside indicator. Therefore we can't just assign method instance to an indicator's config. For example, There are some other reasons for
It is not possible even with |
Perhaps in some cases, but who's to say I don't want to try out something out-of-the-box and delay the slow MA by one candle (the opposite of what you suggested)?
This is a good point, indeed. But the whole initialization feels wrong as it is anyway. I've read that the recommended initial value of EMA is SMA, yet you use the first candle. Plus for MACD, if I choose E/D/TMA it takes much more than
Yes, this occured to me only a while after I opened the issue. It would require some complex stuff to make this work for probably too little benefit. Withdrawn... |
It is useless recommendation. Just ask yourself: if initial value of Initialization of methods and indicators may depend, but this library aims to follow next invariant:
It's like you have "virtual" infinite previous history with constant value.
Exponential moving averages uses all the history it has. There is no such a period, after you can tell "Now it's totally correct". So, again, the same invariant of infinite previous history helps a lot.
Well... It can... But MACD has three different moving averages. So there must be three different generic parameters for MACD: struct<M1, M2, M3> MACDInstance
where M1: Method<Params = ValueType, Input = PeriodType, Output = ValueType>,
M2: Method<Params = ValueType, Input = PeriodType, Output = ValueType>
M3: Method<Params = ValueType, Input = PeriodType, Output = ValueType>
{
// ...
} It may become a generic hell. There are bunch of other negative side effects of this architecture. F.e. you can't no longer return |
Ah, that one is easy and the the core of why initialization feels off to me: it is not initialized until it gets
Mathematically, yes, but in practice eventually far away periods become meaningless and even get lost in the floating point precision, as I'm sure you're aware.
I fail to understand this. You would add verbosity to implementors of But I'd really love if your crate were more open to extensability! As I see it, this mainly requires separating configuration from initialization (like not assuming Note that my issue is only against |
I thought about this issue and came to the same decision. So my proposal is to make a trait pub trait MovingAverageConfig {
fn init(&self, initial_value: ValueType) -> Result<Box<dyn Method<Params = PeriodType, Input = ValueType, Output = ValueType>>, Error>;
} Then create pub enum MovingAverages {
SMA(PeriodType),
WMA(PeriodType,
// ...
}
impl MovingAverageConfig for MovingAverages {
fn init(&self, initial_value: ValueType) -> Result<Box<dyn Method<Params = PeriodType, Input = ValueType, Output = ValueType>>, Error> {
match self {
Self::SMA(length) => Ok(Box::new(SMA::new(length, initial_value)?),
Self::WMA(length) => Ok(Box::new(WMA::new(length, initial_value)?),
// ...
}
}
} And indicators will be generalized over M: pub struct MACD<M: MovingAverageConfig> {
// ...
} On one hand it is pretty the same as it's implemented now. On the other hand, if you need to add your own moving average, you just need to create your own enum (or any other type) and implement |
Yes, I think something like this is much better! I'm assuming MACD now takes 3 MovingAverageConfig instances, right? Maybe with a macro it gets simple to even |
I've created a new branch. There are lot of changes, but the most important are:
So if you want to use your own moving average, you need to create some type (probably just an enum) and implement |
Resolved in v0.5 |
Most
Indicator
s use theRegularMethods
type. For me to use an existing indicator with a newMethod
I make I have to clone the source and add the new method toRegularMethods
. Why don't they just use aMethod
?Related to this is that by using the
RegularMethods
you are forcing the usage ofBox
and possible multiple-calculation of the same thing. If I want to use MACD and Keltner Channels in which one of the methods and its period is the same we are making double calculations. If Indicators take instead&'a dyn Method
we would be both generalizing and allowing for more optimizations.The text was updated successfully, but these errors were encountered: