avatar of 发明者量化-小小梦 发明者量化-小小梦
konzentrieren Sie sich auf Private Nachricht
4
konzentrieren Sie sich auf
1271
Anhänger

Über die Erfahrung bei der Entwicklung von Handelsstrategien sprechen

Erstellt in: 2019-08-06 17:15:13, aktualisiert am: 2023-10-20 20:06:49
comments   4
hits   3416

Über die Erfahrung bei der Entwicklung von Handelsstrategien sprechen

Über die Erfahrung bei der Entwicklung von Handelsstrategien sprechen

Der Zweck dieses Artikels besteht darin, einige Erfahrungen und Tipps zur Strategieentwicklung weiterzugeben, die es den Lesern ermöglichen, schnell einen Eindruck von den Erfahrungen bei der Entwicklung von Handelsstrategien zu gewinnen. Beim Auftreffen auf ähnliche Detailprobleme bei der Strategieentwicklung können sofort sinnvolle Lösungsansätze konzipiert werden. Die Inventor Quantitative Trading Platform dient als Plattform zum Erklären, Testen und Üben. Programmiersprache für Richtlinien: JavaScript Handelsmarkt: Blockchain-Asset-Markt (BTC, ETH usw.)

  • ## Datenerfassung und -verarbeitung

Normalerweise ist es je nach Strategielogik möglich, die folgenden verschiedenen Schnittstellen zu verwenden, um Marktdaten zu erhalten, da die Handelslogik der Strategie normalerweise von Marktdaten gesteuert wird (natürlich gibt es einige Strategien, die den Markt nicht berücksichtigen , wie etwa Strategien für feste Investitionen).

  • GetTicker: Erhalten Sie Tick-Informationen in Echtzeit. Es wird im Allgemeinen verwendet, um schnell den aktuellen Preis, Kaufpreis und Verkaufspreis zu ermitteln.

  • GetDepth: Erhalten Sie Kurse zur Auftragsbuchtiefe. Es wird im Allgemeinen verwendet, um den Preis jeder Ebene und die Größe der Bestellung zu ermitteln. Wird für Absicherungsstrategien, Market-Making-Strategien usw. verwendet.

  • GetTrade: Holen Sie sich die neuesten Transaktionsaufzeichnungen auf dem Markt. Es wird im Allgemeinen verwendet, um das Marktverhalten in einem kurzen Zeitraum zu analysieren und Mikroveränderungen am Markt zu analysieren. Wird normalerweise in Hochfrequenzstrategien und algorithmischen Strategien verwendet.

  • GetRecords: Holen Sie sich Markt-K-Line-Daten. Wird häufig in Trendfolgestrategien verwendet. Wird zur Berechnung von Indikatoren verwendet.

  • Fehlertoleranz

    Beim Entwerfen von Strategien ignorieren Anfänger normalerweise verschiedene Fehlersituationen und glauben intuitiv, dass die Ergebnisse jeder Verknüpfung in der Strategie vorbestimmt sind. Tatsächlich ist dies jedoch nicht der Fall. Bei der Abfrage von Marktdaten während der Ausführung des Strategieprogramms treten verschiedene unerwartete Situationen auf. Beispielsweise geben einige Marktschnittstellen abnormale Daten zurück:

    var depth = exchange.GetDepth()
    
    
    // depth.Asks[0].Price < depth.Bids[0].Price      卖一价格低于了买一价格,这种情况不可能存在于盘面上,
    //                                                因为卖出的价格低于买入的价格,必定已经成交了。
    // depth.Bids[n].Amount = 0                       订单薄买入列表第n档,订单量为0
    // depth.Asks[m].Price = 0                        订单薄卖出列表第m档,订单价格为0
    

    Oder exchange.GetDepth() gibt direkt einen Nullwert zurück.

    Es gibt viele solcher seltsamen Situationen. Daher muss für diese vorhersehbaren Probleme eine entsprechende Verarbeitung durchgeführt werden, und diese Art der Verarbeitungslösung wird als fehlertolerante Verarbeitung bezeichnet.

    Der übliche Ansatz zur Fehlertoleranz besteht darin, Daten zu verwerfen und erneut abzurufen.

    Zum Beispiel:

    function main () {
        while (true) {
            onTick()
            Sleep(500)
        }
    }
    
    
    function GetTicker () {
        while (true) {
            var ticker = exchange.GetTicker()
            if (ticker.Sell > ticker.Buy) {       // 以 检测卖一价格是不是小于买一价这个错误的容错处理为例,
                                                  // 排除这个错误,当前函数返回 ticker 。
                return ticker
            }
            Sleep(500)
        }
    }
    
    
    function onTick () {
        var ticker = GetTicker()                  // 确保获取到的 ticker 不会存在 卖一价格小于买一价格这种数据错误的情况。
        // ...  具体的策略逻辑
    }
    

    Andere vorhersehbare fehlertolerante Prozesse können auf ähnliche Weise gehandhabt werden. Das Designprinzip besteht darin, dass niemals falsche Daten zur Entwicklung einer Strategielogik verwendet werden dürfen.

  • Verwendung von K-Line-Daten

    K-Line Datenerfassung, Aufruf:

    var r = exchange.GetRecords()
    

    Die erhaltenen K-Line-Daten sind ein Array wie dieses:

    [
        {"Time":1562068800000,"Open":10000.7,"High":10208.9,"Low":9942.4,"Close":10058.8,"Volume":6281.887000000001},
        {"Time":1562072400000,"Open":10058.6,"High":10154.4,"Low":9914.5,"Close":9990.7,"Volume":4322.099},
        ...
        {"Time":1562079600000,"Open":10535.1,"High":10654.6,"Low":10383.6,"Close":10630.7,"Volume":5163.484000000004}
    ]
    

    Sie können sehen, dass jede geschweifte Klammer{}Dazu zählen Zeit, Eröffnungskurs (Open), Höchstkurs (High), Tiefstkurs (Low), Schlusskurs (Close) und Handelsvolumen (Volumen). Dies ist ein Kerzenständer. Im Allgemeinen werden K-Line-Daten zur Berechnung von Indikatoren wie MA-gleitender Durchschnitt, MACD usw. verwendet. Geben Sie die K-Line-Daten als Parameter ein (Rohmaterialdaten), legen Sie dann die Indikatorparameter fest und berechnen Sie die Funktion der Indikatordaten, die wir als Indikatorfunktion bezeichnen. Auf der Inventor Quantitative Trading Platform gibt es viele Indikatorfunktionen.

    Wenn wir beispielsweise den gleitenden Durchschnittsindikator berechnen, berechnen wir auf der Grundlage der unterschiedlichen Zeiträume der von uns übergebenen K-Line-Daten den gleitenden Durchschnitt des entsprechenden Zeitraums. Wenn beispielsweise die täglichen K-Linien-Daten übergeben werden (ein K-Linien-Balken repräsentiert einen Tag), ist der berechnete Indikator der tägliche gleitende Durchschnitt. Ähnlich verhält es sich, wenn die an die gleitende Durchschnittsindikatorfunktion übergebenen K-Linien-Daten ein 1-Stunden-Zeitraum, dann ist der berechnete Indikator der gleitende 1-Stunden-Durchschnitt. .

    Normalerweise übersehen wir bei der Berechnung von Indikatoren oft ein Problem.Wenn ich den 5-Tage-Durchschnittsindikator berechnen möchte, bereiten wir zunächst die täglichen K-Line-Daten vor:

    var r = exchange.GetRecords(PERIOD_D1)  // 给GetRecords 函数传入参数 PERIOD_D1就是指定获取日K线,
                                            // 具体函数使用可以参看:https://www.fmz.com/api#GetRecords
    

    Mit den täglichen K-Liniendaten können wir den gleitenden Durchschnittsindikator berechnen. Wenn wir den 5-Tage-Durchschnitt berechnen möchten, müssen wir den Indikatorparameter der Indikatorfunktion auf 5 setzen.

    var ma = TA.MA(r, 5)        // TA.MA() 就是指标函数,用来计算均线指标,第一个参数设置刚才获取的日K线数据r,
                                // 第二个参数设置5,计算出来的就是5日均线,其它指标函数同理。
    

    Wir haben ein potenzielles Problem übersehen. Was passiert, wenn die Anzahl der K-Linien-Balken in den r-Tage-K-Linien-Daten weniger als 5 beträgt? Können wir dann einen gültigen 5-Tage-Durchschnittsindikator berechnen? Die Antwort ist definitiv nein. Denn der gleitende Durchschnittsindikator dient dazu, den Durchschnitt der Schlusskurse einer bestimmten Anzahl von K-Linien-Balken zu ermitteln.

    Über die Erfahrung bei der Entwicklung von Handelsstrategien sprechen

    Daher muss vor der Verwendung von K-Liniendaten und Indikatorfunktionen zur Berechnung von Indikatordaten festgestellt werden, ob die Anzahl der K-Linienspalten in den K-Liniendaten die Bedingungen für die Indikatorberechnung (Indikatorparameter) erfüllt.

    Daher ist vor der Berechnung des 5-Tage-Durchschnitts eine Beurteilung erforderlich. Der vollständige Code lautet wie folgt:

    function CalcMA () {
        var r = _C(exchange.GetRecords, PERIOD_D1)     // _C() 是容错函数,目的就是避免 r 为 null , 具体可以查询文档:https://www.fmz.com/api#_C
        if (r.length > 5) {
            return TA.MA(r, 5)                         // 用均线指标函数 TA.MA 计算出均线数据,做为函数返回值,返回。
        }
    
    
        return false 
    }
    
    
    function main () {
        var ma = CalcMA()
        Log(ma)
    }
    

    Über die Erfahrung bei der Entwicklung von Handelsstrategien sprechen

    Backtesting zeigt: [null,null,null,null,4228.7,4402.9400000000005, … ]

    Es ist ersichtlich, dass die ersten vier der berechneten 5-Tage-Durchschnittsindikatoren null sind, da die Anzahl der K-Linienspalten kleiner als 5 ist und der Durchschnitt nicht berechnet werden kann. Es kann ab der 5. Kerze berechnet werden.

  • Tipps zur Beurteilung von K-Line-Updates

    Wenn wir einige Strategien schreiben, gibt es oft ein Szenario, in dem wir einige Vorgänge verarbeiten oder einige Protokolle drucken müssen, wenn jeder K-Line-Zyklus abgeschlossen ist. Wie erreichen wir diese Funktionalität? Anfänger ohne Programmiererfahrung können sich möglicherweise nicht vorstellen, welchen Mechanismus sie verwenden sollen, um damit umzugehen. Hier geben wir Ihnen direkt einige Tipps.

    Wir können beurteilen, dass ein K-Linien-Spaltenzyklus abgeschlossen ist, indem wir mit dem Zeitattribut in den K-Linien-Daten beginnen. Jedes Mal, wenn wir K-Linien-Daten erhalten, beurteilen wir das Zeitattribut in den Daten der letzten K-Linien-Spalte dieser K-Liniendaten. Ob sich dieser Attributwert geändert hat. Wenn er sich geändert hat, bedeutet dies, dass eine neue K-Linienspalte generiert wurde (was beweist, dass der vorherige K-Linienspaltenzyklus der neu generierten K-Linienspalte abgeschlossen). Wenn es sich nicht geändert hat, bedeutet dies, dass kein neuer Candlestick generiert wird (der aktuelle letzte Candlestick-Zyklus ist noch nicht abgeschlossen).

    Wir benötigen also eine Variable, um die Zeit der letzten Candlestick-Spalte der Candlestick-Daten aufzuzeichnen.

    var r = exchange.GetRecords()
    var lastTime = r[r.length - 1].Time       // lastTime 用来记录最后一根K线柱的时间。
    

    In der Praxis sieht der Aufbau meist so aus:

    function main () {
        var lastTime = 0
        while (true) {
            var r = _C(exchange.GetRecords)
            if (r[r.length - 1].Time != lastTime) {
                Log("新K线柱产生")
                lastTime = r[r.length - 1].Time      // 一定要更新 lastTime ,这个至关重要。
    
    
                // ... 其它处理逻辑
                // ...
            }
    
    
            Sleep(500)
        }
    }
    

    Über die Erfahrung bei der Entwicklung von Handelsstrategien sprechen

    Es ist ersichtlich, dass im Backtest die K-Line-Periode auf den Tag eingestellt ist (die Funktion exchange.GetRecords wird ohne Angabe von Parametern aufgerufen, und die gemäß dem Backtest eingestellte K-Line-Periode ist der Standardparameter). Immer wenn ein Es erscheint eine neue K-Line-Spalte und es wird ein A-Protokoll gedruckt.

  • Numerische Berechnungen

    • ### Berechnen Sie die Zeit, die für den Zugriff auf die Austauschschnittstelle benötigt wird

    Wenn Sie die Zeit anzeigen oder steuern möchten, die eine Strategie benötigt, um auf die Schnittstelle der Börse zuzugreifen, können Sie den folgenden Code verwenden:

    function main () {
        while (true) {
            var beginTime = new Date().getTime()
            var ticker = exchange.GetTicker()
            var endTime = new Date().getTime()
    
    
            LogStatus(_D(), "GetTicker() 函数耗时:", endTime - beginTime, "毫秒")
            Sleep(1000)
        } 
    }
    

    Einfach ausgedrückt wird der nach dem Aufruf der GetTicker-Funktion aufgezeichnete Zeitstempel vom Zeitstempel vor dem Aufruf abgezogen, um die Anzahl der vergangenen Millisekunden zu berechnen, d. h. die Zeit, die die GetTicker-Funktion benötigt, um ausgeführt zu werden und das Ergebnis zurückzugeben.

    • ### Verwenden Sie Math.min / Math.max, um Ober- und Untergrenzen für Werte festzulegen

    Wenn Sie eine numerische Obergrenze wünschen, verwenden Sie normalerweise Math.min, um

    Wenn Sie beispielsweise einen Verkaufsauftrag erteilen, darf der Auftragsbetrag nicht größer sein als die Anzahl der Münzen auf dem Konto. Denn ist diese größer als die Anzahl der verfügbaren Coins auf dem Konto, wird bei einer Bestellung ein Fehler gemeldet.

    Normalerweise wird es so gesteuert: Sie planen beispielsweise, einen Verkaufsauftrag für 0,2 Münzen zu erteilen.

    var planAmount = 0.2
    var account = _C(exchange.GetAccount)
    var amount = Math.min(account.Stocks, planAmount)
    

    Dadurch wird sichergestellt, dass der Betrag, also der Betrag der aufzugebenden Bestellung, die Anzahl der auf dem Konto verfügbaren Münzen nicht übersteigt.

    In ähnlicher Weise wird Math.max verwendet, um eine Untergrenze für einen Wert sicherzustellen. Auf welche Szenarien trifft dies normalerweise zu? Im Allgemeinen haben Börsen für bestimmte Handelspaare eine Mindestbestellmenge. Wenn die Bestellmenge unter dieser Mindestbestellmenge liegt, wird die Bestellung abgelehnt. In diesem Fall schlägt die Bestellung fehl. Gehen Sie davon aus, dass die Mindestbestellmenge für BTC normalerweise 0,01 beträgt. Manchmal berechnet die Handelsstrategie, dass die Bestellmenge weniger als 0,01 beträgt. In diesem Fall können wir Math.max verwenden, um die Mindestbestellmenge sicherzustellen.

    • ### Bestellmengen- und Preispräzisionskontrolle

    Kann verwendet werden_N()-Funktion oder SetPrecision-Funktion zur Steuerung der Genauigkeit.

    Die Funktion SetPrecision() muss nur einmal festgelegt werden und das System schneidet überzählige Dezimalstellen in den Werten für Bestellmenge und Preis automatisch ab.

    _Die Funktion N() wird verwendet, um einen Wert auf eine bestimmte Anzahl von Dezimalstellen zu kürzen (Präzisionskontrolle).

    Zum Beispiel:

    var pi = _N(3.141592653, 2)
    Log(pi)
    

    Der Wert von Pi wird auf 2 Dezimalstellen gekürzt und ergibt: 3,14

    Weitere Einzelheiten finden Sie in der API-Dokumentation.

  • Einige Logikeinstellungen

    • ### Timing: Führen Sie einige Vorgänge in einem bestimmten Zeitraum aus

    Mit diesem Mechanismus können Sie die Zeitstempelerkennungsmethode verwenden, um den aktuellen Zeitstempel abzüglich des Zeitstempels des letzten Abschlusses der geplanten Aufgabe zu ermitteln und die verstrichene Zeit in Echtzeit zu berechnen. Wenn die verstrichene Zeit eine bestimmte festgelegte Zeitdauer überschreitet Danach , wird die neue Operation ausgeführt.

    Es kann beispielsweise in festen Anlagestrategien verwendet werden.

    var lastActTime = 0
    var waitTime = 1000 * 60 * 60 * 12   // 一天的毫秒数
    function main () {
        while (true) {
            var nowTime = new Date().getTime()
            if (nowTime - lastActTime > waitTime) {
                Log("执行定投")
                // ... 具体的定投操作,买入操作。
    
    
                lastActTime = nowTime
            }
    
    
            Sleep(500)
        }
    }
    

    Dies ist ein einfaches Beispiel.

    • ### Entwerfen automatischer Wiederherstellungsmechanismen für Strategien

    Durch die Verwendung der quantisierten _G()-Funktion des Erfinders und der Exit-Save-Funktion lässt sich sehr bequem eine Strategie zum Beenden und Speichern des Fortschritts sowie zum Neustarten zum automatischen Wiederherstellen des Status entwerfen.

    var hold = {
        price : 0, 
        amount : 0,
    }
    
    
    function main () {
        if (_G("hold")) {
            var ret = _G("hold")
            hold.price = ret.price
            hold.amount = ret.amount
            Log("恢复 hold:", hold)
        }
    
    
        var count = 1
        while (true) {
            // ... 策略逻辑
            // ... 策略运行中,可能开仓,交易,把开仓的持仓价格赋值给 hold.price ,开仓的数量赋值给 hold.amount,用以记录持仓信息。
    
    
            hold.price = count++     // 模拟一些数值
            hold.amount = count/10   // 模拟一些数值
    
    
            Sleep(500)
        }
    }
    
    
    function onexit () {    // 点击机器人上的停止按钮,会触发执行这个函数,执行完毕机器人停止。
        _G("hold", hold)
        Log("保存 hold:", JSON.stringify(hold))
    }
    

    Über die Erfahrung bei der Entwicklung von Handelsstrategien sprechen

    Es ist ersichtlich, dass bei jedem Stoppen des Roboters die Daten im Halteobjekt gespeichert werden. Bei jedem Neustart werden die Daten gelesen und der Haltewert auf den Zustand beim vorherigen Stopp zurückgesetzt. Natürlich ist das oben genannte ein einfaches Beispiel. Wenn es in einer tatsächlichen Strategie verwendet wird, sollte es entsprechend den Schlüsseldaten entworfen werden, die in der Strategie wiederhergestellt werden müssen (im Allgemeinen Kontoinformationen, Positionen, Gewinnwerte, Handelsrichtungen usw.). .). Natürlich können Sie auch einige Bedingungen festlegen, um zu bestimmen, ob eine Wiederherstellung durchgeführt werden soll.

Oben finden Sie einige Tipps zur Entwicklung von Strategien. Ich hoffe, sie sind sowohl für Anfänger als auch für Strategieentwickler hilfreich! Der schnellste Weg, sich zu verbessern, ist Übung! Ich wünsche Ihnen allen weiterhin viel Erfolg.