Unit NxCoreRegionalProxy; { This is a minimum job to handle the alerts that were working in the pure TAL/ Delphi alert server. We could try to make this more general. But there doesn't seem to be much interest in this type of data. We are only tracking the bid and ask prices, only tracking them on the NYSE, and only tracking them for specific stocks. There is a seperate way to request this data vs NBBO, last print, etc. Presumably we'll only be watching this for stocks listed on the NYSE. } Interface Uses DataNodes, ProxyListenerBaseUnit, MessageQueues, Classes; Type TNxCoreRegionalsData = Record BidPrice : Double; AskPrice : Double; End; TNxCoreRegionalsMessageInfo = Class(TBroadcastMessage) Private FData : TNxCoreRegionalsData; Public Property Data : TNxCoreRegionalsData Read FData Write FData; End; TNxCoreRegionalsProxy = Class(TProxyListenerBase) Private FSymbol : String; FValid : Boolean; FData : TNxCoreRegionalsData; FLastBid, FLastAsk : Double; Procedure Initialize; Procedure Send(AlwaysSend : Boolean); Procedure NewRegionalsData(Msg : TBroadcastMessage; Owner : TDataNode); Constructor Create(Const Symbol : String; MessageQueue : TMessageQueue); Protected Procedure OnRestartOutput; Override; Class Function CreateNew(Data : String) : TDataNodeWithStringKey; Override; Public Class Procedure Find(Symbol : String; MessageQueue : TMessageQueue; OnChange : TThreadMethod; Out Node : TProxyListenerBase; Out Link : TDataNodeLink); End; Implementation Uses DataFormats, TalkWithServer, DebugOutput, StrUtils, SysUtils; Constructor TNxCoreRegionalsProxy.Create(Const Symbol : String; MessageQueue : TMessageQueue); Begin Try FSymbol := Symbol; FValid := True; FMessageQueue := MessageQueue; Inherited Create; DoInCorrectThread(Initialize); If OutputStarted Then // If someone was already listening to this data node then we will have // data already, and we should push that to the user. Note that noone // is listening our NotifyListeners yet, so anyone who creates one of // these should immediately check their queue. OnRestartOutput Except On Ex : Exception Do Begin DebugOutputWindow.AddMessage(Ex, 'TL1Proxy.Create') End End End; Procedure TNxCoreRegionalsProxy.Initialize; Begin RegisterForBroadcast('REGIONAL-' + FSymbol, NewRegionalsData) End; Procedure TNxCoreRegionalsProxy.Send(AlwaysSend : Boolean); Var SomethingSent : Boolean; Procedure SendField(Const NameOnWire : String; Current : Double; Var Last : Double); Var Encoded : String; Msg : TMessageToServer; Begin { SendField } If AlwaysSend Or (Current <> Last) Then Begin Last := Current; SetLength(Encoded, SizeOf(Double)); PDouble(PChar(Encoded))^ := Current; SetLength(Msg, 3); Msg[0].Name := WireCommand; Msg[0].Value := NameOnWire; Msg[1].Name := WireSymbol; Msg[1].Value := FSymbol; Msg[2].Name := WireBody; Msg[2].Value := Encoded; FMessageQueue.AddToQueue(Msg); SomethingSent := True End End; { SendField } Begin { TRegionalsProxy.Send } SomethingSent := False; If FValid Then Begin SendField(WireNyseBidData, FData.BidPrice, FLastBid); SendField(WireNyseAskData, FData.AskPrice, FLastAsk) End Else Begin SendField(WireNyseBidData, 0.0, FLastBid); SendField(WireNyseAskData, 0.0, FLastAsk) End; If SomethingSent Then NotifyListeners End; { TRegionalsProxy.Send } Procedure TNxCoreRegionalsProxy.NewRegionalsData(Msg : TBroadcastMessage; Owner : TDataNode); Begin FValid := True; FData := (Msg as TNxCoreRegionalsMessageInfo).Data; If OutputStarted Then Send(False) End; Procedure TNxCoreRegionalsProxy.OnRestartOutput; Begin Send(True) End; Class Function TNxCoreRegionalsProxy.CreateNew(Data : String) : TDataNodeWithStringKey; Var Symbol : String; MessageQueue : TMessageQueue; Begin MessageQueue := TObject(PInteger(PChar(Data))^) As TMessageQueue; Symbol := MidBStr(Data, 5, MaxInt); //DebugOutputWindow.AddMessage('About to create: ' + Symbol); Result := Create(Symbol, MessageQueue) //DebugOutputWindow.AddMessage('Created: ' + Symbol); End; Class Procedure TNxCoreRegionalsProxy.Find(Symbol : String; MessageQueue : TMessageQueue; OnChange : TThreadMethod; Out Node : TProxyListenerBase; Out Link : TDataNodeLink); Var Encoded : String; TempNode : TDataNodeWithStringKey; Begin //DebugOutputWindow.AddMessage('About to find: ' + Symbol); Encoded := 'XXXX' + Symbol; PInteger(PChar(Encoded))^ := Integer(MessageQueue); FindCommon(TNxCoreRegionalsProxy, Encoded, OnChange, TempNode, Link); Node := TempNode As TProxyListenerBase //DebugOutputWindow.AddMessage('Found: ' + Symbol); End; End.