Die Ressourcen sind geladen. Beförderung...

Die Stromnetzhandelsstrategie

Schriftsteller:Gutes, Erstellt: 2018-08-23 13:45:27, aktualisiert:

Die Stromnetzhandelsstrategie (www.fmz.com) Die Grundidee des Grid-Tradings ist sehr einfach. Statt einen Handel zu platzieren, platzieren wir mehrere Trades, die ein Rastermuster bilden. Normalerweise werden diese als stop oder limit-Orders um das aktuelle Preisniveau eingegeben, aber nicht immer. Ich werde dies im Detail unten erklären, aber das ist die grundlegende Idee.

Was ist Netzhandel und wie funktioniert er? Grid-Trading ist ein Spiel mit der Marktvolatilität. Es gibt zwei Gründe, warum es von den Händlern bevorzugt wird.

Zweitens funktioniert es gut auf volatilen Märkten, wo es keinen klaren Trend gibt.

Grid-Trading ist eine Art von technischer Analyse, die auf Bewegung innerhalb bestimmter Grid-Muster basiert. Grid-Trading ist im Devisenhandel beliebt. Insgesamt versucht die Technik, die normale Preisvolatilität in den Märkten zu nutzen, indem Kauf- und Verkaufsaufträge in bestimmten regelmäßigen Abständen über und unter einem vordefinierten Basispreis platziert werden. Solche Kauf- und Verkaufsaufträge, die im Allgemeinen in 10 oder 15 Einheiten von Intervallen verteilt sind, schaffen ein Handelsgrid.

Gitter kann die Richtung anpassen

Grundlegender Handel: zuerst kaufen und dann verkaufen.

Das Raster beginnt, Kaufbestellungen zu einem Preis zu senden, der unter dem ersten Preis liegt, dem Preis, der vom ersten Preis gefolgt ist (zweiter letzter Kaufpreis, dritter letzter Kaufpreis... usw.). Jeder Kaufbefehl wird durch den Preisintervall-Parameter getrennt. Die Anzahl der ausstehenden Aufträge beträgt Einzelmenge und sendet die Gesamtbestellung, bis die Gesamtmenge ausgefüllt ist.

Nach Abschluss einer Kaufbestellung wird das Programm auf der Grundlage des Kaufpreises sein, fügen Sie den Preis des Preisdifferenz Parameter zum Verkaufspreis, nachdem die Bestellung verkauft wurde, und dann starten Sie erneut den Fortschritt dieser Rasterstrategie (Checking, platzieren Order, warten, bis es ausgeführt, verkaufen)

Erst kurz verkaufen und dann kaufen, um sich zu decken: das Gegenteil der Situation

Das größte Risiko dieser Strategie besteht darin, wenn sich der Markttrend einseitig bewegt und die Preisschwankungen das Netz überschreiten.

Der folgende Code hat das Raster mit automatischem Stoppverlust und Bewegungsfunktion erstellt.

Anmerkungen:

Die Strategie verwendet ein virtuelles Ausstehendes Auftragsdesign, das eine große Menge Verarbeitung für die Börse zur Verfügung stellt, um die Anzahl der ausstehenden Aufträge zu begrenzen, und löst das Problem flexibel.

Die Rasterlogik ist flexibel gestaltet und intelligent aufgebaut.

Profit-und-Loss-Berechnung, jeder numerische statistische Algorithmus kann als Referenz verwendet werden, und jeder Zustand Detektion Design ist streng. (für die Möglichkeit von BUG zu minimieren)

Der Quellcode ist es wert, gelernt zu werden.

Weitere Informationen finden Sie unter:

https://www.fmz.com/strategy/112633

Quelle:

