20 using System.Collections;
21 using System.Collections.Generic;
35 private bool _alreadyAppliedTypeFilters;
37 private IEnumerable<TData> _data;
43 protected enum ContractExpirationType :
int
60 protected ContractExpirationType
Type {
get;
set; } = ContractExpirationType.Standard;
74 internal IEnumerable<TData> Data
93 internal IEnumerable<Symbol> AllSymbols
121 Type = ContractExpirationType.Standard;
148 internal T ApplyTypesFilter()
150 if (_alreadyAppliedTypeFilters)
156 var memoizedMap =
new Dictionary<DateTime, bool>();
158 Func<TData, bool> memoizedIsStandardType = data =>
160 var dt = data.ID.Date;
163 if (memoizedMap.TryGetValue(dt, out result))
166 memoizedMap[dt] = res;
171 Data = Data.Where(x =>
175 case ContractExpirationType.Weekly:
176 return !memoizedIsStandardType(x);
177 case ContractExpirationType.Standard:
178 return memoizedIsStandardType(x);
179 case ContractExpirationType.Standard | ContractExpirationType.Weekly:
186 _alreadyAppliedTypeFilters =
true;
195 public virtual void Refresh(IEnumerable<TData> allData, DateTime localTime)
199 Type = ContractExpirationType.Standard;
200 _alreadyAppliedTypeFilters =
false;
210 if (_alreadyAppliedTypeFilters)
212 throw new InvalidOperationException(
"Type filters have already been applied, " +
213 "please call StandardsOnly() before applying other filters such as FrontMonth() or BackMonths()");
216 Type = ContractExpirationType.Standard;
226 if (_alreadyAppliedTypeFilters)
228 throw new InvalidOperationException(
"Type filters have already been applied, " +
229 "please call IncludeWeeklys() before applying other filters such as FrontMonth() or BackMonths()");
232 Type |= ContractExpirationType.Weekly;
242 Type = ContractExpirationType.Weekly;
253 var ordered = Data.OrderBy(x => x.ID.Date).ToList();
254 if (ordered.Count == 0)
return (T)
this;
255 var frontMonth = ordered.TakeWhile(x => ordered[0].ID.Date == x.ID.Date);
257 Data = frontMonth.ToList();
268 var ordered = Data.OrderBy(x => x.ID.Date).ToList();
269 if (ordered.Count == 0)
return (T)
this;
270 var backMonths = ordered.SkipWhile(x => ordered[0].ID.Date == x.ID.Date);
272 Data = backMonths.ToList();
292 return referenceDate;
303 public virtual T
Expiration(TimeSpan minExpiry, TimeSpan maxExpiry)
314 var minExpiryToDate = referenceDate + minExpiry;
315 var maxExpiryToDate = referenceDate + maxExpiry;
318 .Where(symbol => symbol.ID.Date.Date >= minExpiryToDate && symbol.ID.Date.Date <= maxExpiryToDate)
334 return Expiration(TimeSpan.FromDays(minExpiryDays), TimeSpan.FromDays(maxExpiryDays));
346 if (contracts.TryConvertToDelegate(out Func<IEnumerable<TData>, IEnumerable<Symbol>> contractSelector))
352 return Contracts(contracts.ConvertToSymbolEnumerable());
363 AllSymbols = contracts.ToList();
375 Data = contracts.ToList();
385 public T
Contracts(Func<IEnumerable<TData>, IEnumerable<Symbol>> contractSelector)
388 AllSymbols = contractSelector(Data).ToList();
398 public T
Contracts(Func<IEnumerable<TData>, IEnumerable<TData>> contractSelector)
401 Data = contractSelector(Data).ToList();
410 [Obsolete(
"Deprecated as of 2023-12-13. Filters are always non-dynamic as of now, which means they will only bee applied daily.")]
422 return Data.GetEnumerator();
428 IEnumerator IEnumerable.GetEnumerator()
430 return Data.GetEnumerator();