5

I have a class

class MarketData
{
    public double Open {get;set;}
    public double High{get;set;}
    public double Low{get;set;}
    public double Close{get;set;}
}

Now I have created List and filled it with last 30 days data. Here's where I am struggling to find best solution for this. A user can enter conditions manually but in fixed format, the fields can be e.g

Open is Greater Than Previous.Close

High is Less Than Previous.Low

Low is Greater Than Next.High,etc

I am parsing the string conditions to

public enum ConditionComparer { And, Or }

class SimpleCondition
{
    public string Operand1 { get; set; }
    public Operators Operator { get; set; }
    public string Operand2 { get; set; }
    public ConditionComparer Compare { get; set; }
}

Now I have to apply this conditions on the List<MarketData> and get matching results.

I used DynamicQueryable class in bit different scenario where conditions where dynamic and it worked perfectly but now I have to compare record with next or previous record.

Matsemann
  • 21,083
  • 19
  • 56
  • 89
Dinesh Ahuja
  • 417
  • 1
  • 5
  • 11
  • 2
    Have you tried something yet? – ken2k Dec 23 '13 at 14:50
  • Could you give an example of how such conditions would be input? e.g a string, and your expected output etc. – stevepkr84 Dec 23 '13 at 14:51
  • @ken2k not yet, i am thinking from quite some time but couldn't find optimal solution. – Dinesh Ahuja Dec 23 '13 at 14:52
  • @user2025312 added more details – Dinesh Ahuja Dec 23 '13 at 14:55
  • 4
    @DineshAhuja "Optimal solution"? Did you find a solution at all? Even not optimal? Show what you have so far. – Mohammad Dehghan Dec 23 '13 at 14:56
  • @MD.Unicorn i mean efficient solution, right now i know only to use for loops and lot of conditions to get results but i am looking for more efficient solution. – Dinesh Ahuja Dec 23 '13 at 14:58
  • I am not fully understand your problem, put you might need to define those as flag enum type and define those relations as bitwise operators between them. See this [question for more details about them](http://stackoverflow.com/a/8462/722783). It might be helpful. – Mahmoud Gamal Dec 23 '13 at 15:00
  • @MahmoudGamal there are two sets of conditions AND, OR e.g Open is Greater than previous Close AND High is Less than previous Close after that let's say Close is Greater than previous Close OR High is Less than previous Close – Dinesh Ahuja Dec 23 '13 at 15:04
  • @DineshAhuja so your main problem is to get those two MarkatData records to compare them? – okrumnow Dec 23 '13 at 15:05
  • 1
    @DineshAhuja As far as dynamic filters go, you've required a lot of rather complex constraints. Comparing one field to another field, and comparing each row to the row before it, complicate dynamic filters quite a lot. Are you always comparing each row to the row before it, or do you have other entirely different operations to support? Also, are all of your field types going to be doubles, or will you also have ints, dates, strings, etc. mixed in there? – Servy Dec 23 '13 at 15:06
  • @Servy each row to the row before it or after it – Dinesh Ahuja Dec 23 '13 at 15:07
  • 1
    @DineshAhuja If you can compare each to the row before it, you don't need to compare each to the row after it. I strongly suggest you choose one or the other, since you could solve any problem using just one of the two. Having both is needlessly complicating your query language. – Servy Dec 23 '13 at 15:08
  • @okrumnow Basically comparing each row with next or previous one with conditions – Dinesh Ahuja Dec 23 '13 at 15:09

1 Answers1

2

The problem to get the two MarketData records to compare is a sliding window problem. If you call

var compare = input.Zip(input.Skip(1), 
                        (a,b) => new Tuple<MarketData, MarketData>(a,b));

you get an IEnumerable<Tuple<MarketData, MarketData>> of all pairs of MarketData. Note that your input is enumerated twice.

Using any framework to build dynamic queries, eg. LinqKit, should then do it. Just write expressions that get an Tuple<MarketData, MarketData> as input. The first item in the Tuple is your "older" item, the second is your "newer" item.

okrumnow
  • 2,346
  • 23
  • 39