Unit NewDayDetector; // The exchange decides when to reset the daily high and low prices. We // maintain the high and low bid and ask values, and similar data, ourselves. // We want to reset these as the same time as the exchange resets the high // and low prices. Interface Uses DataNodes, GenericL1DataNode, Prices, Classes, SysUtils; Type TNewDay = Class(TDataNodeWithStringKey) Public Class Procedure Find(Symbol : String; OnChange : TThreadMethod; Out Link : TDataNodeLink); Class Procedure FindDebug(Symbol : String; OnChange : TThreadMethod; Out Node : TNewDay; Out Link : TDataNodeLink); Protected Class Function CreateNew(Data : String) : TDataNodeWithStringKey; Override; Private Data : TGenericL1DataNode; FSymbol : String; LastHigh, LastLow : Double; Constructor Create(Symbol : String); Procedure Init; Procedure GetCurrent; Procedure NewData; End; Implementation Uses GenericDataNodes, AlertBase; //////////////////////////////////////////////////////////////////////// // TNewDay //////////////////////////////////////////////////////////////////////// Class Procedure TNewDay.Find(Symbol : String; OnChange : TThreadMethod; Out Link : TDataNodeLink); Var TempNode : TDataNodeWithStringKey; Begin FindCommon(TNewDay, Symbol, OnChange, TempNode, Link) End; Class Procedure TNewDay.FindDebug(Symbol : String; OnChange : TThreadMethod; Out Node : TNewDay; Out Link : TDataNodeLink); Var TempNode : TDataNodeWithStringKey; Begin FindCommon(TNewDay, Symbol, OnChange, TempNode, Link); Node := TNewDay(TempNode) End; Class Function TNewDay.CreateNew(Data : String) : TDataNodeWithStringKey; Begin Result := Create(Data) End; Constructor TNewDay.Create(Symbol : String); Begin Inherited Create; FSymbol := Symbol; DoInCorrectThread(Init) End; Procedure TNewDay.Init; Var Link : TDataNodeLink; Begin TGenericL1DataNode.Find(FSymbol, NewData, Data, Link); AddAutoLink(Link); Link.SetReceiveInput(True); GetCurrent End; Procedure TNewDay.NewData; Begin If Data.IsValid Then If (LastHigh <> LastLow) And (Data.GetCurrent.High = Data.GetCurrent.Low) And (Data.GetCurrent.High <> 0) And (Data.GetCurrent.Low <> 0) Then NotifyListeners; GetCurrent End; Procedure TNewDay.GetCurrent; Begin If Data.IsValid Then Begin LastHigh := Data.GetCurrent.High; LastLow := Data.GetCurrent.Low End Else Begin LastHigh := 0; LastLow := 0 End End; //////////////////////////////////////////////////////////////////////// // TNewDayAlert // // This is just test/debugging code for TNewDay. This lets us watch // what the exchange is doing to us and when. Not for end user // consumption. //////////////////////////////////////////////////////////////////////// Type TNewDayAlert = Class(TAlert) Private NewDay : TNewDay; L1 : TGenericL1DataNode; Procedure OnNewDay; Protected Constructor Create(Params : TParamList); Override; End; Constructor TNewDayAlert.Create(Params : TParamList); Var Symbol : String; Link : TDataNodeLink; Begin Inherited Create; Assert(Length(Params)=1); Symbol := Params[0]; TNewDay.FindDebug(Symbol, OnNewDay, NewDay, Link); AddAutoLink(Link); TGenericL1DataNode.Find(Symbol, Nil, L1, Link); AddAutoLink(Link) End; Procedure TNewDayAlert.OnNewDay; Begin Report(Format('New Day! Low: (%s --> %s) High: (%s --> %s)', [FormatPrice(NewDay.LastLow), FormatPrice(L1.GetCurrent.Low), FormatPrice(NewDay.LastHigh), FormatPrice(L1.GetCurrent.High)])) End; //////////////////////////////////////////////////////////////////////// // Initialization //////////////////////////////////////////////////////////////////////// Initialization TGenericDataNodeFactory.StoreStandardFactory('NewDay', TNewDayAlert); End.