- ago
I'm wondering whether it's possible to implement a strategy that swaps one position with another one at the EOD based on some condition. Here is an example strategy of what I mean:
Swap b/w SPY and UXVY,
Based on SPY RSI(10):
If at close SPY RSI(10) > 80: If holding SPY, sell SPY and buy UXVY at close. If no holdings (only at the start of the backtesting), buy UXVY.
If at close SPY RSI(10)<= 80: If holding UXVY, sell UXVY and buy SPY at close. If no holdings (only at the start of the backtesting), buy SPY.

Basically I want to swap b/w SPY and UXVY at EOD.

0
259
Solved
10 Replies

Reply

Bookmark

Sort
- ago
#1
I tried the following code but it did not work as the sell and buy will be on different days.

CODE:
using WealthLab.Backtest; using WealthLab.Core; using WealthLab.Indicators; namespace WealthScript1 {    public class TestStrategy : UserStrategyBase    {       BarHistory UVXY, SPY;       int RSIWindow = 10;       string previousCondition = "";       TimeSeries SPY_RSI;       public override void Initialize(BarHistory bars)       {          UVXY = GetHistory(bars, "UVXY");          SPY = GetHistory(bars, "SPY");          SPY_RSI = RSI.Series(SPY.Close, RSIWindow);          PlotTimeSeries(SPY_RSI, "SPY RSI", "RatioPane", WLColor.Coral);          StartIndex = RSIWindow;       }       public override void Execute(BarHistory bars, int idx)       {          // Determine the current condition          string currentCondition = DetermineCondition(idx);          WriteToDebugLog($"{bars.DateString(idx)}, current condition {currentCondition}, previous condition {previousCondition}");          // If the condition has changed since the previous day, close all positions          if (currentCondition != previousCondition)          {             WriteToDebugLog($"Condition changed. Closing all positions.");             CloseAllPositions();             OpenPositionsBasedOnCondition(currentCondition, idx);             previousCondition = currentCondition;          }          else          {             WriteToDebugLog($"No condition change, no position change.");          }       }       private string DetermineCondition(int idx)       {          // Condition based on SPY RSI          if (SPY_RSI[idx] > 80)          {             return "Buy UVXY";          }          else          {             return "Buy SPY";          }       }       private void CloseAllPositions()       {          foreach (var position in OpenPositionsAllSymbols)          {             WriteToDebugLog($"Closing position {position.Symbol}");             ClosePosition(position, OrderType.MarketClose, 0, "Close " + position.Symbol);          }       }       private void OpenPositionsBasedOnCondition(string condition, int idx)       {          WriteToDebugLog($"{condition}");          // Open new positions based on the current condition          switch (condition)          {             case "Buy UVXY":                PlaceTrade(UVXY, TransactionType.Buy, OrderType.MarketClose, 0, "Buy UVXY");                break;             case "Buy SPY":                PlaceTrade(SPY, TransactionType.Buy, OrderType.MarketClose, 0, "Buy SPY");                break;          }       }    } }
0
Cone8
 ( 5.88% )
- ago
#2
WealthLab will only trade on the next bar. If these are Daily bars, then the only way you can backtest a strategy that creates a trade on the Close using the closing data is by peeking.

In your script in WeatlhLab's Editor, click on the word OrderType. It will show you a QuickRef example of how to peek in a backtest for a Sell at MarketClose exit.
0
Best Answer
- ago
#3
Thanks @Cone for pointing to the example. By changing
CODE:
string currentCondition = DetermineCondition(idx);

to
CODE:
string currentCondition = DetermineCondition(idx+1);


I was able to get what I wanted to test.
0
- ago
#4
Re: Post #3. Is it just me or your change looks like bluntly peeking into the future and will throw an exception on the last bar?
0
- ago
#5
@Eugene sorry I forgot to update the code here, locally I skipped the last bar in execute.

update: I just tried even without skipping last bar it did not throw exception.
0
- ago
#6
Somehow when i extended this to a three condition switch, it did not work as expected. I only see SPY positions. Any idea?
0
- ago
#8
So for the above code I noticed NSF positions in the report. After i increased margin factor to 3-5 it worked fine and I see positions from all three tickers.

I guess the reason might be that sell and buy happens on the close of the same bar when a switch happens, WL might not be enforce the execution order of these trades?

Any idea @Engene, @Cone?
0
- ago
#9
CODE:
private string DetermineCondition(int idx) { if (SPY_RSI[idx] > 80) { return "Buy UVXY"; } else { if (SPY_RSI[idx] < 30) { return "Buy UPRO"; } return "Buy SPY"; } }


Looks like most of the time, you'll default to buying SPY. If SPY_RSI is less than 80 and greater than 30 then you'll by SPY.
0
- ago
#10
@paul1986: yes that was the rules.
0

Reply

Bookmark

Sort