17 using System.Collections.Generic;
18 using Newtonsoft.Json;
34 private readonly IPeriodSpecification _periodSpecification;
39 public Guid
Id {
get;
protected set; }
44 public Guid?
GroupId {
get;
protected set; }
96 public TimeSpan
Period {
get;
internal set; }
111 public double?
Weight {
get;
private set; }
126 public string Tag {
get;
protected set; }
179 : this(symbol, period, type, direction, null, null, tag)
212 _periodSpecification =
new TimeSpanPeriodSpecification(period);
224 : this(symbol, expiryFunc, type, direction, null, null, tag)
240 public Insight(
Symbol symbol, Func<DateTime, DateTime> expiryFunc,
InsightType type,
InsightDirection direction,
double? magnitude,
double? confidence,
string sourceModel =
null,
double? weight =
null,
string tag =
"")
241 : this(symbol, new FuncPeriodSpecification(expiryFunc), type, direction, magnitude, confidence, sourceModel, weight, tag)
260 public Insight(DateTime generatedTimeUtc,
Symbol symbol, TimeSpan period,
InsightType type,
InsightDirection direction,
double? magnitude,
double? confidence,
string sourceModel =
null,
double? weight =
null,
string tag =
"")
261 : this(symbol, period, type, direction, magnitude, confidence, sourceModel, weight, tag)
279 private Insight(
Symbol symbol, IPeriodSpecification periodSpec,
InsightType type,
InsightDirection direction,
double? magnitude,
double? confidence,
string sourceModel =
null,
double? weight =
null,
string tag =
"")
295 _periodSpecification = periodSpec;
298 var period = (periodSpec as TimeSpanPeriodSpecification)?.
Period;
313 throw new InvalidOperationException(
Messages.
Insight.GeneratedTimeUtcNotSet(
this));
316 _periodSpecification.SetPeriodAndCloseTime(
this, exchangeHours);
356 throw new ArgumentOutOfRangeException(nameof(barCount),
Messages.
Insight.InvalidBarCount);
359 var spec =
new ResolutionBarCountPeriodSpecification(resolution, barCount);
360 return new Insight(symbol, spec,
InsightType.Price, direction, magnitude, confidence, sourceModel, weight, tag);
375 public static Insight Price(
Symbol symbol, DateTime closeTimeLocal,
InsightDirection direction,
double? magnitude =
null,
double? confidence =
null,
string sourceModel =
null,
double? weight =
null,
string tag =
"")
377 var spec = closeTimeLocal ==
Time.
EndOfTime ? (IPeriodSpecification)
378 new EndOfTimeCloseTimePeriodSpecification() :
new CloseTimePeriodSpecification(closeTimeLocal);
379 return new Insight(symbol, spec,
InsightType.Price, direction, magnitude, confidence, sourceModel, weight, tag);
394 public static Insight Price(
Symbol symbol, TimeSpan period,
InsightDirection direction,
double? magnitude =
null,
double? confidence =
null,
string sourceModel =
null,
double? weight =
null,
string tag =
"")
398 throw new ArgumentOutOfRangeException(nameof(period),
Messages.
Insight.InvalidPeriod);
402 new EndOfTimeCloseTimePeriodSpecification() :
new TimeSpanPeriodSpecification(period);
403 return new Insight(symbol, spec,
InsightType.Price, direction, magnitude, confidence, sourceModel, weight, tag);
418 public static Insight Price(
Symbol symbol, Func<DateTime, DateTime> expiryFunc,
InsightDirection direction,
double? magnitude =
null,
double? confidence =
null,
string sourceModel =
null,
double? weight =
null,
string tag =
"")
420 return new Insight(symbol, expiryFunc,
InsightType.Price, direction, magnitude, confidence, sourceModel, weight, tag);
429 if (insights ==
null)
431 throw new ArgumentNullException(nameof(insights));
434 var groupId = Guid.NewGuid();
435 foreach (var insight
in insights)
437 if (insight.GroupId.HasValue)
439 throw new InvalidOperationException(
Messages.
Insight.InsightAlreadyAssignedToAGroup(insight));
442 insight.GroupId = groupId;
451 public static IEnumerable<Insight>
Group(
Insight insight) =>
Group(
new[] {insight});
463 TimeSpan.FromSeconds(serializedInsight.
Period),
464 serializedInsight.
Type,
470 serializedInsight.
Tag
473 Id = Guid.Parse(serializedInsight.
Id),
478 GroupId =
string.IsNullOrEmpty(serializedInsight.
GroupId) ? (Guid?)
null : Guid.Parse(serializedInsight.
GroupId)
486 insight.Score.Finalize(insight.CloseTimeUtc);
517 throw new ArgumentOutOfRangeException(nameof(barCount),
Messages.
Insight.InvalidBarCount);
530 var barSize = resolution.ToTimeSpan();
531 var startTimeLocal = generatedTimeUtc.ConvertFromUtc(exchangeHours.
TimeZone);
533 return closeTimeLocal.ConvertToUtc(exchangeHours.
TimeZone);
547 throw new ArgumentOutOfRangeException(nameof(period),
Messages.
Insight.InvalidPeriod);
550 var barSize = period.ToHigherResolutionEquivalent(
false);
555 var barCount = (int)(period.Ticks / barSize.ToTimeSpan().Ticks);
556 var closeTimeUtc =
ComputeCloseTime(exchangeHours, generatedTimeUtc, barSize, barCount);
557 if (closeTimeUtc == generatedTimeUtc)
562 var totalPeriodUsed = barSize.ToTimeSpan().Multiply(barCount);
563 if (totalPeriodUsed != period)
565 var delta = period - totalPeriodUsed;
570 var percentOfDay = delta.Ticks / (double)
Time.
OneDay.Ticks;
574 if (delta != TimeSpan.Zero)
612 private interface IPeriodSpecification
620 private class TimeSpanPeriodSpecification : IPeriodSpecification
622 public readonly TimeSpan
Period;
624 public TimeSpanPeriodSpecification(TimeSpan period)
626 if (period == TimeSpan.Zero)
644 private class ResolutionBarCountPeriodSpecification : IPeriodSpecification
647 public readonly
int BarCount;
649 public ResolutionBarCountPeriodSpecification(
Resolution resolution,
int barCount)
670 insight.Period = insight.CloseTimeUtc - insight.GeneratedTimeUtc;
677 private class CloseTimePeriodSpecification : IPeriodSpecification
679 public readonly DateTime CloseTimeLocal;
681 public CloseTimePeriodSpecification(DateTime closeTimeLocal)
683 CloseTimeLocal = closeTimeLocal;
689 var closeTimeLocal = exchangeHours.
IsOpen(CloseTimeLocal,
false)
693 insight.CloseTimeUtc = closeTimeLocal.ConvertToUtc(exchangeHours.
TimeZone);
695 if (insight.GeneratedTimeUtc > insight.CloseTimeUtc)
697 throw new ArgumentOutOfRangeException(nameof(closeTimeLocal), $
"Insight closeTimeLocal must not be in the past.");
700 insight.Period = insight.CloseTimeUtc - insight.GeneratedTimeUtc;
708 private class FuncPeriodSpecification : IPeriodSpecification
710 public readonly Func<DateTime, DateTime> _expiryFunc;
712 public FuncPeriodSpecification(Func<DateTime, DateTime> expiryFunc)
714 _expiryFunc = expiryFunc;
719 var closeTimeLocal = insight.GeneratedTimeUtc.ConvertFromUtc(exchangeHours.
TimeZone);
720 closeTimeLocal = _expiryFunc(closeTimeLocal);
723 if (!exchangeHours.
IsOpen(closeTimeLocal,
false))
728 insight.CloseTimeUtc = closeTimeLocal.ConvertToUtc(exchangeHours.
TimeZone);
729 insight.Period = insight.CloseTimeUtc - insight.GeneratedTimeUtc;
737 private class EndOfTimeCloseTimePeriodSpecification : IPeriodSpecification
741 insight.Period = Time.EndOfTimeTimeSpan;
742 insight.CloseTimeUtc = Time.EndOfTime;