` // Gitter kann Richtung anpassen // Grundlegende Handelsoperation: zuerst kaufen und dann verkaufen. // Das Raster wird anfangen, Kaufbestellungen zu einem Preis zu senden, der unter dem ersten Preis liegt, der der Preis folgt // nach dem ersten Preis (zweiter letzter Kaufpreis, dritter letzter Kaufpreis... usw.). // der Preisintervall Parameter. Die Anzahl der ausstehenden Aufträge beträgt eine einzelne Menge, und wird die Gesamtbestellung bis // die Gesamtmenge ist ausgefüllt. // Nachdem jede Kauf-Bestellung abgeschlossen ist, wird das Programm auf der Grundlage des Kaufpreises, fügen Sie den Preis des preis // Differenz Parameter zum Verkaufspreis, nachdem die Bestellung verkauft wurde, und dann den Fortschritt dieser neu starten // Gitter-Strategie (Checking, Platz-Order, warten, bis es ausgeführt, verkaufen) // zuerst kurz verkaufen und dann kaufen, um zu decken: die Operation ist genau das Gegenteil // Das größte Risiko dieser Strategie besteht darin, wenn sich der Markttrend einseitig bewegt und die Preisschwankungen das Raster übersteigen. // Der folgende Code hat das Gitter mit automatischem Stop-Verlust und Bewegung Funktion gemacht. // Kommentare: // Die Strategie verwendet ein virtuelles ausstehendes Auftragsdesign, das eine große Menge an Verarbeitung für die Börse bietet, um die Anzahl der // von ausstehenden Aufträgen, und löst das Problem flexibel. // Die Gitterlogik ist flexibel gestaltet und intelligent aufgebaut. // Gewinn- und Verlustberechnung, jeder numerische statistische Algorithmus kann als Referenz verwendet werden, und jeder Zustand Erkennung Design // ist streng. (um die Möglichkeit von BUG zu minimieren) // Der Quellcode ist sehr lernenswert.

// Quelle: /* Schnittstellenparameter (im Code als globale Variablen angezeigt) OpType Gitterrichtung Dropdown-Box (gewählt) Kaufen zuerst und dann verkaufen. FirstPriceAuto Anfangspreis automatisch Boolean (wahr/falsch) wahr Erster Preis@!Erster PreisAuto Anfangspreis numerisch (Nummer) 100 AllNummer Gesamtzahl numerische (Nummer) 10 Preissystem Preisintervall numerisch (Nummer) 1 Preisdifferenz numerische Differenz (Nummer) 2 BetragTyp Bestellgröße Dropdown-Box (gewählt) Kaufen und verkaufen Sie die gleiche Menge SummeOnce@AmountType==0 Einmalige Transaktionsmenge numerisch (Nummer) 0,1 BAmountOnce@AmountType==1 Bestellgröße numerische (Nummer) 0.1 SAmountOnce@AmountType==1 Verkaufsbestellungsgröße (Nummer) 0,1 QuantityCoefficient@AmountType==0 Mengenunterschied Zeichenfolge (Zeilenfolge) *1 QuantityDot Die Zahl mit dem Dezimalpunkt (Nummer) 3 AktivierenProtectDiff Aktivieren des Spread-Schutzes Boolean (true/false) falsch ProtectDiff@EnableProtectDiff Einstiegsspread Preisschutz numerisch (Nummer) 20 CancelAllWS stop annulliert alle ausstehenden Aufträge Boolean (true/false) true CheckInterval Zahl des Wahlintervalls (Nummer) 2000 Intervallfehler Wiederversuchsintervall (Nummer) 1300 RestoreProfit stellt den letzten Gewinn wieder her Boolean (true/false) false LastProfit@RestoreProfit Letzter Gewinn (Nummer) 0 ProfitAsOrg@RestoreProfit Letzter Gewinn, der als Durchschnittspreis gezählt wird Boolean (true/false) false AktivierenAccountCheck Aktivieren Sie die Bilanzüberprüfung Boolean (true/false) true AktivierenStopLoss@AktivierenAccountCheck öffnen Stop Loss Boolean (true/false) falsch StopLoss@EnableStopLoss maximaler schwebender Verlust (Nummer) 100 StopLossMode@EnableStopLoss Post-Stop-Loss-Operation Dropdown-Box (gewählt) Recycling und Ausgang EnableStopWin@EnableAccountCheck Aktivieren von Take Profit Boolean (wahr/falsch) falsch StopWin@EnableStopWin Maximaler variabler Gewinn Nummer (Nummer) 120 StopWinMode@EnableStopWin nach Gewinngewinn-Operation Dropdown-Box (gewählt) Recycling und Ausgang AutoMove@EnableAccountCheck AutoMove Boolean (wahr/falsch) falsch MaxDistance@AutoMove Höchstdistanz (Nummer) 20 MaxIdle@AutoMove maximale Leerlaufzeit (Sekunden) numerische (Nummer) 7200 EnableDynamic Dreht an dynamischen ausstehenden Aufträgen an Boolean (true/false) false DynamicMax@EnableDynamic Order Ablaufdistanz Nummer (Nummer) 30 ResetData löscht alle Daten beim Starten Boolean (true/false) true Präzisionspreis (Nummer) 5 */

Funktion hasOrder ((Orders, orderId) { // Überprüfen Sie, ob in Parameterordnungen eine Bestellung mit Order-ID vorhanden ist für (var i = 0; i < orders.length; i++) { // Überqueren Sie Befehle, um zu überprüfen, ob es gleiche IDs gibt, wenn es gibt, dann geben Sie true zurück wenn (Orders[i].Id == orderId) { zurückkehren true; - Ich weiß. - Ich weiß. return false; // Alle durchlaufen, kein Auslöser, wenn bedeutet, die Reihenfolge mit der ID-OrderId nicht gefunden haben, return false - Ich weiß.

Funktion annulPending() { // Alle ausstehenden Auftragsfunktionen stornieren VAR RET = FALSE; // Variablen für die Erfolgsmarkierung zurücksetzen while (true) { // während der Schleife wenn (ret) { // Wenn ret wahr ist dann Schlaf für eine bestimmte Zeit Schlaf ((Intervall); - Ich weiß. Var orders = _C(exchange.GetOrders); // Ruf die API an, um die Auftragsinformationen zu erhalten, die der Austausch nicht ausgeführt hat. wenn (orders.length == 0) { // Wenn ein leeres Array zurückgegeben wird, hat der Austausch keine nicht ausgeführten Aufträge. Break; // Aus der While-Schleife springen - Ich weiß.

    for (var j = 0; j < orders.length; j++) {              // Traverse the unfinished order array and use orders[j].Id one by one to cancel the order based on the index j.
        exchange.CancelOrder(orders[j].Id, orders[j]);
        ret = true;                                        // Once there is a cancel operation, ret is assigned a value of true. Used to trigger above Sleep, wait for re-exchange.GetOrders detection 
    }
}
return ret;                                                // return ret

}

FunktionswerteToString(Werte, pos) { // Wert in eine Zeichenfolge umgewandelt Var-Ergebnis = ; // Deklarieren eines leeren Zeichenfolgeergebnisses für die Rückgabe wenn (typeof(pos) === undefined) { // Wenn der Pos-Parameter nicht übergeben wird, wird dem Pos ein Wert von 0 zugewiesen. Pos = 0; - Ich weiß. für (var i = pos; i < values.length; i++) { // Prozesswerte-Array nach dem übergebenen pos wenn (i > pos) { // Zusätzlich zur ersten Schleife fügen Sie einen Leerzeichen nach der Ergebniszeile hinzu Ergebnis += ; - Ich weiß. wenn (Werte[i] === null) { // Wenn Werte (Array der Funktionsargumente) das aktuelle Indexs-Element null ist, fügt das Ergebnis null hinzu Zeichenfolge Ergebnis += null; } else if (typeof(values[i]) == undefined) { // Wenn es undefined ist, fügen Sie undefined hinzu Ergebnis += unbestimmt; } else { // Die übrigen Typen machen die Schaltdetektion separat switch (values[i].constructor.name) { // Überprüfen Sie die Name-Eigenschaft des Konstruktors von Werte[i], die der Typname ist Fall Datum : Fall Nummer : Fall String: Fall Funktion : result += values[i].toString(); // Wenn es sich um einen Datumstyp, einen numerischen Typ, einen String-Typ oder einen Funktionstyp handelt, rufen Sie die toString-Funktion an und konvertieren Sie sie in eine Zeichenfolge, und fügen Sie dann Unterbrechung; Standard: Ergebnis += JSON.stringify(Werte[i]); // In anderen Fällen verwenden Sie die JSON.stringify-Funktion zur Umwandlung in eine JSON-String. Unterbrechung; - Ich weiß. - Ich weiß. - Ich weiß. Ergebnis zurück; // Ergebnis zurück - Ich weiß.

Funktion Trader() { // Trader-Funktion, die Schließungen verwendet. VAR vId = 0; // Auftragsinkrement ID VAR OrderBooks = []; // Auftragsbuch Var hisBooks = []; // Historische Reihenfolge Var orderBooksLen = 0; // Länge des Auftragsbuchs this.Buy = Funktion ((Preis, Betrag, Extra) { // Kauffunktion, Parameter: Preis, Menge, erweiterte Informationen wenn (typeof(extra) === undefined) { // Wenn der Parameter extra nicht eingegeben wird, d. h. typeof gibt undefined zurück extra = ; // Zuweisen einer leeren Zeichenfolge an extra - Nein. extra = valuesToString ((arguments, 2); // Die Argumentargumente, die beim Aufruf dieser Funktion übergeben werden, werden an die Funktion valuesToString übergeben. - Ich weiß. VId++; // VAR ordId = V + vId; // orderBooks[orderId] = { // Fügen Sie das Attribut orderId zum Ordnungsbuch-Array hinzu und initialisieren Sie es mit dem konstruierten Objekt. Typ: ORDER_TYPE_BUY, // Konstruierte Objektart Eigenschaft: Typ kaufen Status: ORDER_STATE_PENDING, // Stand in der Wartezeit Identifizierung: 0, // OrderID 0 Preis: Preis, // Preisparameter Preis Betrag: Betrag, // Bestellmenge Parameterbetrag Extra: extra // Erweiterte Informationen Eine Zeichenfolge, die von valuesToString verarbeitet wird ); orderBooksLen++; // Die Länge des Auftragsbuchs wird um 1 erhöht return orderId; // Gibt die OrderId der diesmal konstruierten Order zurück (Nicht-Austausch-Order-ID, nicht verwechseln.) ); this.Sell = Funktion ((Preis, Betrag, Extra) { // Grundsätzlich ähnlich wie this.Buy, konstruieren Sie eine Verkaufsanordnung. wenn (Typeof(extra) === undefined) { extra = ; - Nein. extra = valuesToString ((Argumente, 2); - Ich weiß. vId++; Der Wert des Verbrauchs wird in der Tabelle 1 angegeben. - - - - - Typ: ORDER_TYPE_SELL, Der Status ist: ORDER_STATE_PENDING Identifizierung: 0, Preis: Preis Betrag: Betrag Zusätzlich: zusätzlich ); Die Daten werden von der Datenbank erfasst. Rückgabebefehl; ); this.GetOrders = function() { // Erhalten Sie unvollendete Auftragsinformationen VAR-Orders = _C(exchange.GetOrders); // API GetOrders anrufen, um unvollendete Auftragsinformationen zu erhalten für (orderId in orderBooks) { // Durchqueren des OrderBooks im Objekt Trader VAR ORDER = orderBooks[orderId]; // Die Bestellung basierend auf der OrderId herausnehmen wenn (order.Status!== ORDER_STATE_PENDING) { // Wenn der Zustand der Bestellung nicht gleich dem ausgesetzten Zustand ist, überspringen Sie diese Schleife fortfahren; - Ich weiß. var found = false; // Die gefundene Variable (angezeigt, wenn sie gefunden wurde) auf true initialisieren für (var i = 0; i < orders.length; i++) { // Durchlaufdaten für nicht ausgeführte Aufträge, die von der API zurückgegeben werden
wenn (orders[i].Id == order.Id) { // Wenn Sie eine Bestellung mit derselben Order-ID in orderBooks finden, geben Sie einen Wert von true zu finden, was finden bedeutet. gefunden = wahr;
Break; // Aus der aktuellen Schleife springen - Ich weiß. - Ich weiß. wenn (!found) { // Wenn nicht gefunden, drücken Sie orderBooks[orderId] auf Orders. orders.push ((orderBooks[orderId]); // Warum wollen Sie so drücken? - Ich weiß. - Ich weiß. Rückgabeaufträge; // Rückgabeaufträge - Ich weiß. Das hier.GetOrder = Funktion ((orderId) { // Order erhalten wenn (typeof(orderId) === number) { // Wenn das übermittelte Argument orderId ein numerischer Typ ist return exchange.GetOrder(orderId); // Ruf die API GetOrder an, um die Auftragsinformationen basierend auf der OrderId zu erhalten und zurückzugeben. - Ich weiß. wenn (typeof(hisBooks[orderId])!== undefined) { // Typeof(hisBooks[orderId]) wenn nicht gleich undefined ist return hisBooks[orderId]; // Gibt Daten in hisBooks mit dem Attribut orderId zurück - Ich weiß. wenn (typeof(orderBooks[orderId])!== undefined) { // Wie oben, wenn es einen Wert von orderId in den orderBooks gibt, werden diese Daten zurückgegeben. Rücksendungsaufträge[orderId]; - Ich weiß. return null; // Return null, wenn die oben genannten Bedingungen nicht erfüllt sind ); this.Len = function() { // Gibt die Variable OrderBookLen des Händlers zurück, die die Orderbuchlänge zurückgibt. RücksendungsanordnungBooksLen; ); this.RealLen = function() { // Zurück im Auftragsbuch Aktivieren Sie die Auftragsmenge. Var n = 0; // Anfangszahl ist 0 für (orderId in orderBooks) { // Durchqueren des Bestellbuchs wenn (orderBooks[orderId].Id > 0) { // Wenn die Id der aktuellen Reihenfolge im Durchlauf größer als 0 ist, d. h. 0 als die Anfangszeit, // bedeutet, dass die Bestellung platziert wurde, die Bestellung aktiviert wurde. n++; // Kumulativ aktivierte Reihenfolge - Ich weiß. - Ich weiß. return n; // Gibt den Wert von n zurück, der die wahre Bestellbuchlänge zurückgibt. (Anzahl der aktivierten Bestellungen) ); Dies.Umfrage = Funktion (Ticker, PreisDiff) Var-Orders = _C ((exchange.GetOrders); // Alle nicht ausgeführten Orders erhalten für (orderId in orderBooks) { // Durchqueren des Bestellbuchs Var order = orderBooks[orderId]; // Nehmen Sie die aktuelle Bestellung zuordnen wenn (order.Id > 0) { // Wenn die Bestellung aktiv ist, d. h. order.Id nicht 0 ist (bereits platziert) Var gefunden = falsch; // Variable gefunden (Marke gefunden) ist falsch für (var i = 0; i < orders.length; i++) { // Finden Sie die gleiche Auftragsnummer in den ausgeführten Auftragsinformationen, die von der Börse zurückgegeben werden wenn (order.Id == orders[i].Id) { // Wenn gefunden, einen Wert von true zu finden zuweisen, was bedeutet, dass es gefunden wurde. gefunden = wahr; - Ich weiß. - Ich weiß. wenn (!found) { // Wenn die aktuelle OrderId eine Bestellung darstellt, die nicht in der Reihenfolge der vom Austausch zurückgegebenen unvollendeten Bestellung gefunden wird. order.Status = ORDER_STATE_CLOSED; // Aktualisiert die der orderId in orderBooks entsprechende Reihenfolge (d. h. die aktuelle Reihenfolgevariable) und aktualisiert // die Status-Eigenschaft zu ORDER_STATE_CLOSED (d. h. geschlossen) hisBooks[orderId] = Order; // Die abgeschlossene Bestellung wird im historischen Bestellbuch, also hisBooks, einheitlich erfasst und mit der eindeutigen Bestellnummer orderId delete ((orderBooks[orderId]); // Löschen Sie das Attribut des Auftragsbuchs mit dem Namen orderId value. (Die abgeschlossene Bestellung wird aus ihm gelöscht) OrderBooksLen; // Verringerung der Bestellbuchlänge Weiter; // Der folgende Code überspringt die Schleife. - Ich weiß. - Ich weiß. vari diff = _N(Order.Type == ORDER_TYPE_BUY? (ticker.Kauf - Order.Preis) : (order.Price - ticker.Sell)); // Diff ist die Differenz zwischen dem geplanten Eröffnungspreis der Order im aktuellen Auftragsbuch und dem aktuellen Echtzeit-Eröffnungspreis.

        var pfn = order.Type == ORDER_TYPE_BUY ? exchange.Buy : exchange.Sell;   // Assign the corresponding API function reference to pfn according to the type of the order.
        // That is, if the order type is a buy order, pfn is a reference to the exchange.Buy function, the same as the sell order.

        if (order.Id == 0 && diff <= priceDiff) {                                // If the order order in the order book is not activated (ie Id is equal to 0) and the current price is less than or 
                                                                                 // equal to the order plan price, the priceDiff passed in the parameter.   
            var realId = pfn(order.Price, order.Amount, order.Extra + "(distance: " + diff + (order.Type == ORDER_TYPE_BUY ? (" ask price: " + ticker.Buy) : (" bid price: " + ticker.Sell))+")");
            // Execute order function, parameter passing price, quantity, order extension information + pending order distance + market data (ask price or bid price), return exchange order id

            if (typeof(realId) === 'number') {    // If the returned realId is a numeric type
                order.Id = realId;                // Assign the Id attribute of the current order order to the order book.
            }
        } else if (order.Id > 0 && diff > (priceDiff + 1)) {  // If the order is active and the current distance is greater than the distance passed in by the parameter
            var ok = true;                                    // Declare a variable for tagging       Initially set true 
            do {                                              // Execute "do" first and then judge while    
                ok = true;                                    // Ok assign true
                exchange.CancelOrder(order.Id, "unnecessary" + (order.Type == ORDER_TYPE_BUY ? "buying" : "selling"), "placed order price:", order.Price, "volume:", order.Amount, ", distance:", 
                                             diff, order.Type == ORDER_TYPE_BUY ? ("ask price: " + ticker.Buy) : ("bid price: " + ticker.Sell));
                // Cancel the pending order that is out of range. After canceling the order, print the current order information and the current distance diff.

                Sleep(200);                                   // Wait 200 milliseconds
                orders = _C(exchange.GetOrders);              // Call the API to get an uncompleted order in the exchange.
                for (var i = 0; i < orders.length; i++) {     // Traverse these unfinished orders.
                    if (orders[i].Id == order.Id) {           // If the cancelled order is found in the list of orders that have not been completed by the exchange
                        ok = false;                           // Assign ok this variable to false, that is, no cancellation is successful.
                    }
                }
            } while (!ok);                                    // If ok is false, then !ok is true and while will continue to repeat the loop, continue to cancel the order,
                                                              // and check if the cancellation is successful.
            order.Id = 0;                                     // Assigning a value of 0 to order.Id means that the current order is inactive.
        }
    }
};

}

Funktion BalanceAccount (orgAccount, initAccount) { // Balance Account Function Parameter Initial account information when the strategy is started (Initielle Kontoinformation, wenn die Strategie gestartet wird) Call the custom function cancelPending() to cancel all pending orders (Call die benutzerdefinierte Funktion cancelPending() um alle ausstehenden Bestellungen zu stornieren. Variable nowAccount = _C ((exchange.GetAccount); // Declare a variable nowAccount to record the latest information about the account at the moment. Die Variable nowAccount wird von einem anderen Variablen verwendet, um die neuesten Informationen über das Konto zu erfassen. // Set the slip price when placing the order as 0.2 Das Slip-Preis wird bei der Platzierung des Auftrags als 0.2 festgelegt. Variable war initially set true. while (true) { // während Loop Der Unterschied zwischen dem aktuellen Konto und dem anfänglichen Konto wird berechnet. Wenn der absolute Wert der Währungsdifferenz kleiner ist als das minimale Transaktionsvolumen der Börse, dann ist die Währungsdifferenz der Währungsdifferenz, wenn der absolute Wert der Währungsdifferenz kleiner ist als das minimale Transaktionsvolumen der Börse, dann ist die Währungsdifferenz der Währungsdifferenz kleiner als das minimale Transaktionsvolumen der Börse. // der Break springt aus der Schleife und führt keine Balancing Operationen durch. Ich bin nicht derjenige. Wir sind hier. VAR DEEPTH = _C (exchange.GetDepth); // Get the exchange depth information Zuordnen Sie die erklärte Tiefe-Variable VAR books = diff > 0? depth.Bids : depth.Asks; // According the difference of the currency is greater than 0 or less than 0, extract the buy order array or // sell order array in depth (gleich 0 wird nicht verarbeitet, es wird gebrochen, wenn es als weniger als GetMinStock beurteilt wird) // Die Differenz zwischen den Coins ist größer als 0 um den Saldo zu verkaufen, also schauen Sie sich das Buy-Order-Array an, // die Differenz zwischen den Münzen ist weniger als 0 ist das Gegenteil. Das ist der Punkt, an dem die Angabe n initial 0 ist. Der Preis ist 0; for (var i = 0; i < books.length; i++) { // Traversing the buy or sell order array n += books[i].Amount; // Accumulate Amount (order quantity) for each order based on the index i traversed Die Anzahl der Bücher, die ich bestelle if (n >= Math.abs ((diff)) { // If the cumulative order quantity n is greater than or equal to the currency difference, then: Wenn die kumulative Ordermenge n größer oder gleich der Währungsdifferenz ist, dann: price = books[i].Price; // Get the price of the current indexed order, assign it to price (Erhalten Sie den Preis der aktuellen indizierten Bestellung und geben Sie ihn dem Preis zu) break; // Jump out of the current for traversal cycle (Springen Sie sich aus dem Strom für den Durchlaufzyklus) Wir sind hier. Wir sind hier. - Pass the sell order API (exchange.Sell) or the next buy order API (exchange.Buy) reference to the declared pfn. - Pass the sell order API (exchange.Sell) or the next buy order API (exchange.Buy) reference to the declared pfn. - Pass the sell order API (exchange.Sell) or the next buy order API (exchange.Buy) reference to the declared pfn. - Pass the sell order API (exchange.Sell) or the next buy order API (exchange.Buy) reference to the declared pfn // basierend auf der Währungsdifferenz größer als 0 oder kleiner als 0 Der Betrag der Order, die ausgeglichen werden soll, ist diff, die Differenz in der Währung, zugewiesen an die erklärte Betrag variable. (Price + slidePrice); // The direction of buying and selling according to the difference in the currency, increase or decrease the difference in the currency Die Richtung des Kaufs und Verkaufs entsprechend der Differenz in der Währung, increase or decrease the // Slip price based on the price (Slip price is to make it easier to trade), und dann zuordnen Sie es zum Preis Log ((start the balance, (diff > 0? sell: buy), amount, of coins); // The number of coins that the output log balances (Die Anzahl der Coins, die der Output-Log ausgleicht). if (diff > 0) { // According to the direction of the buying and selling, determine whether the account currency or the amount of coins is sufficient. Wenn die Währung des Kontos oder der Betrag der Münzen ausreichend ist, wird die Währung des Kontos oder der Betrag der Münzen bestimmt. amount = Math.min ((nowAccount.Stocks, amount); // Make sure that the order amount will not exceed the available coins of the current account. (Machen Sie sicher, dass der Auftragsbetrag die verfügbaren Münzen des aktuellen Kontos nicht übersteigt.) } else { amount = Math.min ((nowAccount.Balance / price, amount); // Stellen Sie sicher, dass der Betrag der platzierten Bestellung nicht den Betrag des Geldes übersteigt, der im aktuellen Konto verfügbar ist. Wir sind hier. Check if (amount < exchange.GetMinStock()) { // Check if the final order quantity is less than the minimum order quantity allowed by the exchange Wenn die Anzahl der Bestellungen kleiner ist als die Anzahl der Bestellungen, die von der Börse erlaubt werden Log (( Insufficient funds, unable to balance to the initial state); // Wenn die Bestellmenge zu klein ist, wird die Information gedruckt. OK = Falsch; // Tag Balance fehlgeschlagen break; // Jump out of the while loop (Springen Sie aus der While-Schleife) Wir sind hier. pfn ((price, amount)); // Execute order API (pfn reference) Sleep ((1000); // Pause für 1 Sekunde - - - - - - - - - - - - - - - nowAccount = _C ((exchange.GetAccount); // Erhalten Sie aktuelle Kontoinformationen Wir sind hier. execute the code inside curly braces when ok is true (balance is successful) wenn ok wahr ist (balance ist erfolgreich) LogProfit ((_N ((nowAccount.Balance - orgAccount.Balance)); // Verwenden Sie die Balance-Eigenschaft des eingehenden Parameters orgAccount (account information before balancing) // um die Balance-Eigenschaft der Leistungsinformationen abzuziehen, das heißt, die Differenz in der Menge an Geld. Das ist, Profit and Loss (weil die Anzahl der Münzen nicht ändert, es gibt einen leichten Fehler, weil einige kleine // Beträge können nicht ausgeglichen werden) Log (Log ausgeglichen, nowAccount); // Der Output log ist ausgewogen. Wir sind hier. Wir sind hier.

var STATE_WAIT_OPEN = 0; // Wird für den Zustand jedes Knoten in der fishTable verwendet Die Daten werden von den zuständigen Behörden des Mitgliedstaats übermittelt. Die Daten werden in der Tabelle aufgeführt. var ProfitCount = 0; // Gewinn- und Verlustrechnung Var BuyFirst = true; // Anfangsparameter der Schnittstelle var IsSupportGetOrder = true; // bestimmen Sie den Austausch der GetOrder API-Funktion, einer globalen Variablen, die zum Beginn der Hauptfunktion verwendet wird var LastBusy = 0; // Das letzte verarbeitete Zeitobjekt aufgezeichnet

Funktion setBusy() { // Setze Busy Zeit LastBusy = new Date(); // LastBusy dem aktuellen Zeitobjekt zuweisen - Ich weiß.

Funktion isTimeout() { // Bestimmen, ob es Zeit abläuft wenn (MaxIdle <= 0) { // Maximale Leerlaufzeit (je nachdem, ob das Gitter automatisch verschoben wird), // wenn die maximale Leerlaufzeit MaxIdle kleiner oder gleich 0 ist return false; // Gibt false zurück, beurteilt nicht den Timeout. Das heißt, immer false ohne Timeout zurück. - Ich weiß. Var now = new Date ((); // Erhalten Sie das aktuelle Zeitobjekt wenn (((now.getTime() - LastBusy.getTime()) / 1000) >= MaxIdle) { // Verwenden Sie die Funktion getTime des aktuellen Zeitobjekts, um den Zeitstempel und den Zeitstempel von LastBusy zu erhalten, um den Unterschied zu berechnen, // Teilen Sie durch 1000, um die Anzahl der Sekunden zwischen den beiden Zeitobjekten zu berechnen. // Bestimmen Sie, ob es größer ist als die maximale Leerlaufzeit MaxIdle LastBusy = jetzt; // Wenn es größer ist als, aktualisieren LastBusy zum aktuellen Zeitobjekt jetzt return true; // Gibt true zurück, was ein Timeout ist. - Ich weiß. zurückkehren false; // zurückkehren false no timeout - Ich weiß.

Funktion onexit() { // Die Schließfunktion, wenn das Programm beendet wird. wenn (CancelAllWS) { // Um alle ausstehenden Bestellungen zu stornieren, rufen Sie cancelPending ((() an, um alle ausstehenden Bestellungen zu stornieren. Log ((Aussteigen, versuchen alle ausstehenden Bestellungen zu stornieren); Absagen (ausstehend) - Ich weiß. Log ((Strategie erfolgreich gestoppt); Log ((_C(exchange.GetAccount)); // Drucken Sie die Konto-Positionsinformationen, wenn Sie das Programm beenden. - Ich weiß.

Funktion Fischerei ((orgZahl, FischZahl) { // Gießparameter: Kontoinformationen, Anzahl der Gießen setBusy(); // LastBuys auf den aktuellen Zeitstempel setzen var account = _C(exchange.GetAccount); // Deklarieren Sie eine Kontovariable, um die Informationen zum aktuellen Konto zu erhalten und zuzuweisen. Log ((account); // Ausgabe der Kontoinformationen zu Beginn des Anrufs an die Fischereifunktion. War InitAccount = Konto; // Deklarieren Sie eine Variable InitAccount und zuweisen Sie es mit Konto. // dieses Gießen, verwendet, um schwebenden Gewinn und Verlust zu berechnen.
Var ticker = _C(exchange.GetTicker); // Erhalten Sie den Angabewert, der der angegebenen Ticker-Variablen zugeordnet ist var amount = _N(AmountOnce); // Verwenden Sie _N, um die Dezimalstellen zu verarbeiten (_N ist standardmäßig 2 Bits) und zuweisen Sie diese an amount. Var amountB = [amount]; // Eine Variable mit dem Namen amountB deklarieren ist ein Array, ein Element mit amount initialisieren Var amountS = [betrag]; // Eine Variable mit dem Namen amountS deklarieren... wenn (typeof(AmountType)!== undefined && AmountType == 1) { // Nach dem benutzerdefinierten Betrag, dem Bestellgrößentyp, wenn dieser Schnittstellenparameter nicht undefined ist, // Und AmountType ist auf eine benutzerdefinierte Menge auf der Schnittstelle gesetzt, das heißt, der AmountType Wert ist 1 (der Index des Dropdown-Box) für (var idx = 0; idx < AllNum; idx++) { // Die Gesamtzahl der AllNum. Wenn Sie einen benutzerdefinierten Betrag festlegen, führen Sie den Zyklus amountB/amountS in das Reihenfolge-Menge-Array entsprechend der Gesamtzahl der Zyklen. amountB[idx] = BAmountOnce; // Zuordnen Sie dem Kaufbestellungsarray einen Wert mithilfe von Schnittstellenparametern Die Anzahl der Bestellungen, die in den Bestellungen enthalten sind, wird in den Bestellungen angegeben, die in den Bestellungen enthalten sind. - Ich weiß. { \ cH00FFFF } sonst { \ cH00FFFF } sonst für (var idx = 1; idx < AllNum; idx++) { // Zyklen basierend auf der Gesamtzahl der Gitter. switch (AmountCoefficient[0]) { // Gemäß dem Parameterunterschied der Schnittstelle ist das erste Zeichen der Zeichenfolge AmountCoefficient[0] +, -, , / Fall +: // Gemäß den Schnittstellenparametern wird ein Gitter mit einer einzigen Ergänzung und Inkrement konstruiert. Die in Absatz 1 genannten Daten werden in der Tabelle 1 aufgeführt. Unterbrechung; Fall -: //... Die Daten werden von der Datenbank für die Bereitstellung von Daten über die Datenverarbeitung erfasst. Unterbrechung; Fall : Die Daten werden von den zuständigen Behörden der Mitgliedstaaten übermittelt. Unterbrechung; Fall /: Die in Absatz 1 genannten Daten werden in der Tabelle 1 aufgeführt. Unterbrechung; - Ich weiß. amountB[idx] = _N(amountB[idx], AmountDot); // Kaufbestellung, Kaufbetrag und Verarbeitung der Daten zu Dezimalstellen. Ausgabe von Zuschüssen - Ich weiß. - Ich weiß. wenn (FirstPriceAuto) { // Wenn der erste Parameter automatisch auf true gesetzt wird, wenn der Schnittstellenparameter gesetzt ist, wird der Code innerhalb der if-Klammern ausgeführt. Erster Preis = Erster Kauf? _N(ticker.Käufe - Preis-Grid, Präzision) : _N(ticker.Verkauf + Preis-Grid, Präzision); // Der Schnittstellenparameter FirstPrice legt den ersten Preis gemäß der globalen Variablen BuyFirst fest (die Anfangsanweisung ist wahr, // und wurde nach dem OpType am Anfang des Haupttextes zugewiesen). // Der Preis wird durch den Preis-Ticker und den Preisparameter PriceGrid Preisintervall festgelegt.
- Ich weiß. // Fischtabelle initialisieren
VAR fishTable = {}; // Ein Gitterobjekt deklarieren Var uuidTable = {}; // Objekt der Identifikationscode-Tabelle Var needStocks = 0; // erforderliche Münzen variable Var needMoney = 0; // Erforderliche Geldvariable Var realNeedMoney = 0; // Eigentlich Geld benötigt var actualNeedStocks = 0; // tatsächlich benötigte Münzen var notEnough = false; // Unterfinanzierte Tag-Variable, ursprünglich auf false gesetzt Var canNum = 0; // Verfügbares Gitter für (var idx = 0; idx < AllNum; idx++) { // Die Struktur wird nach der Anzahl des Rasters AllNum durchlaufen. VAR-PRICE = _N((BuyFirst? FirstPrice - (idx * PriceGrid) : FirstPrice + (idx * PriceGrid)), Präzision); // Beim Durchqueren des Konstrukts wird die aktuelle Index-IDX-Preiseinstellung nach BuyFirst festgelegt. needStocks += amountS[idx]; // Die Anzahl der verkauften Münzen wird im Zyklus allmählich angesammelt. needMoney += Preis * BetragB[idx]; // Der Geldbetrag, der zum Kauf benötigt wird, wird im Zyklus allmählich angesammelt. wenn (BuyFirst) { // Handling kaufen zuerst wenn (_N(bedarfGeld) <= _N(Konto.Guthaben)) { // Wenn das Netz weniger Geld benötigt als der auf dem Konto verfügbare Geldbetrag realNeedMondy = needMoney; // dem tatsächlichen Geldbetrag zugeordnet realNeedStocks = needStocks; // Zuweisung an die tatsächliche Anzahl der benötigten Münzen. canNum++; // Kumulative Anzahl der verfügbaren Gitter } else { // _N(needMoney) <= _N(account.Balance) Wenn diese Bedingung nicht erfüllt ist, wird die Variable "underfunded" auf "true" gesetzt. notEnough = wahr; - Ich weiß. { \ cH00FFFF } sonst { \ cH00FFFF } Handling verkaufen zuerst wenn (_N(bedarfStocks) <= _N(account.Stocks)) { // Überprüfen Sie, ob die erforderliche Anzahl von Münzen kleiner ist als die Anzahl der auf dem Konto verfügbaren Münzen realNeedMondy = needMoney; // Zuweisung realNeedStocks = needStocks canNum++; // Kumulative Anzahl der verfügbaren Gitter - Nein. notEnough = true; // Wenn die Finanzierungsbedingungen nicht erfüllt sind, wird true gesetzt - Ich weiß. - Ich weiß. fishTable[idx] = STATE_WAIT_OPEN; // Nach dem aktuellen Index idx den Status des idx-Mitglieds (Gitterknoten) des Gitterobjekts festlegen, // zunächst STATE_WAIT_OPEN (Wartet auf die Öffnung der Position) uuidTable[idx] = -1; // Das nummerierte Objekt initialisiert auch seinen eigenen idx-Wert (den Knoten, der dem fishTable entspricht) auf -1 basierend auf der aktuellen idx. - Ich weiß. wenn (!EnableAccountCheck && (canNum < AllNum)) { // Wenn die Überprüfung der Mittel nicht aktiviert ist, und die Anzahl der Gitter (die Gesamtzahl der Knoten), bei denen der Knoten kleiner ist // als die Interface-Parameter-Einstellung geöffnet werden kann. Log ((Warnung, nur laufende Mittel können erworben werden, canNum, von Netzen, Gesamtnetzbedarf, (BuyFirst? needMoney: needStocks), Bitte genügend Mittel behalten); // Log liefert eine Warnmeldung. canNum = AllNum; // Aktualisieren der Anzahl der Öffnbarkeitseinstellungen für die Schnittstellenparameter - Ich weiß. wenn (BuyFirst) { // zuerst kaufen if (EnableProtectDiff && (FirstPrice - ticker.Sell) > ProtectDiff) { // Öffnen Sie den Spread-Schutz und geben Sie den Marktpreis abzüglich des aktuellen Gebotspreises mehr als // die Markteintrittspreissicherung
Werfen Der erste Kaufpreis ist höher als der Marktverkaufspreis + _N(FirstPrice - ticker.Sell, Präzision) + Dollar; // Werfen Sie eine Fehlermeldung. } else if (EnableAccountCheck && account.Balance < _N(needMoney)) { // Wenn die Überprüfung der Mittel aktiviert ist und der für das Konto verfügbare Geldbetrag kleiner ist als // die Menge an Geld, die für das Netz benötigt wird. wenn (fishCount == 1) { // Wenn es das erste Mal ist, das Raster zu werfen Werfen Sie Unzureichende Mittel, Notwendigkeit + _N(notwendigkeitGeld) + Dollar; // Werfen Sie einen Fehler, unzureichende Mittel - Nein. Log ((Unzureichende Mittel, Bedarf, _N(bedarfMoney), Dollar, das Programm macht nur, kannNum, von Gitter #ff0000); // Wenn es nicht das erste Mal ist, ein Gitter zu werfen, eine Nachricht ausgeben. - Ich weiß. In anderen Fällen gibt es keine Kapitalkontrolle, keinen Preisschutz usw. Log ((Schätzung der Verwendung von Mitteln: , _N ((needMoney), dollar); // Die Ausgabe wird voraussichtlich Mittel verwenden. - Ich weiß. } else { // verkaufen zuerst, Das folgende ist ähnlich wie kaufen zuerst wenn (EnableProtectDiff && (ticker.Buy - FirstPrice) > ProtectDiff) { Werfen Der erste Verkaufspreis ist höher als der Marktkaufpreis + _N(ticker.Buy - FirstPrice, Präzision) + Dollar; } anders wenn (AkcountCheck aktivieren && account.Stocks < _N(needStocks)) { wenn (FishCount == 1) { Werfen Sie Unzureichende Mittel, Bedarf + _N(bedarfStocks) + von Münzen ; - Nein. Log ((Unzureichende Mittel, Bedarf, _N(bedarfStocks), von Münzen, Programm nur machen, kannNum, von Gitter #ff0000); - Ich weiß. - Nein. Log ((Schätzung der Verwendung von Mitteln: , _N(needAktien), Münzen, ca., _N(needGeld), Dollar); - Ich weiß. - Ich weiß.

var trader = new Trader();                                          // Constructs a Trader object, assigning it to the trader variable declared here.
var OpenFunc = BuyFirst ? exchange.Buy : exchange.Sell;             // According to whether to buy and sell first, set the open function OpenFunc to refer to exchange.Buy or exchange.Sell
var CoverFunc = BuyFirst ? exchange.Sell : exchange.Buy;            // same as above
if (EnableDynamic) {                                                // Set OpenFunc/CoverFunc again according to whether the interface parameter EnableDynamic is enabled.
    OpenFunc = BuyFirst ? trader.Buy : trader.Sell;                 // The member function Buy that references the trader object is used for dynamic pending orders (mainly because 
                                                                    // some exchanges limit the number of pending orders, so virtual dynamic pending orders are required)
    CoverFunc = BuyFirst ? trader.Sell : trader.Buy;                // same as above
}
var ts = new Date();                                                // Create a time object at this time (assigned to ts) to record the time at the moment.
var preMsg = "";                                                    // Declare a variable to record the last message, the initial set to empty string
var profitMax = 0;                                                  // Maximum return 
while (true) {                                                      // The main logic after the grid is casted
    var now = new Date();                                           // Record the time when the current cycle started
    var table = null;                                               // Declare a variable
    if (now.getTime() - ts.getTime() > 5000) {                      // Calculate whether the difference between the current time now and the recorded time ts is greater than 5000 milliseconds
        if (typeof(GetCommand) == 'function' && GetCommand() == "Receiving grid") {         // Check if the strategy interaction control command "receives the grid" is received, 
                                                                                            // stops and balances to the initial state.
            Log("Start executing commands to perform grid operations");                                          // Output information 
            balanceAccount(orgAccount, InitAccount);                              // Perform a balancing function to balance the number of coins to the initial state
            return false;                                                         // This time the grid function is fishing and return false
        }
        ts = now;                                                                 // Update ts with current time now for next comparison time
        var nowAccount = _C(exchange.GetAccount);                                 // Declare the nowAccount variable and initially been set as the current account information. 
        var ticker = _C(exchange.GetTicker);                                      // Declare the ticker variable and initially been set as the current market information.
        if (EnableDynamic) {                                                      // If you enable dynamic pending orders
            trader.Poll(ticker, DynamicMax);                                      // Call the Poll function of the trader object to detect and process all orders based on the 
                                                                                  // current ticker market and the interface parameter DynamicMax.
        }
        var amount_diff = (nowAccount.Stocks + nowAccount.FrozenStocks) - (InitAccount.Stocks + InitAccount.FrozenStocks);  // Calculate the current coin difference
        var money_diff = (nowAccount.Balance + nowAccount.FrozenBalance) - (InitAccount.Balance + InitAccount.FrozenBalance); // Calculate the current money difference
        var floatProfit = _N(money_diff + (amount_diff * ticker.Last));           // Calculate the current floating profit and loss of this time of casting grid
        var floatProfitAll = _N((nowAccount.Balance + nowAccount.FrozenBalance - orgAccount.Balance - orgAccount.FrozenBalance) + ((nowAccount.Stocks + nowAccount.FrozenStocks 
                                 - orgAccount.Stocks - orgAccount.FrozenStocks) * ticker.Last));
        // Calculate the overall floating profit and loss

        var isHold = Math.abs(amount_diff) >= exchange.GetMinStock();             // If the absolute value of the coin difference at this moment is greater than the minimum trading 
                                                                                  // volume of the exchange, it means that the position has been held.
        if (isHold) {                                                             // If you have already held a position, execute the setBusy() function, which will update the LastBusy time.
            setBusy();                                                            // That is, after opening the position, the opening of the opening mechanism is started.
        }

        profitMax = Math.max(floatProfit, profitMax);                             // Refresh the maximum floating profit and loss
        if (EnableAccountCheck && EnableStopLoss) {                               // If you initiate account detection and start a stop loss
            if ((profitMax - floatProfit) >= StopLoss) {                          // If the maximum floating profit or loss minus the current floating profit or loss is greater than or equal to 
                                                                                  // the maximum floating loss value, execute the code inside the curly braces
                Log("Current floating profit a

Weitere Informationen