- ago
Could you please help with my pipeline.

My strategy has... base signals, let's say bar.Close[idx] > bars.Open[idx] is a signal. I don't want those signals to be executed but to be the base for the real signal calculation. Rolling window, like previous 10 base signals are profitable I want to get new base signal executed, if they are not - I don't want to. The problem is if I use real signals for this, once the the real signal is affected by theese 10 previous base signals it will no more be the base signal as it can be skeeped.

So it could look like this: some kind of shadowed signals and positions I can look backward at, but that do not generate real signals and trades and so on. I thought I could use NSF positions for this, but I didn't succeed.

CODE:
var v = PlaceTrade(bars, TransactionType.Buy, OrderType.Market); v.NSF = true; v.Weight = -17; v.Quantity = CurrentEquity * 2 / bars.Close[idx]; v.SignalName = "algo";


This prevents this signal to be executed (as I didn't see "algo" in positions list), but NSF Positions Count were also zero in Metrics Report.

Maybe NSF is far from what I should use).

Do you have any idea about how I can solve this?)
0
453
14 Answers

Reply

Bookmark

Sort
- ago
#2
It sounds like you could store the shadow signals in a List or even a Queue, you could then do a mini analysis to see how many were profitable? You’d need to create your own little class to store the shadow signal info.
0
- ago
#3
So using no WL7 signals of any kind, just my own implementation? I think this would be my main direction of my further ideas if you haven't suggested this), yes, I think I'll use something like this. Thanks, Dion!
0
- ago
#4
QUOTE:
... you could store the shadow signals in a List or even a Queue, you could then do a mini analysis to see how many were profitable ...

I agree. If you want to restrict your data store to 10 elements, then you need a "ring buffer" of 10. The problem is there's no RingBuffer<T> datatype in the .NET framework.

If you know you will be restricted to 10 elements exactly, why not just declare an array of 10 elements? The Transaction class already exists, so you can use that as your array element datatype.
CODE:
int transIdx = 0; Transaction x1, x2, x3, x4, x5, x6; //use the "new" operator to declare storage for these first Transaction[] transactRingBuff = new Transaction[10]; ... //I'm not sure if the assignment operator "=" produces a shallow or deep copy for Transaction x1 = transactRingBuff[++transIdx%10]; //example pull (shallow copy?) x2 = transactRingBuff[++transIdx%10];          x3 = transactRingBuff[++transIdx%10]; transactRingBuff[++transIdx%10] = x4; //example push (shallow copy?) transactRingBuff[++transIdx%10] = x5; foreach (Transaction x in transactRingBuff) {    continue; }
As long as you access your array index by modulo 10 division, you should never overflow your ring buffer array of 10 elements. Also, an array is much faster than any collection (e.g. List or Queue). But you can't change the size of an array once it's created (without garbage collection), and that's a big disadvantage.
2
- ago
#5
@superticker

Thanks a lot for the code an the explanation.
0
- ago
#6
Happy to help. You can create your own class which inherits from Transaction if you want to add your own "=" operator, methods, or some supplemental field variables. But looking at the Transaction class better, I don't think it has any virtual methods of its own for inheritance. The designers never anticipated what you're trying to do. Your thinking is beyond the typical WL user. Happy computing.
0
- ago
#7
QUOTE:
So it could look like this: some kind of shadowed signals and positions I can look backward at, but that do not generate real signals and trades and so on. I thought I could use NSF positions for this, but I didn't succeed.


My idea:
Maybe it makes sense to start 2 strategies in livetrading:
1. shadow-strategy (let's call it shadow)
2. execution-strategy (let's call it exec)

shadow writes a global variable.
exec reads this global variable.

The global variable is declared as a string: we append a 1 for profitable trades, a 0 for losers.

So the global variable builds up: for example 10111 and so on. The next completed trade in shadow then results in 101110 or 101111.

If the string length is >= 10, you can evaluate the string in exec.

With this approach, your coding would remain relatively simple, the code would not be very bloated. The trade-off here might be that backtesting would not be possible or would be limited. I am not yet experienced enough in WL to make more concrete statements about this.
0
- ago
#8
QUOTE:
The global variable is declared as a string: we append a 1 for profitable trades, a 0 for losers.

C# lets you declare a Boolean array, which would be faster than using a string. Whether you use a Boolean array or string, you'll have a garbage collection problem if you change their length. Try making them a fixed length; otherwise, use a collection.
0
- ago
#9
QUOTE:
Whether you use a Boolean array or string, you'll have a garbage collection problem if you change their length.


A string also has advantages:
a fixed size is not necessary, the first 10 characters provide exactly the desired information. In shadow strat you could also stop writing to the global variable after 10 entries (string length >= 10).

Performance disadvantages / garbage collection? IMHO irrelavant in this order of size. Correct me if I'm wrong. I'm not an experienced C# developer, my programming background lies elsewhere.

I was also more concerned with reflecting a general idea. The variable type should not play a big role.
1
- ago
#10
QUOTE:
Maybe it makes sense to start 2 strategies in livetrading


Wow, this one is no doubt an out of the box idea!) I'll think about it, although it looks like too complicated... and I do not feel ready not to backtest my ideas befor live trading)).
0
- ago
#11
I desided to try the simplest way first. I add real positions and label them as shadowed using tags, then I tried to delete those transactions after backtest is over, as a result there are no such transactions in Transactions tab, but the Equity tab looks like they are still there)). E.g. when I labeled all transactions as shadow the Transactions tab was empty, but the equity was still there.

I used this code:

CODE:
for (int n = Backtester.Positions.Count - 1; n >= 0; n--) { Position p = Backtester.Positions[n]; if (p.Tag.ToString().Contains("NotToCalculate")) { Backtester.Positions.RemoveAt(n); } }


I tried it in BacktestComplete() and in Cleanup().

I like the way I go, it's simple), maybe I miss something, maybe I use a wrong method to place positions deleting or something?
0
- ago
#12
I use settings that prevent NSF, so there is no competition between NSF and non NSF, so if I could delete them before all the visualizers use positions it could work for me.
0
- ago
#13
So, I couldn't use:

- Deleting shadow positions after a backtest as I couldn't prevent equity and metrics to be affected by shadow positions.

- Using custom transactions, as the problem was not in storing transactions and position, I couldn't run it as expected, constructing positions and transactions using new() make them dummy objects with no values, so useless for me. Maybe I'm missing something)). Any further suggestions appreciated.


My next research branch: I'm going to use StrategyRunner class...). The first thing I'm going to find out is whether I can call the same strategy but with different options or not)).
0
- ago
#14
QUOTE:
My next research branch: I'm going to use StrategyRunner class...). The first thing I'm going to find out is whether I can call the same strategy but with different options or not


It turned out it's too time consuming and not appropriate for this purposes(, it took extra 14 minutes for a strategy (with 1 inside run added) to make a single run for a 275 dataset in strategy monitor.

0

Reply

Bookmark

Sort