Hello,
I didn't find any indicator, maybe I missed one.
Does anyone know if there is an indicator that can measure the percentage increase / decrease in a certain period of time. For example: Increase 40% in 25 days. I thought of ROC, but it's not quite the right one. Thanks.
Kind regard
I didn't find any indicator, maybe I missed one.
Does anyone know if there is an indicator that can measure the percentage increase / decrease in a certain period of time. For example: Increase 40% in 25 days. I thought of ROC, but it's not quite the right one. Thanks.
Kind regard
Rename
Like that?)
or even:
CODE:
TimeSeries dif25Shifted = (bars.Close - (bars.Close >> 25)) / (bars.Close >> 25);
or even:
CODE:
TimeSeries dif25ShiftedMoreThan40Percent = ((bars.Close - (bars.Close >> 25)) / (bars.Close >> 25)) > 0.4;
This is exactly what the "Rate of Change" Indicator is doing. In WL it is called ROC.
Just a remark: If you plan to use "percentage change during the last N bars" in your trading strategy, you'll observe, that the ROC indicator shows two "jumps" if the input series has one "jump". This will produce "false" trading signals.
The second jump is generated, when the past reference price (price N bars ago) moves across the jump in the input series.
While the first jump is unavoidable (and probably correct) the second jump can be avoided when the past reference point is not calculated form a single price but from a smoothed price calculated form several past prices.
This is what the SROC indicator (smoothed ROC) does.
The SROC indicator is available in the finantic.Indicators extension.
https://www.wealth-lab.com/extension/detail/finantic.Indicators
The second jump is generated, when the past reference price (price N bars ago) moves across the jump in the input series.
While the first jump is unavoidable (and probably correct) the second jump can be avoided when the past reference point is not calculated form a single price but from a smoothed price calculated form several past prices.
This is what the SROC indicator (smoothed ROC) does.
The SROC indicator is available in the finantic.Indicators extension.
https://www.wealth-lab.com/extension/detail/finantic.Indicators
Thank you both.
Hello,
can someone help me with the TimeSeries. How to add the 40Percent for EntryLong.
I did try with "if" but I am getting an error cannot convert TimeSeries to bool.
can someone help me with the TimeSeries. How to add the 40Percent for EntryLong.
I did try with "if" but I am getting an error cannot convert TimeSeries to bool.
CODE:
using System.Drawing; using WealthLab.Backtest; using WealthLab.Candlesticks; using WealthLab.Core; namespace StrategiesCollection { public class EngulfingCandlesticks : UserStrategyBase { //create indicators and other objects here, this is executed prior to the main trading loop public override void Initialize(BarHistory bars) { TimeSeries dif25ShiftedMoreThan40Percent = ((Convert.ToInt32(bars.Close - (bars.Close >> 25))) / (bars.Close >> 25)) > 0.4; // PlotTimeSeries(dif25ShiftedMoreThan40Percent, "Percentage", String.Empty, Color.Aqua); _cpEntry = CandleGeneDecoder.FindPattern("Bullish Harami"); for (int n = 0; n < bars.Count; n++) { if (CandleGeneDecoder.DetectPattern(bars, n, _cpEntry)) { _cfi = new CandleEventItem(_cpEntry, bars.DateTimes[n]); _cbg = new CandleBarGlyph(_cfi, _cpEntry); DrawCustomBarGlyph(n, _cbg); } } _cpExit = CandleGeneDecoder.FindPattern("Bearish Engulfing"); for (int n = 0; n < bars.Count; n++) { if (CandleGeneDecoder.DetectPattern(bars, n, _cpExit)) { _cfi1 = new CandleEventItem(_cpExit, bars.DateTimes[n]); _cbg1 = new CandleBarGlyph(_cfi1, _cpExit); DrawCustomBarGlyph(n, _cbg1); } StartIndex = 20; } } //execute the strategy rules here, this is executed once for each bar in the backtest history public override void Execute(BarHistory bars, int idx) { int index = idx; if (!HasOpenPosition(bars, PositionType.Long)) { if (CandleGeneDecoder.DetectPattern(bars, index, _cpEntry)) { PlaceTrade(bars, TransactionType.Buy, OrderType.Market); } } else { var isLastPositionAcitve = HasOpenPosition(bars, PositionType.Long); if (isLastPositionAcitve) { Position p = LastPosition; if (p.PositionType == PositionType.Long) { if (CandleGeneDecoder.DetectPattern(bars, index, _cpExit)) { ClosePosition(p, OrderType.Market); } } } } } private CandleGenePattern _cpEntry; private CandleGenePattern _cpExit; private CandleEventItem _cfi; private CandleEventItem _cfi1; private CandleBarGlyph _cbg; private CandleBarGlyph _cbg1; } }
Hi,
That code line from Post #1 will not work. As DrKoch said you should use ROC.
That code line from Post #1 will not work. As DrKoch said you should use ROC.
Hi,
I've checked a few Entries Conditions. But I couldn't find a percentage movements up/down.
Is this the same as percentage - see picture. Or should I coded the increase/decrease percentage manually?

Regards,
I've checked a few Entries Conditions. But I couldn't find a percentage movements up/down.
Is this the same as percentage - see picture. Or should I coded the increase/decrease percentage manually?
Regards,
ROC is percentage change.
Hi Glitch,
Okay. But if I am usina a 20 bar range. Then the first bar can have a change from about 4.5%, the second 5.5%, the third 3.5%. Ans so on.
But I am looking for an increase to measure for example 15% a few days in a row. Like in the picture.
Okay. But if I am usina a 20 bar range. Then the first bar can have a change from about 4.5%, the second 5.5%, the third 3.5%. Ans so on.
But I am looking for an increase to measure for example 15% a few days in a row. Like in the picture.
QUOTE:
But I am looking for an increase to measure for example 15% a few days in a row. Like in the picture.
You mean something like this (a WL6 example)?
https://wl6.wealth-lab.com/Forum/Posts/Custom-Indicator-Request-from-NY-Expo-consecutive-days-where-prices-declined-5-or-more-28970
To get 5% up in that example in the link, you need to flip the inequality and sign around, but that example looks good.
WL7 has a ...
I'm sure there are mistakes in the solution below; someone can post a correction. But it goes something like this.
I agree with Reply# 3, using SROC here may make more sense. One day might give you an 8% increase and the next a 4% increase, but when smoothed out, both days will average over 5%, which is what matters.
CODE:
while(b >= 0 && roc[b] > +5) //while(b >= 0 && roc[b] < -5)
WL7 has a ...
CODE:indicator, but the "source" would have to look something like ROC-5.
ConsecUp(TimeSeries source, int lookback);
I'm sure there are mistakes in the solution below; someone can post a correction. But it goes something like this.
CODE:
IndicatorBase percentChg = new ROC(bars.Close, 1); IndicatorBase consecutiveUp = new ConsecUp(percentChg-5.0,3); //three consecutive days of 5% increases
I agree with Reply# 3, using SROC here may make more sense. One day might give you an 8% increase and the next a 4% increase, but when smoothed out, both days will average over 5%, which is what matters.
Hi Eugene,
yes, that's right #10.
I will try it out as well as the translation in WL7 and #11.
Thanks to all.
Regards,
yes, that's right #10.
I will try it out as well as the translation in WL7 and #11.
Thanks to all.
Regards,
Hello,
I am trying translating the code from Glitch to WL7 and I think I have created an endless loop. Can someone check this for me. I can't find the error. Thanks.
I am trying translating the code from Glitch to WL7 and I think I have created an endless loop. Can someone check this for me. I can't find the error. Thanks.
CODE:
using System.Drawing; using fiIndicators; using WealthLab.Backtest; using WealthLab.Core; using WealthLab.Indicators; namespace StrategiesCollection { public class SROCpercentageUpDown : UserStrategyBase { public SROCpercentageUpDown() { AddParameter("PeriodSROC", ParameterTypes.Int32, 4, 2, 100, 2); AddParameter("ConsecPctUp", ParameterTypes.Int32, 4, 2, 40, 2); AddParameter("Percentage", ParameterTypes.Double, 4, 2, 32, 2); AddParameter("ExitAfterX", ParameterTypes.Int32, 5, 1, 31, 2); } //create indicators and other objects here, this is executed prior to the main trading loop public override void Initialize(BarHistory bars) { _indicator = new SROC(bars.Close, Parameters[0].AsInt); PlotIndicator(_indicator, Color.FromArgb(64, Color.BlueViolet), PlotStyles.ThickLine); _consecutiveUp = new ConsecUp(_indicator, Parameters[1].AsInt); PlotIndicator(_consecutiveUp, Color.Aqua, PlotStyles.DashedLine, true, "ConsecUp"); _percentage = (int) Parameters[2].AsDouble; for (int i = bars.Count - 1; i >= 0; i++) { while (b >= 0 && _indicator[b] > _percentage) { cd--; b++; } _consecutiveUp[i] = cd; } StartIndex= 14; } //execute the strategy rules here, this is executed once for each bar in the backtest history public override void Execute(BarHistory bars, int idx) { var isLastPositionAcitve = HasOpenPosition(bars, PositionType.Long) || HasOpenPosition(bars, PositionType.Short); if(isLastPositionAcitve) { Position p = LastPosition; if(p.PositionType == PositionType.Short) { if (_consecutiveUp[idx] >= Parameters[1].AsInt) { if (_indicator[idx] >= Parameters[2].AsDouble) { _transaction = PlaceTrade(bars, TransactionType.Buy, OrderType.Market,0, 0, "BuyAtMarket"); } else { if (idx - p.EntryBar >= Parameters[3].AsInt) { ClosePosition(p, OrderType.Market); } } } } } } //declare private variables below private IndicatorBase _indicator; private IndicatorBase _consecutiveUp; private Transaction _transaction; private int _percentage; int cd = 0; int b = 1; } }
The i++ should be i--
But there are unrelated concerns. How are you initializing "b" for the WHILE loop? What I would do is convert that WHILE loop into a FOR loop so it's less confusing.
Also, why is _percentage declared as an "int" when it should be a "double"?
Why is the scoping of "cd" and "b" declared globally for the entire strategy class when it only appears locally in Initialize?
CODE:
for (int i = bars.Count - 1; i >= 0; i--) //for (int i = bars.Count - 1; i >= 0; i++)
But there are unrelated concerns. How are you initializing "b" for the WHILE loop? What I would do is convert that WHILE loop into a FOR loop so it's less confusing.
Also, why is _percentage declared as an "int" when it should be a "double"?
Why is the scoping of "cd" and "b" declared globally for the entire strategy class when it only appears locally in Initialize?
QUOTE:
if(isLastPositionAcitve)
We've been there before, this directive is not applied correctly so the system will not trade as expected. Have you had a chance to review the solution below?
https://www.wealth-lab.com/Discussion/My-Strategy-doesn-t-open-positions-7168
Hello,
@superticker. I made the changes. Can you check this please.
@Eugene. I changed the Entry/Exit Logic as in that post. Can you check the logic please.
I did make a few optimization and Optimize but I don't get results. Has someone an idea what is wrong? Or maybe is the idea bad.
Regards,
@superticker. I made the changes. Can you check this please.
@Eugene. I changed the Entry/Exit Logic as in that post. Can you check the logic please.
I did make a few optimization and Optimize but I don't get results. Has someone an idea what is wrong? Or maybe is the idea bad.
Regards,
CODE:
using System.Drawing; using fiIndicators; using WealthLab.Backtest; using WealthLab.Core; using WealthLab.Indicators; namespace StrategiesCollection { public class SroCpercentageUpDown : UserStrategyBase { public SroCpercentageUpDown() { AddParameter("PeriodSROC", ParameterTypes.Int32, 4, 2, 100, 2); AddParameter("ConsecutivUpPeriod", ParameterTypes.Int32, 4, 2, 40, 2); AddParameter("Percentage", ParameterTypes.Double, 4, 2, 32, 2); AddParameter("ExitAfterX", ParameterTypes.Int32, 5, 1, 31, 2); } //create indicators and other objects here, this is executed prior to the main trading loop public override void Initialize(BarHistory bars) { _indicator = new SROC(bars.Close, Parameters[0].AsInt); PlotIndicator(_indicator, Color.FromArgb(64, Color.BlueViolet), PlotStyles.ThickLine); _consecutiveUp = new ConsecUp(_indicator, Parameters[1].AsInt); PlotIndicator(_consecutiveUp, Color.Aqua, PlotStyles.DashedLine, true, "ConsecUp"); for (int i = bars.Count - 1; i >= 0; i--) { int cd = 0; int b = i; while (b >=0 && _indicator[b] > _percentage) { cd--; b++; } _consecutiveUp[i] = cd; } StartIndex= 14; } //execute the strategy rules here, this is executed once for each bar in the backtest history public override void Execute(BarHistory bars, int idx) { _enterLong = _consecutiveUp[idx] >= Parameters[1].AsInt && _indicator[idx] >= Parameters[2].AsDouble; _exitLong = bars.Close[idx] >= Parameters[3].AsInt; _percentage = Parameters[2].AsDouble; { if (!HasOpenPosition(bars, PositionType.Long)) { if (_enterLong) { PlaceTrade(bars, TransactionType.Buy, OrderType.Market, 0, 0, "BuyAtMarket"); } } else { var isLastPositionAcitve = HasOpenPosition(bars, PositionType.Long); if (isLastPositionAcitve) { Position p = LastPosition; if (_exitLong && p.PositionType == PositionType.Long) { ClosePosition(p, OrderType.Market); } } } } } //declare private variables below private IndicatorBase _indicator; private IndicatorBase _consecutiveUp; private bool _enterLong; private bool _exitLong; private double _percentage; } }
Sorry, I don't understand this code. Is there something wrong with the solution given in the latter part of Reply# 11, or are we doing something different?
This should be moved to Initialize():
CODE:
_percentage = Parameters[2].AsDouble;
Hello,
@Eugene ,thanks.
@superticker. I did use the while loop from #11. And IndicatorBase seems there are mistakes, as you said.
The idea is: I would like entry the position if the price increase x percentage in x days in a row and exit the position after x days.
I think I don't need both SROC and ConsecUP. I think it's enough only to choose just ConsecUP or SROC.
Did you mean this with your Post #11 ?
@Eugene ,thanks.
@superticker. I did use the while loop from #11. And IndicatorBase seems there are mistakes, as you said.
The idea is: I would like entry the position if the price increase x percentage in x days in a row and exit the position after x days.
I think I don't need both SROC and ConsecUP. I think it's enough only to choose just ConsecUP or SROC.
Did you mean this with your Post #11 ?
I'm a little confused. The whole point of using ConsecUp() is to avoid using the WHILE loop altogether. ConsecUp() is doing the WHILE business internally in order to simplify your strategy code.
I haven't tested this code, but this is the idea of Reply# 11. The WL7 ConsecUp() is measuring relative to "zero" rather than a percentage (see the docs), so you need to pass the difference, _indicator-percentage, as a parameter.
Notice that "percentage" is defined as a local variable to Initialize here, so it will be unavailable to Execute. You don't want your scoping design to cross more block boundaries than necessary.
CODE:
public override void Initialize(BarHistory bars) { _indicator = new SROC(bars.Close, Parameters[0].AsInt); PlotIndicator(_indicator, Color.FromArgb(64, Color.BlueViolet), PlotStyles.ThickLine); double percentage = Parameters[2].AsDouble; _consecutiveUp = new ConsecUp(_indicator-percentage, Parameters[1].AsInt); PlotIndicator(_consecutiveUp, Color.Aqua, PlotStyles.DashedLine, true, "ConsecUp"); StartIndex= 14; }
I haven't tested this code, but this is the idea of Reply# 11. The WL7 ConsecUp() is measuring relative to "zero" rather than a percentage (see the docs), so you need to pass the difference, _indicator-percentage, as a parameter.
Notice that "percentage" is defined as a local variable to Initialize here, so it will be unavailable to Execute. You don't want your scoping design to cross more block boundaries than necessary.
@superticker. Thanks, I'll try out and give feedback.
Can you tell me what is meant by "scoping desing." Thanks.
Can you tell me what is meant by "scoping desing." Thanks.
QUOTE:
what is meant by "scoping design."
Well this is an important issue. And you must master it! In the code below ...
CODE:
int i=5; for (int i=0; i<10; i++) continue; WriteToDebugLog(i);
the WriteToDebugLog should print out "5". Do you understand why because if you don't, your code will fail. There are two different i's being defined here based on the scoping rules. The FOR loop defines it's own "internal" {block} and a local "i" within that block. It's confusing here because you don't see braces around the FOR loop block, but they are there.
You then have an external block with a different "i" defined, which is 5. (There are braces around that block too, but they aren't showing. But they are really there.) The value for that "i" never changes. So we are talking about two separate i's based on scoping rules. If this isn't perfectly clear, check your C# textbook for more examples where they discuss placement of declarations.
Now take a look at a very advanced scoping design contained in the code in the link below. Be sure you understand it. If your textbook isn't clear, then ask questions. StackOverflow is a good source of answers for program design.
https://www.wealth-lab.com/blog/anatomy-of-a-wl7-strategy
You need to master this scoping concept. It's not hard, but it can be confusing. And your programs won't run until you master it.
@superticker. Many thanks for the explanations and example.
@superticker. Code works fine. Thanks.
For educational purposes, it's important to understand the WHILE-loop consecutive-percentage-gains design. However, for the "production case" I would employ as much of the WL framework as possible. That means using WL indicators (like ConsecUp) as much as possible.
The purpose of any framework (whether that be Wealth-Lab, .NET, fiIndicators, ScottPlot, or Math.Net) is to provide you with debugged code that hides implementation complexity (i.e. software engineering). All four mentioned frameworks (fiIndicators are optional) are part of the WL install, so try to employ all of them in your code work.
All these different frameworks also have their own data types, which may not be compatible with WL. For example, Math.Net has matrix and vector. But what you do there is write stubs (code segments) that you compile into your personal Local.Components.dll code library via Visual Studio, which you can then call from your WL strategy using only WL data types. It's software engineering 101. Happy computing to you.
Visual Studio questions should be posted to a different (existing) topic, not this one.
The purpose of any framework (whether that be Wealth-Lab, .NET, fiIndicators, ScottPlot, or Math.Net) is to provide you with debugged code that hides implementation complexity (i.e. software engineering). All four mentioned frameworks (fiIndicators are optional) are part of the WL install, so try to employ all of them in your code work.
All these different frameworks also have their own data types, which may not be compatible with WL. For example, Math.Net has matrix and vector. But what you do there is write stubs (code segments) that you compile into your personal Local.Components.dll code library via Visual Studio, which you can then call from your WL strategy using only WL data types. It's software engineering 101. Happy computing to you.
Visual Studio questions should be posted to a different (existing) topic, not this one.
@superticker. Many thanks. This will help.
Your Response
Post
Edit Post
Login is required