- ago
I am not sure that
CODE:
    // SMA cross     if(!sma25.CrossesOver(sma50, idx)) return;


reflects Bensdorp's intent, perhaps simply
CODE:
             if (sma25[idx] <= sma50[idx]) return;
0
1,038
15 Replies

Reply

Bookmark

Sort
Cone8
 ( 6.32% )
- ago
#1
The difference is between that of a filter and a trigger. Assuming the code makes it through the filter section, your suggestion (a filter) would allow a trade at ANY TIME the sma25 was greater than the sma50. This could be the case, for example, immediately after exiting on the trailing stop. Instead, the strategy waits to ensure a Crossover (trigger) condition.

That's the way it's programmed, I'll let you decide on Bensdorp's intentions.
0
- ago
#2
Could I ask, which interpretation makes the most money, the filter (the inequality) or the trigger (crossover moment)? After all, this is a backtesting forum, so which interpretation does the actual backtesting favor?
0
- ago
#3
The filter returns much better results than the crossover
1
- ago
#4
Just for the record: The book says (on page 137):
Setup: The close of the 25-day simple moving average is above the close of the 50-day simple moving average.
0
- ago
#5
This means: The published script does not reflect the book's description. The script should be corrected to read like the suggested code.
0
Cone8
 ( 6.32% )
- ago
#6
@DrKoch - you can publish a revision and then we can take down an outdated version upon request.
0
- ago
#7
I tried the crossover->filter adjustment but I am still not able to replicate results from the book... am I missing something?
0
Cone8
 ( 6.32% )
- ago
#8
There are so many variables that are probably not the same starting with:
1. Source of data
2. Data adjustments
3. Did you (or Bendrop) use a dynamic DataSet?
4. Commissions
5. Stock selection when buying power is limited. (This programmed strategy chooses the stocks with the highest 200-period ROC.)

And if it's wrong, break it down and find a trade that should or shouldn't have taken place.
0
- ago
#9
I think one big difference between "the book" and backtests in WL is:
Laurens uses "all available US Stocks" while a mere mortal WL user can just afford to run backtests on S&P500 or similar.

I adjusted some parameters in the scripts for such a smaller portfolio.

If you want to see a true comparison with the book you'll need:
* A data provider which can produce a DataSet with 3000+ US stocks including delisted stocks (a.k.a Norgate Data)
* A PC which can handle that amount of data within WL (64GB of RAM or more)
* Use the parameters from "the book"

.... yes, I am on the way to go all these steps, currently working on "A PC..."
0
- ago
#10
I am not beyond "mere mortal" level in any way but I think I already tackled the three problems Dr. Koch cites :)

I am backtesting on a 64 GB pc using Norgate datasets free from survivorship bias, e.g. Russel 3000 with delisted symbols.

Also the parameters and commissions I use should be ok.

I am a beginner of Wealth Lab though, so I am afraid I am missing something basic.

For starters, why are backtesting results for this very strategy non-deterministic?

Entries are market orders and are ranked so there should be no random selection of entries, there are no multiple same bar limit orders (only two concurrent stops but that should not be a problem, right?).

I think my adjustment settings are right (adjusted for splits but disregarding dividends)
1
Glitch8
 ( 12.10% )
- ago
#11
It's not deterministic because there are two exits for the same position, a stop loss and a trailing stop, but in order for WL8 to understand that those two exits should apply to the same position they need to be assigned a group code, which is one of the parameters of PlaceTrade. Unfortunately the group code parameter isn't included in the ClosePosition and CloseAtTrailingStop methods used in the code, and the CloseAtTrailingStop doesn't return a Transaction instance where it could be assigned.

So if both exits could get hit on the same bar, the exit is determined randomly. It's a current small gap in the backtester's robustness that we're aware of and will address in the future.

Building Block strategies assign the group code automatically so we run into this in coded strategies only.
2
Glitch8
 ( 12.10% )
- ago
#12
Technically it's possible to hack it to get deterministic results by modifying the code below, since the Transactions are available via the TransactionLog property of the Backtester ...

CODE:
public override void Execute(BarHistory bars, int idx) {          //=== Exit ===          Position p = LastOpenPosition;          if(p != null)          {             // Stop Loss             ClosePosition(p, OrderType.Stop, p.EntryPrice - 5.0 * atr20[p.EntryBar], "Stop Loss");             Transaction trade = Backtester.TransactionLog[Backtester.TransactionLog.Count - 1];             trade.PositionTag = 0;             if (p.IsOpen)             {                // Trailing Stop                CloseAtTrailingStop(p, TrailingStopType.PercentC, 25, "Trailing Stop");                trade = Backtester.TransactionLog[Backtester.TransactionLog.Count - 1];                trade.PositionTag = 0;             }          }
1
- ago
#13
Thanks Glitch, now the strategy results at least are deterministic!
0
- ago
#14
Very interesting strategy, I'd love to be able to backtest it

Basic question, which of the finatic extensions are needed to run the strategy...is is the "finatic.indicators" extension?
0
Glitch8
 ( 12.10% )
- ago
#15
Yes, only finantic Indicators.
1

Reply

Bookmark

Sort