Replies: 3 comments
-
Yes, your observation is correct. Most cross-over and oscillator strategies only signal a Buy or Sell at a very specific point and for a short period of time. Without the DenormalizeActions, it is very infrequent to see all strategies signal at the same time. With the DenormalizeActions, we're keeping track of the strategie's earlier stand. In your example, RsiStrategy have a Sell action followed by Hold actions. We interpret this as the RsiStrategy recommended a Sell action and it didn't change its stand since then. So we take the subsequent Hold actions as Sell. At that point it is saying that you should have already sold this asset. When used with the OrStrategy, it is correct that if the other strategy even recommends a Buy, the OrStrategy will see that as a conflict and not give a Buy recommendation until the RsiStrategy also gives a Buy. I do see your point. This eventually ends up being the same as the AndStrategy, which is not the intended outcome here. Let me think a little more and get back to you. What's your use case by the way? It can be a good case study as we think through this. |
Beta Was this translation helpful? Give feedback.
-
Thank you for your response. It does make sense. I can see how we need to replicate actions in the situation where a strategy might only signal a Buy or Sell over a short period of time. In my particular situation, my repository reads fund and share prices from a “Portfolio Performance” (https://www.portfolio-performance.info/en/) backup file. I was using indicator/cmd/backtest.go to run the assets through a number of strategies and, only just having found the indicator software, I was experimenting with what it would allow me to do with custom strategies and was interested in how I could use the or_strategy to compose sub-strategies but also use a custom strategy.Report to see how the individual sub-strategies contributed to the final collection of Buy and Sell annotations and the outcome chart. I was looking at a simple (MACD OR RSI(70, 30)) combination for 12 months worth of daily data from July 2023 to July 2024 and as luck (or mis-fortune) would have it one of my funds had an initially high RSI value of 84 which signalled an immediate Sell action in late July. The MACD strategy returned a sequence of reasonable Buy and Sell actions from late August 2023 to February 2024. However a few things looked strange on the charts:
After a little bit of investigation I could see that the lack of annotations on the main and RSI charts was because of the behaviour of the strategy.NormalizeActions function when it is delivered an initial Sell action (as discussed elsewhere here). So I realised that RSI was delivering an early Sell action which lasted from 27th July to 1st Aug 2023. But then MACD signalled a Buy action on August 30th which was being ignored even though RSI had a neutral signal at that point. The same thing happened when MACD signalled a Buy in Nov 2023, and Jan 2024 - all of these were ignored because of 3 days of Sell from RSI back in July 2023. My feeling is that, certainly in this example, it is wrong to allow the reach of the early RSI Sell signal to continue for so long. And when the RSI strategy returns a Hold signal it is because it is ambivalent about what action should be taken and that shouldn’t be ignored. The flip side is that, as you point out, many of these strategies will indicate for just a short time and when comparing sub-strategies in something like an AND or OR strategy they are not likely to all be signalling together. If we were to a deliver a Hold when the sub-strategy didn’t signal a Buy or a Sell we would probably end up with more Buy and Sell annotations on our resulting chart than we would like. But by not delivering a Hold we are giving much more weight to the early Sell action (in my example) than it deserves. As a human looking at a chart showing a number of indicators you automatically weigh up the strengths of each indicator according to how strong they appear and how close they are to a point in time (perhaps the current date). Perhaps the AND or OR strategies need to be able to do the same thing. Which would suggest that they would need more information than just a replicated Buy or Sell. Knowing the age of the Buy or Sell action would be a start, so that it could either ignore actions older than a certain number of periods or else give them some weighting which would allow them to be combined with the other Buy or Sell actions that are received from the other sub-strategies that are being consulted. My personal view is that I would rather have seen a few more Buy/Sell annotations on the main chart than have my strategy refuse to buy anything evermore (or at least until the RSI strategy decided that the stock was oversold). As an experiment, if I remove the call to DenormalizeAction from ActionSources I do get a good combination of influence from both the MACD and the RSI strategies and I get a nice 6% outcome at the end of the year (see below). [p.s. Thanks for creating the indicator software. It is enjoyable to use and nicely structured] |
Beta Was this translation helpful? Give feedback.
-
The change is available in v2.1.3. Please feel free to reopen if you believe we should do some more work on this. Thanks again for the discussion. |
Beta Was this translation helpful? Give feedback.
-
Each of the combining strategies, AndStrategy, OrStrategy and MajorityStrategy, use the strategy.ActionSource function to create “a slice of action channels, one for each strategy, where each channel emits actions computed by its corresponding strategy” for a given channel of snapshots.
This allows these combining strategies to compare the actions from the component strategies to make a decision on a snapshot by snapshot basis about whether to return a Buy, Sell or Hold action. For example the OrStrategy “emits actionable recommendations when at least one strategy in the group recommends an action without any conflicting recommendations from other strategies”
The ActionSource function calls the Compute function from each of component strategies to get a channel of Actions but it then maps the elements of that channel through DenormalizeActions.
DenormalizeActions “retains Hold actions until the first Buy or Sell action appears. Subsequently, it replaces all remaining Hold actions with the preceding Buy or Sell action, effectively merging consecutive actions.”
Perhaps I’m mis-understanding something, but it seems to me that this takes important information away from the combining strategy.
Best seen by example: Suppose I use the OrStrategy to combine a number of strategies together with an RsiStrategy. In my example the RSI strategy returned a Sell very early on in the Snapshot stream and after than a sequence of Hold actions. Passing that through DenormalizeActions converts it into a Sell followed by a sequence of Sell actions. Because the Compute function of the OrStrategy will never return a Buy if it is OR’d with a Sell action the overall composite action will never return a Buy even though the RSI strategy just returned a single Sell action perhaps many days earlier and had subsequently returned a sequence of Hold actions because it didn’t have a strong enough signal for a Buy or a Sell.
Something feels slightly wrong here. Or have I overlooked something?
Beta Was this translation helpful? Give feedback.
All reactions