Erweiterte Plattformforschung Python-Datenanalyse und Strategie-Backtest

Schriftsteller:- Ich bin ein Idiot., Erstellt: 2022-04-13 09:12:47, Aktualisiert: 2022-04-28 11:06:13

Erweiterte Plattformforschung Python Datenanalyse & Strategie Backtest.ipynb

Fortgeschrittene Plattformforschung

FMZ verfügt über ein integriertes jupyter-Notebook, das Benutzern hilft, sich mit der Plattform-API vertraut zu machen und Strategieforschung durchzuführen, und unterstützt die Lernumgebungen von Python3 C++11/17 und Javascript. Notebook+Python ist ein sehr leistungsstarkes Tool, das für Datenanalyse und Strategieforschung fast unverzichtbar ist. Obwohl der Backtest, der mit der FMZ-Plattform geliefert wird, sehr nützlich ist, ist er nicht für Strategien mit komplexen und großen Datenmengen geeignet. Dieser Artikel wird einige fortgeschrittene Fähigkeiten mit jupyter-Notebook vorstellen und Backtests von zufälligen Paare und Multi-Paar-Handelsstrategien realisieren.

Verwendung von Jupyter

Die Forschungsumgebung innerhalb des FMZ kann genutzt werden, aber die Vernetzung ist unbequem. Es wird empfohlen, die Anaconda3 mit Notebook und häufig verwendeten verwandten Bibliotheken für mathematische Berechnungen auf Ihrem eigenen Gerät zu installieren; sie kann die lokale Netzwerkumgebung teilen und eine bessere Leistung haben. Es wird auch empfohlen, Google Collab zu verwenden. Obwohl es einige Speicherbeschränkungen gibt, ist sie kostenlos und leistungsstark, geeignet für die Forschung im Zusammenhang mit dem Roboterstudium.

Tutorial

Es gibt viele Online-Tutorials für spezifische Benutzerfähigkeiten von Notebook und Python. Sie können viele Informationen durch Suche nach Schlüsselwörtern wie Python Quantification und jupyter Notebook Tutorial finden. Sie müssen eine Reihe von Grundlagen wie Crawler, Datenverarbeitung, Backtest, Strategieentwicklung und Plotting lernen und beherrschen.

Datenerfassung

Plattformen bieten in der Regel APIs, um K-Linien mit Historiedaten zu erhalten, und einige liefern auch Daten der Ausführung von Handel nach Handel. Wir müssen den Crawler verwenden, um die Daten zu erhalten und zu speichern.

Als nächstes werden wir zeigen, wie man die K-Line-Daten von Perpetual Contracts auf Binance erhält und speichert.

Zuerst finden Sie die Dokumentation für den Binance Perpetual Swap:https://binance-docs.github.io/apidocs/futures/cn/#c59e471e81. Sie können die erforderlichen Parameter und die zurückgegebenen Datenformate anzeigen. Normalerweise ist die Anzahl der von der API erworbenen K-Linien begrenzt, Binance hat maximal 1000, daher muss sie durch Schleifeniteration erworben werden. Die Situation auf anderen Plattformen ist ähnlich wie bei Binance. Beachten Sie, dass das Netzwerk mit dem ausländischen Netzwerk (im Vergleich zum inländischen Netzwerk in China) verbunden sein muss, um die K-Linien zu durchsuchen.

Die Perioden, die Binance unterstützt: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M.

