- ago
Thank you, Glitch, for the code example. I see that I have to completely revamp my design pattern and thinking from V6 when it comes to transactions.

Following the example, I am able to buy an alternative symbol (to the signal symbol) but don't seem to be able to detect an open position. The program is definitely opening positions as shown in backtest summary..

I tried using LastPosition, FindOpenPosition, LastOpenPosition, and, the Linq version from the example

CODE:
      if (FindOpenPosition(PositionType.Long) != null)          {             WriteToDebugLog("Found Last Open Position");          }          else          {             WriteToDebugLog("Last Open Position is Null");          }

Result: Last Open Position is Null

CODE:
         if (LastOpenPosition != null)          {             WriteToDebugLog("Found Last Open Position");          }          else          {             WriteToDebugLog("Last Open Position is Null");          }

Result: Last Open Position is Null

CODE:
         if (GetPositions().Where(p => p.IsOpen == true).Count() != 0)          {             WriteToDebugLog("Found open position");          }          else          {             WriteToDebugLog ("Didn't find open position");          }

Result: Didn't find open position

I thought (at least in V6), the Positions List contains all trades, even if they are not the current dataset symbol under test. Is V7 only looking for positions that match the dataset (signal) symbol under test? I never trade the signal symbol.

What I am simply doing is running an indicator on an index like NDX and then trading an alternative symbol like QQQ. I am able to execute Buy logic, but not detect QQQ as an Open position after buy. Am I missing some required step to do alt symbol trading?.

Note that the Pairs Trading example does not appear to be a use case of alternative symbol trading like mine, in that it appears it does depends on a Dataset to fetch symbols. It also does not appear to have *equivalent* functionality like SetContext / RestoreContext from V6 .
0
632
Solved
18 Replies

Reply

Bookmark

Sort
- ago
#1
I tripped across FIndOpenPositionAllSymbols. The explanation of this method in the QR confirms my speculation above about the FindOpenPositions method. But I can't get this to work either.

Using a value of 0 or 1 for the required Position tag still does not detect an Open position. Even it did detect one, I wouldn't know how to work with it because I don't know the index number of the position I am testing for.

I simply want to test if an open position exists for my alt symbol but I don't see any way to do that yet.
0
- ago
#2
QUOTE:
I never trade the signal symbol.

What I am simply doing is running an indicator on an index like NDX and then trading an alternative (i.e. external) symbol like QQQ.... Am I missing some required step to do alt symbol trading?

This sounds like upside down logic to me. Why not turn this around and run WL7 on the symbol you actually want to trade against in the first place? When you get into that trading symbol's Initialize{} (or Execute{}) logic, then check the "external" signal symbol (say present in IndexLab) to see if there's a trading opportunity present.
1
- ago
#3
Hi @superticker. There are a couple of reasons. The first is that I find the index to be a more reliable indicator of trend than the derivative. The second reason is I am rotating positions of different leverage ETF's (NDX ==> QQQ, QLD, TQQQ for example). based on technical indicators.

The strategy is solid and I have been using it for years with V6. I'm just trying to figure out how to replicate the logic in V7.
0
- ago
#4
QUOTE:
... I find the index to be a more reliable indicator of trend than the derivative.

I'm not sure what you mean by "the derivative". But I already appreciate that the external index is the "signaling" TimeSeries. That was always understood.

QUOTE:
I am rotating positions of different leverage ETF's ... QQQ, QLD, TQQQ....

No problem. Place QQQ, QLD, and TQQQ in your WL7 dataset. And have WL7 cycle through them and check for trading opportunities bar-by-bar against your external signaling index. I don't see a problem.

I use the S&P500 as an external index for all my WL7 stock trading as well. I've never had any problems using an external index for trading purposes. But in all cases, the stocks (or ETFs) being traded are in the WL dataset itself. The S&P500 external index is only used for signaling or decorrelating each stock in the trading dataset.

If we are talking about doing a rotational strategy (say with an external signaling index), we probably should start a new topic for exactly that.
1
- ago
#5
@superticker The issue appears to be that V7 does not have the same approach to "Open Positions" or Positions List in general, when it comes to External Symbols. The only issue I'm having at this point is to detect whether an alt position is "open" so I can decide whether to fork to selling logic or buying logic. Real simple, pedestrian logic pattern.

I'm not sure if putting all the symbols in one DataSet would resolve this issue. You see, I don't really require historical data on the symbols I'm trading. I just need to know whether I have an open position (to test for selling) or not, in which case I would only (potentially) buy at market the alt symbol. Currently in V&, these alt symbols are not in any DataSet.
0
- ago
#6
QUOTE:
V7 does not have the same approach to "Open Positions" or Positions List in general, when it comes to External Symbols.

Correct. You're not going to be able to trade external symbols. So put the instruments you want to trade in a WL dataset instead.

QUOTE:
I don't really require historical data on the symbols I'm trading.
Understood. There is not a requirement to use the BarHistory of any of the stocks in the WL dataset for trading. But you still need the Position information for these traded stocks, so they still need to be in the WL dataset so this Position information is made available.

Moreover, the WL Performance Visualizers also need this Position information to work. So the bottom line is to place the instruments you're trading against in the WL dataset (whether you're going to use their BarHistory or not).
1
- ago
#7
QUOTE:
You're not going to be able to trade external symbols

How come? Can't you specify any BarHistory in PlaceTrade, leveraging GetHistory?
0
- ago
#8
If you like the proposed upside down solution better, please post it here. I'm curious to see how efficiently it executes since WL7 wasn't optimized to work that way. Maybe we'll discover something. Will the Performance Visualizers still work or will they be confused if the external symbols are the ones being traded instead of the dataset symbols?
0
Glitch8
 ( 10.89% )
