Seite 4 von 8
Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Samstag 10. Juli 2021, 19:17
von sparrow
Es sieht ein bisschen aus als hätte jemand versucht Java in Python zu programmieren.
Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Sonntag 11. Juli 2021, 19:00
von mirko3107
@LukeNukem: Wie bau ich da jetzt am besten den Rest vom Script ein?
Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Sonntag 11. Juli 2021, 22:40
von LukeNukem
mirko3107 hat geschrieben: Samstag 10. Juli 2021, 11:12
Code: Alles auswählen
rat1 = quote_req.json()['quoteResponse']['result'][0].get('averageAnalystRating', 'None')
rating=''
for i in rat1:
if i.isalpha():
rating = "".join([rating, i])
Oder gibts da noch bessere Möglichkeit als nur Buchstaben rausfiltern?
Ungetestet:
Code: Alles auswählen
def filter_alpha(value):
if isinstance(value, (bytes, str)):
return ''.join([c for c in value if c.isalpha()])
return value
df.rating = df.rating.apply(filter_alpha).astype('category')
Das ".astype()" muß nicht, konvertiert die Daten aber in kategorische Variablen, siehe dazu [1].
[1]
https://pandas.pydata.org/pandas-docs/s ... rical.html
Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Sonntag 11. Juli 2021, 22:51
von LukeNukem
mirko3107 hat geschrieben: Sonntag 11. Juli 2021, 19:00
@LukeNukem: Wie bau ich da jetzt am besten den Rest vom Script ein?
Du hast ja mehrere Teile, die die Daten aus unterschiedlichen Quellen ziehen und dann, zumindest teilweise, auf eine recht ähnliche Art konvertieren. Also nimmst Du Dir Deine anderen Programmteile und baust sie nach dem Vorbild um, das ich gezeigt habe. Das baust Du dann in den Hauptteil -- also: dem Teil unter "if __name__ ==..." ein, erzeugst aus Deinen neuen Klassen (bei mir: "YahooFun") also Instanzen (bei mir: "yf = YahooFun()"), übergibst die "Arbeitsfunktionen" (bei mir: "yahoo()") Deinem ThreadPoolExecutor und hängst die future-Objekte mit += an die Variable "futures" an.
Am Ende -- also: wenn alles durchgelaufen ist und alle future-Objekte in "futures" mit "result()" ihre Ergebnisse geliefert haben -- ziehst Du aus den genannten Instanzen dann Deine Pandas-DataFrames, wie ich in der letzten Zeile, baust mit "pandas.concat()" einen großen Ergebnis-Dataframe, und dann kannst Du damit viele lustige Dinge machen: sie einfach schnöde ausgeben, mit Altair oder Bokeh hübsche Plots daraus erzeugen, ganz wie Du lustig bist. Vorher würde ich Dir allerdings empfehlen, mal ein Python- und ein Pandas-Tutorial durchzuarbeiten... Viel Erfolg!

Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Montag 12. Juli 2021, 09:53
von mirko3107
LukeNukem hat geschrieben: Sonntag 11. Juli 2021, 22:40
mirko3107 hat geschrieben: Samstag 10. Juli 2021, 11:12
Code: Alles auswählen
rat1 = quote_req.json()['quoteResponse']['result'][0].get('averageAnalystRating', 'None')
rating=''
for i in rat1:
if i.isalpha():
rating = "".join([rating, i])
Oder gibts da noch bessere Möglichkeit als nur Buchstaben rausfiltern?
Ungetestet:
Code: Alles auswählen
def filter_alpha(value):
if isinstance(value, (bytes, str)):
return ''.join([c for c in value if c.isalpha()])
return value
df.rating = df.rating.apply(filter_alpha).astype('category')
Das ".astype()" muß nicht, konvertiert die Daten aber in kategorische Variablen, siehe dazu [1].
[1]
https://pandas.pydata.org/pandas-docs/s ... rical.html
Wenn ich über die gleiche URL wie die anderen Werte den Wert "averageAnalystRating" abfrage, bekomm ich ab der Hälfte der Ticker-Werte keinen Wert mehr ausgelesen,
alle anderen funktionieren weiterhin. Der Wert verschwindet scheinbar, auch wenn man im Browser den Link zu oft abfragt.
Ich bleib dann bei meiner anderen URL, die scheint dauerhaft zu funktionieren.
Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Montag 12. Juli 2021, 13:28
von LukeNukem
mirko3107 hat geschrieben: Montag 12. Juli 2021, 09:53
Wenn ich über die gleiche URL wie die anderen Werte den Wert "averageAnalystRating" abfrage, bekomm ich ab der Hälfte der Ticker-Werte keinen Wert mehr ausgelesen,
alle anderen funktionieren weiterhin. Der Wert verschwindet scheinbar, auch wenn man im Browser den Link zu oft abfragt.
Möglich, ja. Einige andere Beitragende in diesem Thread haben ja schon angedeutet, daß es da serverseitige Limitierungen gibt -- und bei Yahoo ist es sogar so, daß offenbar auch der User-Agent geprüft wird.
Es ist halt so, daß die Börsenbetreiber und verschiedene andere tatsächlich bemerkt haben, daß man Börsentickerdaten a) für gutes Geld verkaufen kann, man b) mit reinen Datenabfragen keine Werbeeinnahmen generiert, und c), daß der Betrieb eigener Server nun einmal Geld kostet -- und daß diese Server und deren Betrieb immer teurer werden, je häufiger jemand diese Daten abfragt und je mehr Jemande das tun.
Insofern bieten sich Dir nun verschiedene Möglichkeiten: die Anzahl Deiner Abfragen so zu reduzieren und / oder zu verlangsamen, daß sie die serverseitigen Rate Limits nicht auslösen. Das kann Dir allerdings morgen oder übermorgen wieder auf die Füße fallen, wenn der Anbieter Deiner Daten entscheidet, die Rate Limits zu verschärfen. Du kannst natürlich auch Deine aktuelle Strategie weiterverfolgen und Deine Daten aus verschiedenen freien Quellen zusammenstoppeln, aber das birgt verschiedene Gefahren: die Daten könnten veraltet oder auf mehr oder weniger subtile Weise inkonsistent sein, und jeder neue Anbieter könnte von heute auf morgen entscheiden, Deine Quellen abzuschalten, neue oder verschärfte Rate Limits einzuführen, ... oder, und, oder.
Die letzte Möglichkeit ist daher, ich weiß, ein bisschen unkonventionell, langfristig jedoch die vermutlich stabilste Lösung: Du suchst Dir einen kommerziellen Anbieter und bezahlst für Deine Daten... und natürlich für die Server und deren Betreiber, die Dir diese Daten bereitstellen.
HTH, YMMV.

Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Montag 12. Juli 2021, 15:09
von mirko3107
LukeNukem hat geschrieben: Sonntag 11. Juli 2021, 22:51
mirko3107 hat geschrieben: Sonntag 11. Juli 2021, 19:00
@LukeNukem: Wie bau ich da jetzt am besten den Rest vom Script ein?
Du hast ja mehrere Teile, die die Daten aus unterschiedlichen Quellen ziehen und dann, zumindest teilweise, auf eine recht ähnliche Art konvertieren. Also nimmst Du Dir Deine anderen Programmteile und baust sie nach dem Vorbild um, das ich gezeigt habe. Das baust Du dann in den Hauptteil -- also: dem Teil unter "if __name__ ==..." ein, erzeugst aus Deinen neuen Klassen (bei mir: "YahooFun") also Instanzen (bei mir: "yf = YahooFun()"), übergibst die "Arbeitsfunktionen" (bei mir: "yahoo()") Deinem ThreadPoolExecutor und hängst die future-Objekte mit += an die Variable "futures" an.
Am Ende -- also: wenn alles durchgelaufen ist und alle future-Objekte in "futures" mit "result()" ihre Ergebnisse geliefert haben -- ziehst Du aus den genannten Instanzen dann Deine Pandas-DataFrames, wie ich in der letzten Zeile, baust mit "pandas.concat()" einen großen Ergebnis-Dataframe, und dann kannst Du damit viele lustige Dinge machen: sie einfach schnöde ausgeben, mit Altair oder Bokeh hübsche Plots daraus erzeugen, ganz wie Du lustig bist. Vorher würde ich Dir allerdings empfehlen, mal ein Python- und ein Pandas-Tutorial durchzuarbeiten... Viel Erfolg!
Sollte ich die RSI/SMA-Berechnung auch mit in die yahoo-Funktion einbauen oder eine eigene Funktion dafür erstellen?
Für die Datenabfrage zu IB wäre sicherlich eine neue Class nötig, oder?
Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Montag 12. Juli 2021, 15:58
von rogerb
Insofern bieten sich Dir nun verschiedene Möglichkeiten: die Anzahl Deiner Abfragen so zu reduzieren und / oder zu verlangsamen, daß sie die serverseitigen Rate Limits nicht auslösen.
Dass wir jetzt wieder an dem Punkte angelangt sind, auf den so viele schon von Anfang an hingewiesen hatten, ist dann aber doch irgendwie bemerkenswert.
Lösung: Du suchst Dir einen kommerziellen Anbieter und bezahlst für Deine Daten... und natürlich für die Server und deren Betreiber, die Dir diese Daten bereitstellen
Warum eine Tankstelle kaufen, wenn man nur tanken will?
Der kommerzielle Anbieter ist Yahoo (Oder jede andere Plattform, die Finanzdaten zur Verfügung stellt). Nur muss man denen eben ein bischen Geld geben wenn man große Mengen an Daten ziehen will.
Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Montag 12. Juli 2021, 16:02
von mirko3107
Betrifft scheinbar nur diesen einen Wert und ein paar andere unwichtige, daher nicht weiter tragisch.
Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Mittwoch 14. Juli 2021, 16:27
von mirko3107
@LukeNukem: Ich muss mittlerweile zugeben, ich bekomm es nicht so eingebaut, wie du es mir vorgeschlagen hast. Könntest du mir noch einen kleinen Tip geben oder einen Einstieg, wie ich das am besten umsetze?
Momentan hab ich die ganzen Berechnungssachen mit in die yahoo-Funktion eingebaut, aber ich denke mal, so war das von dir nicht gemeint.
Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Donnerstag 15. Juli 2021, 03:34
von LukeNukem
mirko3107 hat geschrieben: Mittwoch 14. Juli 2021, 16:27
@LukeNukem: Ich muss mittlerweile zugeben, ich bekomm es nicht so eingebaut, wie du es mir vorgeschlagen hast.
Könntest du mir noch einen kleinen Tip geben oder einen Einstieg, wie ich das am besten umsetze?
Na klar, gerne... aber ich bin mir nicht ganz sicher, ob er Dir gefallen wird. Mein Tipp ist, erst die Grundlagen von Python und dann die von Pandas zu lernen. Also... nicht den Schlangen und den Bären, wohlgemerkt.
mirko3107 hat geschrieben: Mittwoch 14. Juli 2021, 16:27
Momentan hab ich die ganzen Berechnungssachen mit in die yahoo-Funktion eingebaut, aber ich denke mal, so war das von dir nicht gemeint.
Naja... mein ganzer Ansatz ist halt ein anderer als Deiner. Und damit meine ich nicht die Datenverarbeitung, sondern vor allem das Laufzeitmodell.
Mein Programmdesign betreibt einen zentralen ThreadPoolExecutor. Der ist dazu da, Deine Funktionen zu verwalten. Dem kannst Du (im Prinzip) so viele Funktionen übergeben, wie Du willst. Das können auch ganz verschiedene Funktionen sein: er wird sie in einem seiner Threads aufrufen, abwarten bis sie durchgelaufen ist und ein Ergebnis produziert hat. Und dann nimmt er sich die nächste wartende Funktion vor... so lange, bis alle Funktionen abgearbeitet sind [1]. Yay!
Außerdem gibt es einen zweiten großen Designunterschied: ich betrachte jeden Download -- also: jeden Ticker von jeder URL -- als einen Funktionsaufruf. (Eigentlich einen Methodenaufruf, aber geschenkt...) Dagegen betrachtet Deine Software jede Quelle als einen Funktionsaufruf. Anders gesagt: Du hast für jede Quelle eine Funktion, die aufgerufen wird, ich dagegen habe eine Funktion (Methode), die für jede Quelle + Ticker an den ThreadPoolExecutor übergeben wird.
Diese beiden Umstände bedeuten im Umkehrschluß: entweder, Du behältst Dein bisheriges Design bei und kannst dann höchstens meine Ideen zum Auslesen der Daten aus den Responses übernehmen. Oder, Du wirfst Deine bisherigen Lösungsansätze über den Haufen und baust Deine Software nach meinem Design um. Zumindest der zweite Ansatz wird es allerdings erfordern, daß Du Dir die Grundlagen von Python und die von Pandas aneignest. Und genau das möchte ich Dir aller-, aller-, aller- und allerwärmstens empfehlen. Die Idee meiner Idee ist nicht, sie zu kopieren. Sondern, sie zu verstehen und zu adaptieren.
[1] Für meine pedantisch orientierten Freunde: das ist nur teilweise korrekt, aber sei's drum.

Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Donnerstag 15. Juli 2021, 05:58
von mirko3107
Ich hab jetzt alles, was von yahoo kommt, in die Yahoo-Class eingebaut, da lieg ich pro Abruf bei knapp 1s, völlig ausreichend.
Ich habe jetzt versucht, den IB-Part einzubauen, aber da meldet er mir folgendes:
Code: Alles auswählen
File "/usr/lib/python3.9/asyncio/events.py", line 642, in get_event_loop
raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'ThreadPoolExecutor-0_0'.
sys:1: RuntimeWarning: coroutine 'IB.connectAsync' was never awaited
Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Donnerstag 15. Juli 2021, 06:34
von Sirius3
Das hatten wir doch schon vor Tagen. Sowohl multiprocessing als auch threads sind falsch. Schreibe asynchron Funktionen. Lass dich von anderen Mitschreibenden nicht in die Irre führen. Am besten fängt man mit einem sehr einfachen Beispiel an, dass z.b. asynchrone Funktionsaufrufen verschiedene Dataframes zurückgeben, die Du dann zu kombinieren versuchst.
Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Donnerstag 15. Juli 2021, 08:18
von rogerb
@mirko3107,
wenn du nach "ib_insync threading" suchst, wirst du schnell merken, dass du nicht der einzige bist, der es so versucht hat und nicht weiter gekommen ist.
Die Antwort war aber immer: "Benutze asyncio"
Ich kann die Hemmschwelle bzgl. asyncio durchaus verstehen. So schwer ist es aber gar nicht wenn man sich etwas einliest.
ib_insync ist so geschrieben, dass es sich nach außen anfühlt, als ob es einfach synchron abläuft. Das funktioniert bei einzelnen Datenabfragen auch noch problemlos. Wenn man aber mal in den Sourcecode schaut, sieht man, dass alle Datenabfragen asynchron ablaufen.
Daher würde jeder, der sich da ein wenig auskennt, die Applikation drum herum auch asynchron schreiben.
Ich kann es bei mir leider nicht ausprobieren, da man dafür anscheinen einen Zugang braucht.
Das ist das Beispiel aus der ib_insync Dokumentation mit asynchronem Aufruf für mehrere Symbole.
So würde ich anfangen, wenn ich es ausprobieren könnte. Nur ein Versuch und ungetestet.
(Wie man sich die Daten von Yahoo holt, hatte ich ja schon in einem früheren Post gezeigt)
Code: Alles auswählen
import asyncio
from ib_insync import IB, Forex
ib = IB()
ib.connect('127.0.0.1', 7497, clientId=1)
async def get_data(symbol):
contract = Forex(symbol)
bars = await ib.reqHistoricalData(
contract, endDateTime='', durationStr='30 D',
barSizeSetting='1 hour', whatToShow='MIDPOINT', useRTH=True)
return bars
async def main():
# holt die historischen Daten der angegebenen Symbole
all_data = await asyncio.gather(*[get_data(symbol) for symbol in ["FOREX", "AMZN", "GOOG"]])
# all_data enthält Liste aller Daten
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Donnerstag 15. Juli 2021, 19:25
von mirko3107
Es muss ja nicht unbedingt async sein bei ib_insync, mir reicht es, wenn der Teil so mal mit durchläuft. Die Werte, die da ausgespuckt werden, ändern sich nicht stündlich.
Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Freitag 16. Juli 2021, 18:39
von mirko3107
Ich habe jetzt einiges probiert, aber mit wenig Erfolg.
Ich hab mein Script vom Beginn mal wieder rausgekramt und wollte da Dinge einbauen, die in den letzten Tage denke gelernt zu haben, besser gesagt gelesen.
Das Script funktioniert im Grunde, nicht schön wie ihr durchaus bemerkt habt, aber läuft.
Wenn ich aus meiner CSV-Datei per
Code: Alles auswählen
yf_df = pd.read_csv(file, sep=',')
tickers = yf_df.Ticker.tolist()
eine Ticker-Liste erstelle und diese dann per
Code: Alles auswählen
p1 = multiprocessing.Process(target=rsi, args = (tickers, ))
an den jeweiligen Prozess schicke, läuft zb. dieser hier durch:
Code: Alles auswählen
def rsi(tickers):
rsilist = []
while True:
for ticker in tickers:
try:
rsi = pdr.get_data_yahoo(ticker, dt.datetime(2021, 5, 1), dt.datetime.now(),session=session)
delta = rsi['Close'].diff()
up = delta.clip(lower=0)
down = -1 * delta.clip(upper=0)
ema_up = up.ewm(com=13, adjust=False).mean()
ema_down = down.ewm(com=13, adjust=False).mean()
rs = ema_up / ema_down
rsi['RSI'] = 100 - (100 / (1 + rs))
rsi_value = rsi.iloc[-1]['RSI']
print(ticker, rsi_value)
rsilist.append(rsi_value)
except Exception as e:
logging.exception('Something went terribly wrong')
return [0.0] * 4
Wie bekomm ich die Ergebnisse dieses Prozesses wieder aus diesem heraus?
Vielen Dank
Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Samstag 17. Juli 2021, 11:01
von LukeNukem
mirko3107 hat geschrieben: Freitag 16. Juli 2021, 18:39
Wie bekomm ich die Ergebnisse dieses Prozesses wieder aus diesem heraus?
Naja, wenn Du es mit Multiprocessing machst, dann müssen die Daten natürlich vom sendenden Prozeß serialisiert werden -- etwa mit pandas.DataFrame.to_pickle() und vom lesenden Prozeß wieder deserialisiert werden, beispielsweise mit pandas.read_pickle(). Aber die Kollegen haben natürlich Recht: wenn dieses ib-Dingsi asynchron arbeitet, solltest Du beim Rest ebenfalls asynchron arbeiten. Man kann die Ansätze zwar mischen, aber... dazu sollte man UNBEDINGT und sehr GENAU wissen, was man tut und warum man es tut.

Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Samstag 17. Juli 2021, 12:26
von mirko3107
Also mit async und ib_insync hatte ich bisher keinen Erfolg, per multiprocessing läuft es aber, reicht mir völlig.
MIt multiprocessing.Pool ist es aber nicht möglich, Funktionen parallel auszuführen, oder?
Hab einen Pool für yahoo mit 4 Prozessen und einen Pool für ib_insync mit 1 Prozess, welche aber nacheinander laufen.
Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Samstag 17. Juli 2021, 12:48
von __deets__
Sinn und Zweck von multiprocessing *ist* Parallelitaet. Wenn das bei dir nicht parallel laeuft, ist da was komisch.
Re: Dataframes aus verschiedenen Prozessen zusammenfügen
Verfasst: Samstag 17. Juli 2021, 13:19
von mirko3107
die Funktionen, die ich aufrufe, laufen auch parallel in mehreren Prozessen (ausser ib_insync), aber ich hab es nicht hinbekommen, während Funktion "Yahoo" läuft, parallel dazu die Funktion "IB" laufen zu lassen.