In [24]: Importanfragen #Netzwerkanfragen für die gemeinsame Bibliothek ab Datum/Zeit Datum der Einfuhr,Datum/Zeit Einfuhrzeit Import von Pandas als PD In [160]: def GetKlines ((Symbol=BTC,start=2020-8-10,end=2021-8-10,Periode=1h): Kline = [] Start_zeit = int(zeit.mktime(datetime.strptime(start, %Y-%m-%d).Mehrfachzeit))) *1000 end_time = int(time.mktime(datetime.strptime(end, %Y-%m-%d).Mehrfachzeit))) *1000 während Start_zeit < End_zeit: Res = Requests.get(https://fapi.binance.com/fapi/v1/klines?symbol=%sUSDT&interval=%s&startTime=%s&limit=1000%(symbol,period,start_time)) Res_list = res.json() Klines += res_list #print ((datetime.utcfromtimestamp ((Start_time/1000).strftime ((%Y-%m-%d %H:%M:%S),len ((res_list)) Start_zeit = res_list[-1][0] return pd.DataFrame ((Klines,columns=[time,open,high,low,close,amount,end_time,volume,count,buy_amount,buy_volume,null]).astype ((float) In [85]: df = GetKlines ((Symbol=BTC,start=2021-1-1,end=2021-8-10,Periode=1h)

Die Datenspeicherung und das Lesen können die Funktionen innerhalb der Panda-Bibliothek verwenden.

Neben dem höchsten Preis, dem niedrigsten Preis, dem offenen Preis, dem Schlusskurs und dem ausgeführten Volumen umfassen die von Binance zurückgegebenen K-Liniendaten auch den gesamten Handelsbetrag, den Kaufbetrag der Initiative, den Ausführungsbetrag usw. Dies sind wertvolle Informationen, die zur Konstruktion von Strategien verwendet werden können.