- ago
#9
With OpenPositionsAllSymbols you can certainly obtain just what the method says. Here's a minimal example that uses a simple RSI4 overbought/oversold, but in addition to buying and selling the DataSet symbol, it also buys and sells SPY. SPY isn't in the DataSet (which has 9 symbols).

You can see, I plot OpenPositionsAllSymbols.Count here in a Pane, and it reaches a max of 18, which is twice the number of symbols in the DataSet. That's all those extra SPY positions.

CODE:
using WealthLab.Backtest; using WealthLab.Core; using WealthLab.Indicators; using System.Drawing; namespace WealthScript1 { public class MyStrategy : UserStrategyBase { //Initialize public override void Initialize(BarHistory bars) {          rsi4 = RSI.Series(bars.Close, 4);          PlotIndicator(rsi4);          numPos = new TimeSeries(bars.DateTimes, 0);          PlotTimeSeries(numPos, "Position Count", "NumPos", Color.Violet);          spy = GetHistory(bars, "SPY"); } //Execute public override void Execute(BarHistory bars, int idx) {          int count = OpenPositionsAllSymbols.Count;          numPos[idx] = count; if (OpenPositions.Count == 0) {             if (rsi4[idx] < 40)             {                PlaceTrade(bars, TransactionType.Buy, OrderType.Market);                PlaceTrade(spy, TransactionType.Buy, OrderType.Market);             } } else {             if (rsi4[idx] > 60)             {                PlaceTrade(bars, TransactionType.Sell, OrderType.Market);                PlaceTrade(spy, TransactionType.Sell, OrderType.Market);             } } }       //private members       private RSI rsi4;       private TimeSeries numPos;       BarHistory spy; } }


1
- ago
#10
To @Eugene's point I can definitely trade external symbols. Here's the setup for that
CODE:
      string _ndxLev1Sym = "QQQ", _ndxLev2Sym = "QQQ", _ndxLev3Sym = "TQQQ",              _spxLev1Sym = "IVV", _spxLev2Sym = "SSO", _spxLev3Sym = "UPRO";       BarHistory ndxLev1Bars, ndxLev2Bars, ndxLev3Bars, spxLev1Bars, spxLev2Bars, spxLev3Bars;

and

CODE:
         ndxLev1Bars = GetHistory(bars, _ndxLev1Sym);          ndxLev2Bars = GetHistory(bars, _ndxLev2Sym);          ndxLev3Bars = GetHistory(bars, _ndxLev3Sym);          spxLev1Bars = GetHistory(bars, _spxLev1Sym);          spxLev2Bars = GetHistory(bars, _spxLev2Sym);          spxLev3Bars = GetHistory(bars, _spxLev3Sym);




0
- ago
#11
@Eugene @superticker
I managed to resolve the Open Positions issue with External Symbols by borrowing a Linq design patten Eugene sent me months ago (thank you1) to solve a similar problem with a completely different application. it didn't occur to me that I was trying to solve the same problem for different purpose. Here's the code:

CODE:
         var lstOpenPositions = GetPositionsAllSymbols().Where(p => p.IsOpen == true).ToList();          curSymOpen = false;          foreach (Position pos in lstOpenPositions)          {             if (pos.Symbol == curSymbol) ;             {                curSymOpen = true;                break;             }          }
1
- ago
#12
Robert, I'm glad to see you're up and running!
0
Cone8
 ( 23.46% )
- ago
#13
This should work too (maybe was added after Eugene's example) -

CODE:
List<Position> lstOpenPositions = OpenPositionsAllSymbols; // But, if you want to include Open NSF Positions, then pass true to GetPositionsAllSymbols() var lstOpenPositions = GetPositionsAllSymbols(true).Where(p => p.IsOpen).ToList();
0
Best Answer
- ago
#14
Thank you, @Eugene

@Cone. Yes I see that, since my filter is so simple (open). The original Linq structure was testing for multiple filter criteria, which is why Eugene likely used it for my previous issue. I see it is not necessary in this case.

I guess the simplest solution is

CODE:
         curSymOpen = false;          foreach (Position pos in OpenPositionsAllSymbols)          {             if (pos.Symbol == curSymbol) ;             {                curSymOpen = true;                break;             }          }


Although best coding practices in C# might suggest cloning a new list object as in your code.
0
Cone8
 ( 23.46% )
- ago
#15
fwiw, it's not really a clone, it's just reference, and as in your example, it's not required. I only wrote it that way to highlight the replacement for the Linq statement.

A "clone" would entail creating a new list object with the new keyword, which you'd fill by .Add(ing) the elements.
0
- ago
#16
Thanks @Cone. I always appreciate learning from @Eugene and you how I can be a better C# programmer (it's a low baseline ;)

Here's a one-line Linq solution for the "Test for External Open Position" use case that someone might helpful.

CODE:
         bool extSymOpen = OpenPositionsAllSymbols.Where(p => p.Symbol == extSymbol).Count() > 0;


Note: For this to work, users should be sure to include
CODE:
using System.Linq;

at the top of the code window
2
Cone8
 ( 23.46% )
- ago
#17
Corrected above:
OpenPositionsAllSymbols().Where to OpenPositionsAllSymbols.Where

Had you used GetPositionsAllSymbols(), that one needs the parentheses for the method group.
0
- ago
#18
@Cone. I have it right in my code but miscopied to the post. Thanks for catching that so we don't frustrate someone who tries to use!
1

Reply

Bookmark

Sort