20 using System.Collections;
21 using System.Collections.Generic;
33 private bool _alreadyAppliedTypeFilters;
35 private IEnumerable<TData> _data;
41 protected enum ContractExpirationType :
int
58 protected ContractExpirationType
Type {
get;
set; } = ContractExpirationType.Standard;
72 internal IEnumerable<TData> Data
91 internal IEnumerable<Symbol> AllSymbols
95 return _data.Select(x => x.Symbol);
101 _data = value.Select(symbol => _data.FirstOrDefault(x => x.Symbol == symbol) ??
CreateDataInstance(symbol)).ToList();
119 Type = ContractExpirationType.Standard;
138 internal T ApplyTypesFilter()
140 if (_alreadyAppliedTypeFilters)
146 var memoizedMap =
new Dictionary<DateTime, bool>();
148 Func<TData, bool> memoizedIsStandardType = data =>
150 var dt = data.ID.Date;
153 if (memoizedMap.TryGetValue(dt, out result))
156 memoizedMap[dt] = res;
161 Data = Data.Where(x =>
165 case ContractExpirationType.Weekly:
166 return !memoizedIsStandardType(x);
167 case ContractExpirationType.Standard:
168 return memoizedIsStandardType(x);
169 case ContractExpirationType.Standard | ContractExpirationType.Weekly:
176 _alreadyAppliedTypeFilters =
true;
185 public virtual void Refresh(IEnumerable<TData> allData, DateTime localTime)
189 Type = ContractExpirationType.Standard;
190 _alreadyAppliedTypeFilters =
false;
200 if (_alreadyAppliedTypeFilters)
202 throw new InvalidOperationException(
"Type filters have already been applied, " +
203 "please call StandardsOnly() before applying other filters such as FrontMonth() or BackMonths()");
206 Type = ContractExpirationType.Standard;
216 if (_alreadyAppliedTypeFilters)
218 throw new InvalidOperationException(
"Type filters have already been applied, " +
219 "please call IncludeWeeklys() before applying other filters such as FrontMonth() or BackMonths()");
222 Type |= ContractExpirationType.Weekly;
232 Type = ContractExpirationType.Weekly;
243 var ordered = Data.OrderBy(x => x.ID.Date).ToList();
244 if (ordered.Count == 0)
return (T)
this;
245 var frontMonth = ordered.TakeWhile(x => ordered[0].ID.Date == x.ID.Date);
247 Data = frontMonth.ToList();
258 var ordered = Data.OrderBy(x => x.ID.Date).ToList();
259 if (ordered.Count == 0)
return (T)
this;
260 var backMonths = ordered.SkipWhile(x => ordered[0].ID.Date == x.ID.Date);
262 Data = backMonths.ToList();
282 return referenceDate;
293 public virtual T
Expiration(TimeSpan minExpiry, TimeSpan maxExpiry)
304 var minExpiryToDate = referenceDate + minExpiry;
305 var maxExpiryToDate = referenceDate + maxExpiry;
308 .Where(symbol => symbol.ID.Date.Date >= minExpiryToDate && symbol.ID.Date.Date <= maxExpiryToDate)
324 return Expiration(TimeSpan.FromDays(minExpiryDays), TimeSpan.FromDays(maxExpiryDays));
336 if (contracts.TryConvertToDelegate(out Func<IEnumerable<TData>, IEnumerable<Symbol>> contractSelector))
342 return Contracts(contracts.ConvertToSymbolEnumerable());
353 AllSymbols = contracts.ToList();
365 Data = contracts.ToList();
375 public T
Contracts(Func<IEnumerable<TData>, IEnumerable<Symbol>> contractSelector)
378 AllSymbols = contractSelector(Data).ToList();
388 public T
Contracts(Func<IEnumerable<TData>, IEnumerable<TData>> contractSelector)
391 Data = contractSelector(Data).ToList();
400 [Obsolete(
"Deprecated as of 2023-12-13. Filters are always non-dynamic as of now, which means they will only bee applied daily.")]
412 return Data.GetEnumerator();
418 IEnumerator IEnumerable.GetEnumerator()
420 return Data.GetEnumerator();