public EventsPostFilter BuildEventsPostFilterFromModel(int earliestYear, RetrieveEventDataDelegate retrieveDataForEvents)
        {
            //if(ProductWrapper == null)
            //    return null;

 //           var dataRetriever = new DailyDataRetriever(new List<ProductWrapper>() { ProductWrapper });
//            RetrieveEventDataDelegate retrieveDataForEvents = () => dataRetriever.getData(new DateTime(earliestYear, 1, 1), false, false, ProductWrapper.ToString());

            switch (PostFilter)
            {
                case PostFilterType.DeMarkBuy:
                    return EventFilterBuilder.DeMark(DeMarkEventType.BuySetupStart, Window, retrieveDataForEvents);
                case PostFilterType.DeMarkSell:
                    return EventFilterBuilder.DeMark(DeMarkEventType.SellSetupIndex, Window, retrieveDataForEvents);                    
                case PostFilterType.RSIDrop:
                    return EventFilterBuilder.RSIDrop(FilterOperator, FilterValue, Window, retrieveDataForEvents);
                case PostFilterType.RSIRise:
                    return EventFilterBuilder.RSIRise(FilterOperator, FilterValue, Window, retrieveDataForEvents);
                case PostFilterType.UpMovement:
                    return Singleton<EventFilterBuilder>.Instance.SdUpMove(FilterOperator, FilterValue, Window, retrieveDataForEvents);
                case PostFilterType.DownMovement:
                    return Singleton<EventFilterBuilder>.Instance.SdDownMove(FilterOperator, FilterValue, Window, retrieveDataForEvents);                    
                default:
                    throw new ArgumentOutOfRangeException();
            }

            return null;
        }
        public static EventsPostFilter RSIRise(FilterOperator filterOperator, double value, int window, RetrieveEventDataDelegate FetchValueToCompare)
        {
            var retrievedData = FetchValueToCompare();
            var prices = retrievedData.Item2;
            var instrumentString = retrievedData.Item1;
            var rsi = HelperMethods.CalculateRSI(prices.ToDifferences(replaceNanWith_: 0d), window);

            return new EventsChangePostFilter(PostFilterType.RSIRise, filterOperator, value, rsi, instrumentString, retrievedData);
        }
 // create filters 
 public EventsPostFilterGroup BuildEventsPostFilterGroup(RetrieveEventDataDelegate retrieveDataForEvents)
 {
     var filterTopGroup = new EventsPostFilterGroup();
     var subEventGroups = postFilterGroupViewModelList.Select(gp => gp.BuildEventsPostFilterGroup(retrieveDataForEvents));
     foreach (var eventsPostFilter in subEventGroups)
     {
         filterTopGroup.AddFilterToGroup(eventsPostFilter);
     }
     return filterTopGroup;
 }
        public static EventsPostFilter KeyReversalBull(RetrieveEventDataDelegate FetchValueToCompare)
        {
            var retrievedData = FetchValueToCompare();
            var prices = retrievedData.Item2;
            var instrumentString = retrievedData.Item1;

            var signals = Technicals.Reversal.KeyReversal.CalculateBullSignals(prices.ToContruct(), 3);
            var signalDates = signals.Dates;
            var signalVal = signals.Data.Select(d => (double) d).ToArray();
            return new EventsPostFilter(PostFilterType.KeyReversal, FilterOperator.Equal, 0, new DatedDataCollectionGen<double>(signalDates, signalVal), instrumentString, retrievedData);            
        }
        public EventsPostFilter SdDownMove(FilterOperator filterOperator, double value, int window, RetrieveEventDataDelegate FetchValueToCompare)
        {
            var retrievedData = FetchValueToCompare();
            var prices = retrievedData.Item2;
            var instrumentString = retrievedData.Item1;

            // create a movment series with the diff based on window
            var diffSeries = prices.ToDifferences(window).GetSubValues(v => v > 0);
            var eventMovementSd = Statistics.Stdev(eventDates.Select(d => diffSeries.ValueOnDate(d)).ToArray());
            PostFilterStatistic stat = null;
            return new MovementBeforeEventPostFilter(PostFilterType.DownMovement, filterOperator, value * eventMovementSd, diffSeries, instrumentString, retrievedData, stat);
        }
        public static EventsPostFilter DeMark(DeMarkEventType markEventType,  int window, RetrieveEventDataDelegate FetchValueToCompare)
        {
            var retrievedData = FetchValueToCompare();
            var prices = retrievedData.Item2;
            var instrumentString = retrievedData.Item1;
            var setups = SI.Strategy.Technicals.DeMark.Analysis.GetSetups(prices.ToContruct(), 0, 0, 0, 0, window)
                  .Where(x => x.EventType == markEventType && x.Children != null);

            var events = setups.Select(x => new {a = x.Children.First(c => c.SeriesIndex == window).Date, b = (double)window}).ToArray();
            var dateWindowDeMarkCollection = new DatedDataCollectionGen<double>(events.Select(e => e.a).ToArray(),
                events.Select(e => e.b).ToArray());
            return new EventsPostFilter(PostFilterType.DeMarkBuy, FilterOperator.Equal, window, dateWindowDeMarkCollection, instrumentString, retrievedData);            
        }
 // create filters 
 public EventsPostFilterGroup BuildEventsPostFilterGroup(RetrieveEventDataDelegate retrieveDataForEvents)
 {
     var currentGroup = new EventsPostFilterGroup();            
     //var postFilters = postFilterItemViewModelList.Select(item => item.BuildEventsPostFilterFromModel(eventControl.RetrieveDataForEvents));
     
     var earliestYear = eventControl.EarliestPreSelectedYear;
       
     var postFilters = postFilterItemViewModelList.Select(item => item.BuildEventsPostFilterFromModel(earliestYear, retrieveDataForEvents));
     foreach (var eventsPostFilter in postFilters)
     {
         currentGroup.AddFilterToGroup(eventsPostFilter);
     }
     currentGroup.LogicalOp = LogicalOp;
     return currentGroup;
 }
 private DateTime[] EventFilterBuilder(DateTime[] eventDates, RetrieveEventDataDelegate retrieveDataForEvents)
 {
     // post filter events
     // with the above event dates from preselection, we filter out the ones match in post filter condition
     var eventBuilder = Singleton<EventFilterBuilder>.Instance;
     eventBuilder.eventDates = eventDates.Select(e => e.Date).ToArray();   // we only need the date without time when using it for filter event.
     var filteredEventDates = eventBuilder.GenerateFilteredDates(GiveMeEventSelectorVM().BuildEventsPostFilterGroup(retrieveDataForEvents));
     return filteredEventDates;
 }
 private EventDate[] EventFilterBuilder(EventDate[] eventDates, RetrieveEventDataDelegate retrieveDataForEvents)
 {
   // post filter events
     // with the above event dates from preselection, we filter out the ones match in post filter condition
     var resultDates = EventFilterBuilder(eventDates.Select(ev => ev.Date).ToArray(), retrieveDataForEvents);
     return eventDates.Where(d => resultDates.Contains(d.Date.Date)).ToArray();
     //var eventBuilder = new EventFilterBuilder {eventDates = eventDates.Select(ev => ev.Date).ToArray()};
     //var filteredEventDates = eventBuilder.GenerateFilteredDates(GiveMeEventSelectorVM().BuildEventsPostFilterGroup());
     //return filteredEventDates;
 }