Mike U
Mike U

Reputation: 3061

LINQ Query to find True Range

I am having trouble working out the LINQ Query to give me the True Range of a Open High Low Close Series.

I have an array of objects bars with the following properties

DateTime BarTime;
decimal Open;
decimal High;
decimal Low;
decimal Close;

Currently my LINQ Query looks like

var TrueRange = bars.Select(b => b.High - b.Low);

What I would like to do is instead of using b.High have Math.Max(b.High, previousBarsClose) and the same for b.Low have Math.Min(b.Low, previousBarsClose)

Any idea how to achieve this, I imagine I would have to join 2 instances of bars together joining the BarTime = BarTime of Previous Bar, but have no idea how to do it in LINQ.

Upvotes: 2

Views: 174

Answers (2)

sloth
sloth

Reputation: 101072

Any idea how to achieve this, I imagine I would have to join 2 instances of bars together joining the BarTime = BarTime of Previous Bar

That's a possible solution. You can use Skip/Zip for this (as an alternative to Ahmand's answer, which uses an indexer):

var TrueRange = bars.Skip(1).Zip(bars, 
                 (b, p) => Math.Max(b.High, p.Close) - Math.Min(b.Low, p.Close));

Upvotes: 2

Ahmad Mageed
Ahmad Mageed

Reputation: 96487

You could skip the first element, then use the overloaded Select method which gives you access to the index. With the index you can then access the previous element in the array. This approach will work provided the original collection lets you use an indexer, such as an array or list.

var query = bars.Skip(1)
                .Select((b, i) => Math.Max(b.High, bars[i].High) - 
                                    Math.Min(b.Low, bars[i].Low));

Note: the index i will start at 0. Since we skip the first element, using bars[i] will refer to the previous element.

Upvotes: 2

Related Questions