|
Gruppen: Kunde
Beiträge: 16
|
Hallo liebes Forum. Ich versuche das Datastream Objekt zu nutzen. Meine Anwendung ist hier wohl etwas "Offroad" da in Python. Prinzipiell sind die Methoden nahe am vba gehalten durch die pycom und win32com libraries. Code:
import win32com.client
com = win32com.client.Dispatch("TaiPanRealtime.Application")
com.Database.Watchlisten.Count #works okay
# fetch stream object str_obj = com.Datastream
# add symbol to stream str_obj.Add(78303,1)
# how to access stream data from here ?? # tried: str_obj.Fetch str_obj.Show
for item in str_obj: # not itterable # nothing works
Wie bekomme ich nun Zugriff auf diesen Datastream? Welche Methode ist dafür vorgesehen? Leider kann ich keine links in der TaiPan Hilfe anklicken. Diese führen zum Einfrieren der Hilfe. Daher liegt mir das Gesamt beispiel nicht vor. Bitte um Denkanstoß. Danke und Gruß
|
|
Gruppen: Kunde
Beiträge: 16
|
i didi it.... Hier ein Modell welches Thread safe ist. Es ist noch etwas basic aber läuft. ein thread je watchlist. Hat TaiPan Realtime hier limits was die Anzahl der Elemente angeht? Code:
import win32com.client import pythoncom import time
import threading
# openup com interface to TaiPan com = win32com.client.Dispatch("TaiPanRealtime.Application")
# connect Database and Stream to object database = com.DataBase stream = com.DataStream
# Theese lists are fetched from TaiPan lists = [ 'FOREX', 'XETRA' ]
################################################################################################################################################## ################################################################################################################################################## ##################################################################################################################################################
def create_data_dict(target_wa):
# need watchlistname from TaiPan as arg
t_dict = {} t_dict['names'] = [] t_dict['db_num'] = [] t_dict['price'] = {}
for i in range( len(database.WatchListen) ):
wa_list = database.Watch(i+1)
if wa_list.Name == target_wa:
for item in wa_list:
name = item.Name.replace(" ", "_")
t_dict['names'].append(name) t_dict['db_num'].append(item.SymbolNr) t_dict['price'][name] = item.Aktuell
return t_dict
def launch_stream(t_dict,xl_id):
pythoncom.CoInitialize() l_com = win32com.client.Dispatch( pythoncom.CoGetInterfaceAndReleaseStream(xl_id, pythoncom.IID_IDispatch) ) stream = l_com.DataStream
def set_value(self, SymbolNr, Kurs, Volume, Zeit):
g_spot = t_dict['db_num'].index( SymbolNr ) name = t_dict['names'][g_spot]
t_dict['price'][name] = Kurs
#if name == 'EUR/NOK_JFD': # print( name, " = ", t_dict['price']['EUR/NOK_JFD'] )
if name == 'INAV_iShares_SMI_(DE)': print( name, " = ", t_dict['price']['INAV_iShares_SMI_(DE)'] )
#print(name)
class EventHandler:
# {1: 'OnBezahlt', 2: 'OnBrief', 3: 'OnGeld', 4: 'OnBriefMT', 5: 'OnGeldMT', 6: 'OnStatus', 7: 'OnAktuellMeldung', 8: 'OnOpenInterest', 9: 'OnKorrekturOpen', 10: 'OnKorrekturHigh', 11: 'OnKorrekturLow', 12: 'OnKorrekturVolume', 13: 'OnIndiKurs', 14: 'OnNews', 15: 'OnReload', 16: 'OnExEvent'}
def OnBezahlt(self, SymbolNr, Kurs, Volume, Zeit):
set_value(self, SymbolNr, Kurs, Volume, Zeit)
def OnBrief(self, SymbolNr, Kurs, Volume, Zeit):
set_value(self, SymbolNr, Kurs, Volume, Zeit)
def OnGeld(self, SymbolNr, Kurs, Volume, Zeit):
set_value(self, SymbolNr, Kurs, Volume, Zeit)
for ident in t_dict['db_num']:
stream.Add( ident , 0 ) # clearify what this 0 has to do
events = win32com.client.WithEvents(stream, EventHandler)
while True: pythoncom.PumpWaitingMessages() time.sleep(0.0001)
################################################################################################################################################## ################################################################################################################################################## ##################################################################################################################################################
for item in lists:
item = create_data_dict(item)
instance = win32com.client.Dispatch('TaiPanRealtime.Application') instance_id = pythoncom.CoMarshalInterThreadInterfaceInStream(pythoncom.IID_IDispatch, instance)
threading.Thread( target=launch_stream, args=(item,instance_id) ).start()
|
|
Gruppen: Mitarbeiter
Beiträge: 54
|
Hallo Herr Oelze, wir haben uns bemüht keine Limitierungen in TAI-PAN Realtime einzubauen (lediglich bei einigen sonder-Produkten ist die Anzahl begrenzt - in diesem Fall sind die Begenzungen aber ausdrücklich ausgewiesen und den Kunden bekannt). Je nach Implementierung des Quellcode, Rechenleistung des Computers oder Bandbreite der Internetverbindung kann es jedoch zu Engpässen kommen. (in der Regel sollte aber eine Anzahl im zehntausender-Bereich kein Problem darstellen). ggf kann Ihnen diese (noch im Aufbau befindliche) Webseite etwas weiter helfen. http://www.tai-pan.net/produkte/tpr/index.aspx(bitte beachten Sie, dass auch hier viele Links nicht funktionieren da Sie nur vorbereitet wurden - es wird nur an der Hilfe gearbeitet wenn gerade etwas Zeit übrig ist)
Entwicklung | Lenz+Partner GmbH | vwd group Phone: +49 231 9153-300 | Fax: +49 231 9153-399 entwicklung@lp-software.de | www.LP-software.de | www.vwd.com
|
|
Gruppen: Kunde
Beiträge: 16
|
Hallo Herr Beyersdorf
Vielen Dank. Das hilft Weiter
Mit freundlichen Grüßen
|
|
Gruppen: Mitarbeiter
Beiträge: 54
|
Ich habe gerade gesehen, dass in der Online-Doku auch noch eine wichtige Verbesserung fehlt. Die COM-Schnittstelle ist zwar fix, bricht aber irgendwann unter der schiren Masse von (gleichzeitig) gefeuerten Events ein. Man Kann die Pushdaten auch mit weniger COM-Events abschürfen: Code:var datastreamEx = m_datastream as IDataStreamEx; datastreamEx.EnableExEvent(); m_datastream.ExEvent += M_datastream_ExEvent; der Trick ist hier, dass nicht unterschiedliche Events gefeuert werden sondern immer nur das gleiche mit der Information darin um welches Event es sich handelt. Hier stückchen aus einem Beispielcode den ich intern gefunden habe. Code: public partial class Form1 : Form { private TaiPanRealtime m_tpr = null; private DataStream m_datastream = null;
private void cmdStart_Click(object sender, EventArgs e) { if( m_tpr == null ) { m_tpr = new TaiPanRealtime();
m_datastream = m_tpr.DataStream as DataStream; var datastreamEx = m_datastream as IDataStreamEx; datastreamEx.EnableExEvent(); m_datastream.ExEvent += M_datastream_ExEvent;
List<int> symbols = getSymbols(); foreach( var symbol in symbols ) { m_datastream.Add(symbol, 1); } } } private void M_datastream_ExEvent([System.Runtime.InteropServices.ComAliasName("TaiPanRTLib.TPRStreamEventID")] TPRStreamEventID nEventID, int SymbolNr, float Kurs, float Volume, DateTime Zeit, int LongValue) { switch( nEventID ) { case TPRStreamEventID.TPRStreamEvent_Price: M_datastream_Bezahlt(SymbolNr, Kurs, Volume, Zeit); break; case TPRStreamEventID.TPRStreamEvent_Bid: M_datastream_Geld(SymbolNr, Kurs, Volume, Zeit); break; case TPRStreamEventID.TPRStreamEvent_Ask: M_datastream_Brief(SymbolNr, Kurs, Volume, Zeit); break; case TPRStreamEventID.TPRStreamEvent_MDBid: break; case TPRStreamEventID.TPRStreamEvent_MDAsk: break; case TPRStreamEventID.TPRStreamEvent_OI: break; case TPRStreamEventID.TPRStreamEvent_OpenCorrection: break; case TPRStreamEventID.TPRStreamEvent_HighCorrection: break; case TPRStreamEventID.TPRStreamEvent_LowCorrection: break; case TPRStreamEventID.TPRStreamEvent_VolumeCorrection: break; case TPRStreamEventID.TPRStreamEvent_AuctionPrice: break; case TPRStreamEventID.TPRStreamEvent_Status: break; default: break; } } private void M_datastream_Brief(int SymbolNr, float Kurs, float Volume, DateTime Zeit) { Debug.WriteLine($" {Kurs}"); } private void M_datastream_Geld(int SymbolNr, float Kurs, float Volume, DateTime Zeit) { Debug.WriteLine($" {Kurs}"); } private void M_datastream_Bezahlt(int SymbolNr, float Kurs, float Volume, DateTime Zeit) { Debug.WriteLine($"{Kurs}"); }
// private List<int> getSymbols() { return new List<int>() { //30 DAX-Werte 79514, 55267788, 369001, 78290, 365550, 169286, 450966, 78275, 78340, 78265, 585410, 78267, 78314, 297469, 78337, 78298, 78365, 78303, 162235, 78296, 8421267, 141184, 78350, 78317, 589677, 78311, 78292, 624857, 78319, 78273, 78274 }; } }
Ich werde versuchen den Quelltext noch etwas zu verallgemeinern und dann auf die TAI-PAN.net Seite stellen.
Entwicklung | Lenz+Partner GmbH | vwd group Phone: +49 231 9153-300 | Fax: +49 231 9153-399 entwicklung@lp-software.de | www.LP-software.de | www.vwd.com
|
|
Gruppen: Kunde
Beiträge: 16
|
Hallo Herr Beyersdorf. Ich habe das Wochenende genutzt meine Python Implementation durch ein c# Programm zu ersetzen. Ich war in der Tat mit zu vielen Events konfrontiert. Jedoch ist es bei meinem Anwendungsfall nutwendig die Börsen voneinander zu trennen. Das hat zur folge das für jede dieser börsen ein gesonderter Thread zu bzw. abschaltet gemäß der Öffnungszeiten in der jeweiligen Zeitzone. Jede Börse hat sein eigenes globales Dictionary. In Ihrem snippet besteht die Annahme das nur ein "Grabber" die Events abfischt. Da meine Fähigkeiten in C# etwas bescheiden sind frage ich mich wie ich das für parallele Threads nutzen kann. So wich ich Ihren Ansatz verstehe, nimmt diese Passage: Code: ...... private void M_datastream_ExEvent([System.Runtime.InteropServices.ComAliasName("TaiPanRTLib.TPRStreamEventID")] TPRStreamEventID nEventID, int SymbolNr, float Kurs, float Volume, DateTime Zeit, int LongValue) ......
bezug auf ein Globales COM event. Dies bedeutet das wenn ich im Thread-1 Symbolnummern einfüge, diese nun auch im Thread-2 oder thread-3 erkannt werden und dort meine jeweilige Funktion triggern. Haben Sie einen Vorschlag zu einer Vorgehensweise, die meinem Anwendungsfall gerecht wird? Ich trenne die Börsen per Watchlists in der TaiPan Realtime Anwendung. Mit freundlichen Grüßen Stephan Oelze
|
|
Gruppen: Kunde
Beiträge: 16
|
Hallo Herr Beyersdorf. Ich habe Ihren snipped nun übernommen, jedoch feuert er keinerlei events. Den Block habe ich mal auf Pastebin hochgeladen. Die Variablennamen habe ich übernommen. https://pastebin.com/hhAwAeNnEs werden keine events gefeuert, die applikation braucht jedoch CPU. Daher scheinen die events aufzulaufen, landen jedoch nicht im korrekten Kanal. Können Sie mir einen Denkanstoß geben? Ich bin ja nahezu am Ziel. Mit freundlichen Grüßen Stephan Oelze EDIT: Selbst dieses stark vereinfachte Model feuert keine events: https://pastebin.com/cRWtNbgeIch weiß nicht, was ich falsch mache.
|
|
Gruppen: Mitarbeiter
Beiträge: 54
|
Die Lösung des Problems wurde gefunden. Es ist darauf zu achten, daß im Solution Explorer unter References in den Eigenschaften von 'TaiPanRTLib' die Option 'Embed Interop Types' auf False steht.
Entwicklung | Lenz+Partner GmbH | vwd group Phone: +49 231 9153-300 | Fax: +49 231 9153-399 entwicklung@lp-software.de | www.LP-software.de | www.vwd.com
|
|
Guest |