In [86]: Der Präsident. - Nach der Tagesordnung folgt die Aussprache über: df = pd.read_csv ((btc_klines.csv,index_col=0) In [87]: df Aus dem Spiel[87]: ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, Zeit der Eröffnung hoher niedrigerer Schließbetrag Ende_Zeit Volumenzählung kaufen_Betrag kaufen_Volumen null 0 1596988800000 11575.08 11642.00 11566.07 11591.37 6541.466 1596992399999 7.592336e+07 25724 3127.898 3.630633e+07 0 1 1596992400000 11591.39 11610.23 11526.90 11534.39 6969.252 1596995999999 8.057780e+07 27403 3390.424 3.920162e+07 0 2 1596996000000 11534.39 11656.69 11527.93 11641.07 6439.365 1596999599999 7.469135e+07 25403 3446.186 3.997906e+07 0 3 1596999600000 11641.06 11665.90 11624.20 11635.30 3911.582 1597003199999 4.555459e+07 17820 1842.413 2.145768e+07 0 4 1597003200000 11635.29 11684.00 11635.29 11673.81 3461.004 1597006799999 4.036804e+07 15513 1660.575 1.936981e+07 0 ............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................. 8805 1628658000000 45627.72 45894.53 45540.00 45801.45 10296.202 1628661599999 4.710187e+08 112187 4988.565 2.282399e+08 0 8806 1628661600000 45801.46 46270.00 45800.01 46087.86 26409.962 1628665199999 1.215164e+09 247170 13696.301 6.302708e+08 0 8807 1628665200000 46087.87 46450.00 46087.87 46367.38 23969.309 1628668799999 1.110210e+09 232348 11990.951 5.554267e+08 0 8808 1628668800000 46367.37 46643.13 46002.01 46217.01 23472.769 1628672399999 1.086549e+09 229533 12334.292 5.711837e+08 0 8809 1628672400000 46217.01 46329.69 46046.54 46297.16 6579.477 16286759999 3.039580e+08 78812 3313.055 1.530718e+08 0 - Ich weiß. 8810 Zeilen × 12 Spalten

- Ich weiß. In [88]: df.index = pd.to_datetime ((df.time,unit=ms) #konvertieren Sie den Index in ein Datum, das für das Ploten praktisch ist In [89]: df.close.plot ((figsize=(15,6),Gitter = True); #close Preis Außen[89]:imgIn [92]: (df.buy_amount.rolling(150).mean()/df.amount.rolling(150.mean()).plot ((figsize=(15,6),Gitter = True); #nach flach, der Anteil des Initiativkaufbetrags Die Situation, in der der Anteil der Initiativkäufe nach dem Tiefpunkt steigt, entspricht normalerweise der Situation des Preisanstiegs, aber der langfristige Durchschnitt des Anteils der Initiativkäufe beträgt 49%. Ausgeschaltet[92]:imgIn [93]: (df[count].rolling(100).mean (()).plot ((figsize=(15,6),grid = True); #der ausgeführte Betrag nach flach,und die Marktnotierungen können an einem niedrigen Ort vorbereitet werden Außen [1]:img

Rücktestmotor

Der vorherige Artikel gab auch die Python-Backtest-Engine, aber hier ist eine optimierte Version. USDT-margined (oder andere Quote-Währung-margined) Perpetual Contracts sind sehr ähnlich wie Spot-Kontrakte. Der Unterschied besteht darin, dass perpetual Contracts Hebelwirkung haben und einen negativen Betrag halten können (entsprechend dem Short machen) und eine Backtest-Engine teilen können. Krypto-margined Lieferverträge sind speziell, da sie in Währung abgewickelt werden und einen spezifischen Backtest erfordern.

Hier wird ein einfaches Beispiel gegeben, das Multi-Symbol Spot oder Multi-Symbol Perpetual Backtesting implementieren kann. Viele Details werden ignoriert: wie Hebelwirkung von Futures, Margin-Besetzung, Finanzierungsrate, Liquidationsmechanismus, Market Making und Order Taker-Transaktionen sowie Orderpflege, aber es beeinflusst normalerweise nicht die normalen Backtest-Ergebnisse. Und der Preis und die Menge des Matchings und die Kontoaktualisierung müssen alle extern importiert werden. Leser können es auf dieser Grundlage verbessern.

Einführung in die Austauschklasse:

  • Konto:USDT gibt die Basiswährung an, die nicht erforderlich ist; realisierter_Gewinn: bereits realisierter Gewinn und Verlust; nicht realisierter_Gewinn: noch nicht realisierter Gewinn und Verlust; Gesamtbetrag: Gesamtkapital; Gebühr: Handlinggebühr. Bei anderen Handelsparen Betrag (bei Shorting eine negative Zahl); Hold_price: Haltpreis; Wert: Haltwert; Preis: aktueller Preis.

  • trade_symbols: Array von Handelspaaren; Sie können auch in einem Handelspaar passieren; die Standardquote-Währung ist USDT, aber Sie können auch andere Quote-Währungssymbole zum Backtest verwenden.

  • Gebühr: die Gebühr für die Übergabe; um es einfach zu sagen, unterscheiden Sie nicht zwischen Hersteller und Empfänger.

  • initial_balance: die anfänglichen Vermögenswerte; der anfängliche Betrag der Standardhandelspaare beträgt 0.

  • Kauffunktion: Kaufen, was dem Long- und Short-Schließen von Dauerverträgen entspricht, ohne einen Matching-Mechanismus.

  • Verkaufsfunktion: zu verkaufen.

  • Aktualisierungsfunktion: Aktualisierung der Kontoinformationen, die in das Preiswörterbuch aller Handelspare eingegeben werden müssen. In [98]: Klasse Austausch:

    def Initialisierung(selbst, trade_symbols, Gebühr=0.0004, initial_balance=10000): Selbst.anfängliches_Guthaben = anfängliches_Guthaben #anfängliches Guthaben Selbstgebühr = Gebühr Selbst.trade_symbols = trade_symbols Selbstkonto = {USDT:{realisiertes_Gewinn:0, unrealisiertes_Gewinn:0, Gesamt:anfängliches_Guthaben, gebühr:0}} für Symbol in trade_symbols: Selbstkonto[Symbol] = {betrag:0, Haltpreis:0, Wert:0, Preis:0, erwirtschafteter_Gewinn:0,unerwirtschafteter_Gewinn:0,Gebühr:0}

    def Handel ((selbst, Symbol, Richtung, Preis, Betrag):

      cover_amount = 0 if direction*self.account[symbol]['amount'] >=0 else min(abs(self.account[symbol]['amount']), amount)
      open_amount = amount - cover_amount
      self.account['USDT']['realised_profit'] -= price*amount*self.fee #take out the fee 
      self.account['USDT']['fee'] += price*amount*self.fee
      self.account[symbol]['fee'] += price*amount*self.fee
    
      if cover_amount > 0: #close first 
          self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount  #profit 
          self.account[symbol]['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount
          
          self.account[symbol]['amount'] -= -direction*cover_amount
          self.account[symbol]['hold_price'] = 0 if self.account[symbol]['amount'] == 0 else self.account[symbol]['hold_price']
          
      if open_amount > 0:
          total_cost = self.account[symbol]['hold_price']*direction*self.account[symbol]['amount'] + price*open_amount
          total_amount = direction*self.account[symbol]['amount']+open_amount
          
          self.account[symbol]['hold_price'] = total_cost/total_amount
          self.account[symbol]['amount'] += direction*open_amount
    

    def Kaufen (selbst, Symbol, Preis, Betrag):self.Trade(Symbol 1, Preis, Betrag)

    def Verkaufen (selbst, Symbol, Preis, Betrag):self.Trade(Symbol -1, Preis, Betrag)

    def Update ((self, close_price): #Aktualisieren der Vermögenswerte Selbstkonto[USDT][nicht realisierter_Gewinn] = 0 für Symbol in self.trade_symbols: Selbstkonto[Symbol][unrealised_profit] = (Schließpreis[Symbol] - Selbstkonto[Symbol][Hold_price]) * Selbstkonto[Symbol][Betrag] Selbst.Account[Symbol][preis] = Schließen_Preis[Symbol] Selbstkonto[Symbol][wert] = abs(Selbstkonto[Symbol][Betrag]) *close_price[Symbol] Selbstkonto[USDT][unrealized_profit] += Selbstkonto[Symbol][unrealized_profit] Selbstkonto[USDT][total] = rund(Selbstkonto[USDT][realisierter_Gewinn] + Selbstkonto[USDT][unrealisierter_Gewinn],6) In [117]: #Im Test kann man sehen, dass es keinen Schwerpunkt darauf gibt, ob die Plattform USDT-margined oder spot ist. e = Exchange([BTC], Gebühr=0.0004, initial_balance=10000) #erstellen Sie ein Exchange-Objekt und nur ein Handelspaar von BTC e.Kaufen(BTC,40000, 0.1)#Kaufen von 0.1 BTC zum Preis von 40.000 e.Verkaufen ((BTC,41000, 0,1) #verkaufen 0,1 BTC zum Preis von 41.000 e.Aktualisieren (({BTC:41000}) #updtae die Kontoinformationen Print ((e.account) #die endgültigen Kontoinformationen print("Gewinn: ',rund(e.Konto[USDT][Gesamtbetrag]-e.anfängliches_Guthaben,2)) Aus[117]:{USDT: {realisiertes_Gewinn: 96.76, unrealisiertes_Gewinn: 0.0, Gesamt: 10096.76, Gebühr: 3.24}, BTC: {Betrag: 0.0, Haltpreis: 0, Wert: 0.0, Preis: 000, 41 realisiertes_Gewinn: 100.0, unrealisiertes_Gewinn: 0.0, Gebühr: 3.24}} Gewinn: 96,76

Grid-Strategie-Backtest

Erstens, lassen Sie uns eine klassische Perpetual Grid-Strategie backtest. Diese Strategie ist in letzter Zeit sehr beliebt auf unserer Plattform. Im Vergleich zum Spot-Grid muss sie keine Währung halten und kann Hebelwirkung hinzufügen, was viel bequemer ist als das Spot-Grid. Da sie jedoch nicht direkt backtested werden kann, ist es nicht förderlich, Währungssymbole auszuwählen. Hier verwenden wir die Backtest-Engine gerade jetzt, um sie zu testen.

An der Spitze von Live befindet sich ein offizieller Bot, der ab dem 4. April 2021 gestartet wurde; der Positionswert beträgt 150, der Rasterabstand beträgt 0,01, und der aktuelle Gewinn beträgt 3600USDT. Mit den gleichen Parametern und der 5min K-Linie zum Backtest beträgt der Gewinn 3937USDT. Da der Positionswert zu Beginn des Bots weniger als 150 USDT beträgt, ist das Ergebnis ziemlich genau. Wenn Sie den Rasterabstand auf 0,005 ändern, beträgt der Gewinn 5226U. Ein Rasterabstand von 0,005 ist offensichtlich ein besserer Parameter als 0,01, der zurück getestet werden muss, um es herauszufinden.

Je kürzer die K-Linie-Periode, desto genauer sind die entsprechenden Backtest-Ergebnisse und desto größer ist die erforderliche Datenmenge.

In [241]: Symbol = TRX df = GetKlines ((symbol=symbol,start=2021-4-4,end=2021-8-11,period=5m) In [286]: Wert = 150 pct = 0,01

e = Wechselkurs (([Symbol], Gebühr=0.0002, initial_balance=10000) Initial_price = df.loc[0,close] res_list = [] #verwendet, um das mittlere Ergebnis zu speichern für die Zeile in df.iterrows(): Kline = Reihe [1] #das nur eine K-Linie testen und nur einen Kauf- oder einen Verkaufsbefehl erhalten wird, was nicht sehr genau ist buy_price = (value / pct - value) / ((value / pct) / init_price + e.account[symbol][amount]) #sell order price, denn es ist eine Maker-Ausführung, ist auch der endgültige Matching-Preis Verkaufspreis = (Wert / pct + Wert) / ((Wert / pct) / init_preis + e.account[Symbol][betrag])

if kline.low < buy_price: #the lowest price of K-line is less than the current maker price; the buy order is executed 
    e.Buy(symbol,buy_price,value/buy_price)
if kline.high > sell_price:
    e.Sell(symbol,sell_price,value/sell_price)
e.Update({symbol:kline.close})
res_list.append([kline.time, kline.close, e.account[symbol]['amount'], e.account['USDT']['total']-e.initial_balance])

res = pd.DataFrame ((data=res_list, Spalten=[Zeit,Preis,Betrag,Gewinn]) Res.index = pd.to_datetime ((res.time,unit=ms) In [287]: e.Konto Aus[287]:{USDT: {realized_profit: 3866.633149565143, nicht realisierter Gewinn: 70.54622281993666, Gesamt: 13937.179372, Gebühr: 177,51000000000596}, TRX: {Betrag: 36497.43208747655, Hold_price: 0,08203709078461048, wert: 3064.689372385406, Preis: 0,08397, realisierter_Gewinn: 4044.143149565462, nicht realisierter Gewinn: 70.54622281993666, Gebühr: 177,51000000000596}} In [288]: Res.profit.plot ((figsize=(15,6),Gitter = Richtig); Außen[288]:imgIn [170]: Res.price.plot ((figsize=(15,6),Gitter = True); #Schließpreis Ausgeschaltet[170]:img

Spot-Gleichgewichtsstrategie Backtest

Diese Art von Strategie ist auch relativ beliebt, aber die FMZ-Plattform ist nicht sehr gut im Backtesting von Multi-Symbol-Strategien, verwenden Sie einfach diese Backtest-Engine, um es auszuprobieren.

Zuerst erhalten Sie die Schlusskosten der vier Symbole im vergangenen Jahr. Es kann gesehen werden, dass ETH den größten Anstieg hat, und die anderen drei ähnliche Anstiege haben. Wenn Sie diese vier Symbole im Durchschnitt halten, beträgt der endgültige Nettowert 4,5. Nach dem Backtest hat die Gleichgewichtsstrategie einen endgültigen Nettowert von 5,3, der leicht erhöht wird.

In [290]: Symbole = [BTC,ETH,LTC,XRP] Daten = für Symbole in Symbolen: df = GetKlines ((symbol=symbol,start=2020-8-11,end=2021-8-11,Periode=1h) Daten[Symbol] = df.close In [291]: df = pd.DataFrame (([Daten[Symbol].Werte für Symbole in Symbolen],index=Symbole).T In [302]: e = Tausch (Symbole, Gebühr = 0,0004, initial_balance = 10000) Res_list = [] für die Zeile in df.iterrows ((): Preise = Zeile [1] Gesamt = e.Konto[USDT][Gesamt] e.Aktualisierung der Preise für Symbole in Symbolen: pct = e.Konto[Symbol][Wert]/Gesamt wenn pct > 0,26 ist: e.Verkaufen (Symbol,Preise (Symbol), Punkt 0.25) *Gesamt/Preise (Symbol)) wenn pct < 0,24 ist: e.Kaufen (Symbol,Preise [Symbol],(0,25 Prozent) *Gesamt/Preise [Symbol]) Res_list.append (([e.account[symbol][value] für Symbol in Symbolen] + [e.account[USDT][total]]) Res = pd.DataFrame ((data=res_list, Spalten=Symbole+[total]) In [303]: (df/df.iloc[0,:]).plot(figsize=(15,6),grid = True); #plot der Trend durch Normalisierung Ausgeschaltet[1]:imgIn [304]: (res.total/10000-(df/df.iloc[0,:]).mean(axis=1)).plot(figsize=(15,6),grid = True); #enheance den Effekt Ausgeschaltet[1]:img

Schildkrötenstrategie

Die Schildkrötenstrategie ist eine klassische Trendstrategie, die eine vollständige Stop-Loss-Logik für das Hinzufügen von Positionen enthält.https://zhuanlan.zhihu.com/p/27987938Wir werden hier eine einfache Version für den Backtest implementieren.

Die Schildkrötenstrategieperiode hat einen großen Einfluss auf die Strategie, und es ist nicht ratsam, eine Periode zu kurz zu wählen. Hier wählen wir 6h. Die Donchian-Kanalperiode wird als 5 ausgewählt, und das Positionsverhältnis wird gemäß dem Backtest als 0.003 ausgewählt. Wenn der Preis durch das UpBand des Kanals bricht, um 1 Einheit einer Long-Position zu öffnen, und der Preis nach der Eröffnung der Positionen weiterhin um 0,3 Volatilität steigt, fügen Sie weiterhin 1 Einheit hinzu, und der Preis fällt unter 2,5 Volatilität des letzten offenen Preises, um den Verlust zu stoppen. Das Prinzip der Short-Order ist das gleiche. Aufgrund des großen Bullenmarktes von ETH hat die Schildkrötenstrategie den Haupttrend erfasst und schließlich 27 Mal Gewinne erzielt, mit einer maximalen Hebelwirkung von 4 Mal während des Zeitraums.

Die Parameter der Schildkrötenstrategie hängen eng mit der Periode zusammen und müssen durch Backtest ausgewählt werden.

Aus dem endgültigen Nettowertdiagramm lässt sich erkennen, dass die Schildkrötenstrategie eine langfristige Strategie ist, bei der es für 3 bis 4 Monate keinen Gewinn geben kann und wiederholte Stop-Losses, aber sobald es eine große Marktquote auf der einen Seite gibt, kann die Schildkrötenstrategie den Trend nutzen, um eine große Position zu akkumulieren, bis zum Ende des Trends zu halten, viel Gewinn zu erzielen. Am Ende des Anstiegs wird die Strategie viele Positionen akkumulieren. Zu diesem Zeitpunkt wird die Volatilität relativ groß sein, und oft werden große Gewinne zurückgezogen. Die Verwendung der Schildkrötenstrategie erfordert, dass Sie ihre Mängel und Ihre Geduld akzeptieren.

In [424]: Symbol = ETH df = GetKlines ((symbol=symbol,start=2019-8-11,end=2021-8-11,period=6h) In [425]: df.index = pd.to_datetime ((df.time,unit=ms) In [568]: M = 5 # Periodenvolumen des Donchian-Kanals pct = 0,003 #der Anteil der hinzugefügten Positionen an den Gesamtpositionen df[up] = df[high].rolling ((M).max().shift(1) #upBand des Donchian-Kanals, verwendet, um lang zu machen und zu beurteilen, um durch t zu brechen df[down] = df[low].Rollung ((M).max ((().Verlagerung ((1) Df[mittler] = (df[up]+df[down])/2 df[true_range] = pd.concat([df[high]-df[low],df[high]-df[close].shift(1),df[close].shift(1)-df[low],Achse=1).max.Achse=1) df[N] = df[true_range].rolling(50).mean() #N entspricht der jüngsten Volatilität, die zur Beurteilung von Buy-in und Stop-Loss verwendet wird In [572]: Open_times = 0,3 #Bewertung der Eröffnung einer Position Stop_times = 2,5 #Stop Verlust e = Exchange (([Symbol], Gebühr=0.0004, initial_balance=10000) #set der Abnehmer auf 0.0004 Res_list = [] Last_price = 0 #letzter offener Positionspreis für die Zeile in df.iterrows ((): Kline = Reihe [1] wenn kline.isnull (().sum() > 0: #überspringen Sie den Abschnitt ohne Daten Weiter Einheit = e.Account[USDT][total]*pct/kline.N #offene Positionen Einheitsbetrag

if kline.high >  kline.up and e.account[symbol]['amount'] == 0: #first time to open long position 
    e.Buy(symbol,kline.up,unit) #notice the trading price here
    last_price = kline.up
if e.account[symbol]['amount'] > 0 and kline.high > last_price + open_times*kline.N: #long position, buy in 
    e.Buy(symbol,last_price + open_times*kline.N,unit)
    last_price = last_price + open_times*kline.N
if e.account[symbol]['amount'] > 0 and kline.low < last_price - stop_times*kline.N: #long position, stop loss
    e.Sell(symbol,last_price - stop_times*kline.N,e.account[symbol]['amount'])
    
if kline.low <  kline.down and e.account[symbol]['amount'] == 0: #open short
    e.Sell(symbol,kline.down,unit)
    last_price = kline.down
if e.account[symbol]['amount'] < 0 and kline.low < last_price - open_times*kline.N: #short position, buy in 
    e.Sell(symbol,last_price - open_times*kline.N,unit)
    last_price = last_price - open_times*kline.N
if e.account[symbol]['amount'] < 0 and kline.high > last_price + stop_times*kline.N: #short position, stop loss
    e.Buy(symbol,last_price + stop_times*kline.N,-e.account[symbol]['amount'])
    
e.Update({symbol:kline.close})
res_list.append([kline.time, kline.close, e.account[symbol]['amount']*kline.close, e.account['USDT']['total']])

res = pd.DataFrame ((data=res_list, Spalten=[zeit,preis,wert,Gesamt]) Res.index = pd.to_datetime ((res.time,unit=ms) print(Endmarktwert:,res[Gesamtwert][-1]) Aus[572]:Endmarktwert: 280760.566996 In [573]: Res.total.plot ((figsize=(15,6), Raster = Richtig); Außen[573]:imgIn [571]: (res.value/res.total).plot(figsize=(15,6),Gitter = Richtig); Außen[571]:img

Schlussfolgerung

Wenn Sie in der Verwendung der jupyter Notebook Research Plattform versiert sind, können Sie leicht Operationen wie Datenerfassung, Datenanalyse, Strategie-Backtest, Chart-Anzeige usw. ausführen, was der unvermeidliche Weg zum quantitativen Handel ist. Wenn Sie im Moment keine Ahnung über das Schreiben von Strategien haben, können Sie die Daten auch zuerst analysieren. Für Anfänger empfehlen wir Ressourcen:

Verwenden Sie Python, um Daten zu analysieren:https://wizardforcel.gitbooks.io/pyda-2e/content/

Quantitativer Python-Tutorial:https://wizardforcel.gitbooks.io/python-quant-uqer/content/

In [ ]:


Mehr