Les ressources ont été chargées... Je charge...

La stratégie de négociation du réseau

Auteur:La bonté, Créé: 2018-08-23 13:45:27, mis à jour:

La stratégie de négociation du réseau (www.fmz.com) L'idée de base du trading en grille est très simple. Au lieu de placer une transaction, nous plaçons plusieurs transactions formant un modèle de grille. Habituellement, celles-ci sont entrées sous forme d'ordres stop ou limit autour du niveau de prix actuel mais pas toujours. Je vais expliquer cela plus en détail ci-dessous, mais c'est l'idée de base.

Qu'est-ce que le trading de réseau et comment fonctionne-t-il? Le trading par grille est un jeu sur la volatilité du marché. Il y a deux raisons pour lesquelles il est préféré par les traders. La première est qu'il ne vous oblige pas à avoir une prédiction définitive sur la direction du marché.

La seconde est qu'il fonctionne bien sur les marchés volatils, où il n'y a pas de tendance claire ces conditions sont très courantes sur les marchés de change

Le trading par grille est un type de trading d'analyse technique basé sur le mouvement dans des modèles de grille spécifiques. Le trading par grille est populaire dans le trading de devises.

La grille peut personnaliser la direction

Opération commerciale de base: acheter d'abord et ensuite vendre.

La grille commencera à envoyer un ordre d'achat au prix inférieur au premier prix, qui est le prix suivi du premier prix (deuxième dernier prix d'achat, troisième dernier prix d'achat...et ainsi de suite).

Après tout ordre d'achat est terminé, le programme sera sur la base du prix d'achat, ajouter le prix de la différence de prix paramètre au prix de vente, après l'ordre a été vendu, puis redémarrer la progression de cette stratégie de grille (vérification, place de l'ordre, attendre jusqu'à ce qu'il soit exécuté, vendre)

Vendre à découvert d'abord et acheter ensuite pour couvrir: l'opération est tout le contraire

Le plus grand risque de cette stratégie est lorsque la tendance du marché est unilatérale et que les fluctuations des prix dépassent la grille.

Le code suivant a fait la grille avec une fonction d'arrêt automatique et de mouvement.

Commentaires:

La stratégie utilise une conception d'ordre en attente virtuelle, qui fournit une grande quantité de traitement pour l'échange afin de limiter le nombre d'ordres en attente, et résout le problème de manière flexible.

La grille logique est flexible dans sa conception et intelligente dans sa structure.

Calcul des profits et pertes, chaque algorithme statistique numérique peut être utilisé à titre de référence, et chaque conception de détection de condition est rigoureuse. (pour minimiser la possibilité de BUG)

Le code source vaut la peine d'être appris.

Pour plus d'informations, veuillez consulter:

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

Code source:

` // Grille peut personnaliser la direction // Opération de trading de base: acheter d'abord et ensuite vendre. // La grille va commencer à envoyer l'ordre d'achat au prix qui est en dessous du premier prix, qui est le prix de suivre Chaque ordre d'achat est séparé par // le paramètre intervalle de prix. Le nombre d'ordres en attente est quantité unique, et enverra le total de l'ordre jusqu'à ce que // la quantité totale est remplie. // Après tout ordre d'achat est terminée, le programme sera sur la base du prix d'achat, ajouter le prix du prix // différence paramètre au prix de vente, après l'ordre a été vendu, puis redémarrer la progression de ce // stratégie de grille (vérification, ordre de place, attendre jusqu'à ce qu'il soit exécuté, vendre) // Vendre à découvert d'abord, puis acheter pour couvrir: l'opération est tout le contraire // Le plus grand risque de cette stratégie est lorsque la tendance du marché est unilatérale et que les fluctuations de prix dépassent la grille. // Le code suivant a fait la grille avec la perte d'arrêt automatique et la fonction de mouvement. // Commentaires: // La stratégie utilise une conception d'ordre en attente virtuelle, qui fournit une grande quantité de traitement pour l'échange de limiter le nombre // des commandes en attente, et résout le problème de façon flexible. // La grille logique est flexible dans la conception et intelligente dans la structure. // calcul des profits et des pertes, chaque algorithme statistique numérique peut être utilisé à titre de référence, et chaque conception de détection de condition // est rigoureux. (pour minimiser la possibilité de BUG) Le code source est très intéressant à apprendre.

// Code source: /* Paramètres d'interface (indiqués sous forme de variables globales dans le code) OpType Grille Direction Boîte déroulante (sélectionnée) Acheter d'abord, puis vendre. Le prix initial automatique automatique (vrai/faux) Le prix initial automatique numérique (numéro) 100 Nombre total numérique (nombre) 10 PriceGrid Intervalle numérique (numéro) 1 Différence de prix numérique (nombre) 2 QuantitéTypes de commande Taille boîte déroulante (sélectionnée) acheter et vendre le même montant Quantité numérique (nombre) de la transaction unique BAmountOnce@AmountType==1 Taille de commande numérique (nombre) 0.1 SAmountOnce@AmountType==1 Taille numérique (numéro) de l'ordre de vente 0.1 QuantitéCoefficient@AmountType==0 Différence de quantité Chaîne (chaîne) *1 AmountDot Le point décimal numérique (nombre) 3 ActiverProtectDiff Activer la protection contre les écarts Booléen (vrai/faux) faux ProtégerDiff@EnableProtectDiff Différence d'entrée de l'écart de protection des prix numérique (numéro) 20 CancelAllWS stop annule tous les ordres en attente Booléen (vrai/faux) vrai CheckInterval Numéro numérique de l'intervalle de vote (numéro) 2000 Intervalle d'échec de la réessai Numérique (numéro) 1300 RestoreProfit rétablit le dernier bénéfice Booléen (vrai/faux) faux Dernier bénéfice@RestoreProfit Dernier bénéfice numérique (nombre) 0 ProfitAsOrg@RestoreProfit Dernier bénéfice compté comme prix moyen Boole (vrai/faux) faux ActiverAccountCheck activer la vérification du solde Booléen (vrai/faux) vrai Définition de l'opération de démarrage de l'opération StopLoss@EnableStopLoss Perte flottante maximale numérique (nombre) 100 StopLossMode@EnableStopLoss Opération de perte post-stop Boîte déroulante (sélectionnée) Recycler et sortir Activation de l'option de prise de bénéfices en mode booléen (vrai/faux) StopWin@EnableStopWin Profit variable maximal Type de numéro (numéro) 120 StopWinMode@EnableStopWin boîte déroulante d'opération après prise de profit (sélectionnée) Recycler et sortir. Automove@EnableAccountVérifier le déplacement automatiqueBooléen (vrai/faux) faux MaxDistance@AutoMove distance maximale numérique (nombre) 20 MaxIdle@AutoMove temps d'arrêt maximal (secondes) numérique (nombre) 7200 Activation dynamique Tourne sur les commandes en attente dynamiques Booléen (vrai/faux) faux DynamicMax@EnableDynamic Distance d'expiration de l'ordre Numéro (nombre) 30 ResetData efface toutes les données au démarrage Boolean (vrai/faux) vrai Prix de précision longueur décimale numérique (numéro) 5 */

fonction hasOrder ((ordres, orderId) { // Vérifiez s'il existe une commande avec l'ID de commande dans les commandes de paramètres pour (var i = 0; i < orders.length; i++) { // Traverser des ordres pour vérifier s'il y a les mêmes id, s'il y en a alors retourner vrai si (ordres[i].Id == ordreId) { retourner true; Je ne sais pas. Je ne sais pas. retourner false; // Tout traversé, pas de déclencheur si signifie n'ont pas trouvé l'ordre avec l'ordre ID, retourner false Je ne sais pas.

fonction annulerPending() { // Annuler toutes les fonctions de commande en attente Var ret = faux; // Retourner la variable de la balise de réussite pendant (true) { // pendant boucle si (ret) { // Si ret est vrai alors Dormez pendant un certain temps Le sommeil (intervalle); Je ne sais pas. var commandes = _C(exchange.GetOrders); // Appeler l'API pour obtenir les informations d'ordre que l'échange n'a pas exécuté. si (ordres.length == 0) { // Si un tableau vide est renvoyé, l'échange n'a pas d'ordres non exécutés. pause; // Sauter hors de la boucle pendant Je ne sais pas.

    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

}

fonction valuesToString(values, pos) { // Valeur convertie en une chaîne Var résultat = ; // Déclarer un résultat de chaîne vide pour retourner si (typeof(pos) === undefined) { // Si le paramètre pos n'est pas passé, attribuer à pos une valeur de 0. pos = 0; Je ne sais pas. pour (var i = pos; i < values.length; i++) { // Processus des valeurs du tableau selon le pos passé si (i > pos) { // En plus de la première boucle, ajoutez un espace après la chaîne de résultats résultat += ; Je ne sais pas. si (values[i] === null) { // Si les valeurs (tableau de liste d'arguments de la fonction) l'élément indexs actuel est nul alors le résultat ajoute null chaîne le résultat += null; } else if (typeof(values[i]) == undefined) { // Si elle est indéfinie, ajouter undefined résultat += indéfini; } else { // Le type restant effectue la détection de commutateur séparément switch (values[i].constructor.name) { // Vérifiez la propriété de nom du constructeur de valeurs[i], qui est le nom de type cas date : cas numéro : cas String: cas fonction : résultat += valeurs[i].toString(); // S'il s'agit d'un type de date, un type numérique, un type de chaîne ou un type de fonction, appelez sa fonction toString et convertissez-la en chaîne, puis ajoutez une rupture; par défaut: résultat += JSON.stringify(values[i]); // Dans les autres cas, utilisez la fonction JSON.stringify pour convertir en une chaîne JSON. Ajouter au résultat une rupture; Je ne sais pas. Je ne sais pas. Je ne sais pas. retourner le résultat; // retourner le résultat Je ne sais pas.

fonction Trader() { // fonction Trader, utilisant des fermetures. Var vId = 0; // Identifiant de l'incrément de commande Var orderBooks = []; // Livre de commandes Var hisBooks = []; // Livre d'ordre historique Var orderBooksLen = 0; // La longueur du carnet de commandes this.Buy = fonction ((prix, montant, supplément) { // Fonction d'achat, paramètres: prix, quantité, informations détaillées si (typeof(extra) === undefined) { // Si le paramètre extra n'est pas passé, c'est-à-dire que typeof renvoie undefined extra = ; // Assigner une chaîne vide à extra { \ pos (192,230) } autre extra = valuesToString ((arguments, 2); // Les arguments d'argument passés lors de l'appel de cette fonction. Je ne sais pas. VId++; // Var ordId = V + vId; // orderBooks[orderId] = { // Ajoutez l'attribut orderId au tableau du carnet de commandes et initialisez-le avec l'objet construit. Type: ORDER_TYPE_BUY, // Propriété de type d'objet construit: type acheter État: ORDER_STATE_PENDING, // État en attente Id: 0, // ordreID 0 Prix: prix, // paramètre prix prix Quantité: quantité, // quantité de commande Paramètre de quantité Extra: extra // Informations étendues Une chaîne traitée par valuesToString Le nombre de personnes concernées orderBooksLen++; // La longueur du carnet de commandes est augmentée de 1 retourner l'ordreId; // renvoie l'ordreId de l'ordre construit cette fois (ID de commande non échangeable, ne pas confondre.) Le nombre de personnes concernées Ceci.Vendre = fonction ((prix, montant, supplémentaire) { // Fondamentalement similaire à ceci.Acheter, construire un ordre de vente. si (typeof(extra) === indéfini) { extra = ; { \ pos (192,230) } autre extra = valeursToString ((arguments, 2); Je ne sais pas. vId++; le nombre de fois où la valeur de l'indicateur est supérieure à 1 Le nombre de commandes est le nombre de commandes. Le type d'échange est le suivant: Le statut est: ORDER_STATE_PENDING, Identifiant: 0, Prix: le prix, Montant: le montant Supplémentaire: supplémentaire Le nombre de personnes concernées commandBooksLen++; l'ordre de retour; Le nombre de personnes concernées this.GetOrders = fonction (() { // Obtenez des informations sur les commandes inachevées Var commandes = _C(exchange.GetOrders); // Appel à l'API GetOrders pour obtenir des informations de commande inachevées Assigné aux commandes pour (orderId dans orderBooks) { // Traverser les orderBooks dans l'objet Trader Var order = orderBooks[orderId]; // Retirer l'ordre basé sur l'ordreId si (ordre.Status!== ORDER_STATE_PENDING) { // Si l'état d'ordre n'est pas égal à l'état de suspension, sautez cette boucle poursuivre; Je ne sais pas. Var trouvé = faux; // Initialiser la variable trouvée (marquée si trouvée) à vrai pour (var i = 0; i < orders.length; i++) { // Traverser les données pour les ordres non exécutés renvoyés par l'API
si (ordres[i].Id == order.Id) { // Lorsque vous trouvez un ordre avec le même id d'ordre dans orderBooks, attribuer une valeur de vrai à trouver, ce qui signifie trouver. trouvé = vrai;
pause; // Sauter hors de la boucle actuelle Je ne sais pas. Je ne sais pas. si (!found) { // Si ce n'est pas le cas, appuyez sur orderBooks[orderId] pour les commandes. commandes.push ((orderBooks[orderId]); // Pourquoi voulez-vous pousser comme ça? Je ne sais pas. Je ne sais pas. commandes de retour; Je ne sais pas. Cette.GetOrder = fonction ((orderId) { // Obtenez l'ordre si (typeof(orderId) === number) { // Si l'ordre d'argument passéId est un type numérique retour exchange.GetOrder(orderId); // Appeler l'API GetOrder pour obtenir les informations de commande basées sur l'ordreId et retourner. Je ne sais pas. si (typeof(hisBooks[orderId])!== undefined) { // Typeof(hisBooks[orderId]) si ce n'est pas égal à défini retourner hisBooks[orderId]; // Renvoyer des données dans hisBooks avec attribut orderId Je ne sais pas. si (typeof(orderBooks[orderId])!== undefined) { // Comme ci-dessus, s'il y a une valeur de orderId dans les orderBooks, ces données sont renvoyées. Les données relatives à l'ordre de retour[ordreId]; Je ne sais pas. retourner null; // retourner null si les conditions ci-dessus ne sont pas remplies Le nombre de personnes concernées this.Len = function() { // Renvoie la variable OrderBookLen du Trader, qui renvoie la longueur du carnet d'ordres. Retour de commandeBooksLen; Le nombre de personnes concernées this.RealLen = function() { // Retour dans le carnet de commandes Activer la quantité de commande. Var n = 0; // Le nombre initial est de 0 pour (orderId in orderBooks) { // Traverser le carnet de commandes si (orderBooks[orderId].Id > 0) { // Si l'Id de l'ordre actuel dans la traversée est supérieur à 0, c'est-à-dire 0 autre que le temps initial, // indiquant que la commande a été passée, la commande a été activée. n++; // ordre activé cumulativement Je ne sais pas. Je ne sais pas. retour n; // Renvoie la valeur de n, qui renvoie la longueur réelle du carnet de commandes. (nombre de commandes activées) Le nombre de personnes concernées Ceci.Poll = fonction ((ticker, prixDiff) { // Var commandes = _C ((exchange.GetOrders); // Obtenez toutes les commandes non exécutées pour (orderId in orderBooks) { // Traverser le carnet de commandes Var order = orderBooks[orderId]; // Prenez l'ordre actuel attribuer à l'ordre si (order.Id > 0) { // Si l'ordre est actif, c'est-à-dire si order.Id n'est pas 0 (déjà placé) Var trouvé = faux; // La variable trouvée (marque trouvée) est false pour (var i = 0; i < orders.length; i++) { // Trouver le même numéro de commande dans l'information de commande exécutée renvoyée par l'échange si (order.Id == orders[i].Id) { // Si trouvé, attribuer une valeur de vrai à trouver, ce qui signifie qu'il a été trouvé. trouvé = vrai; Je ne sais pas. Je ne sais pas. si (!found) { // Si l'ordre courantId représente un ordre qui n'est pas trouvé dans l'ordre de l'ordre inachevé renvoyé par l'échange. order.Status = ORDER_STATE_CLOSED; // met à jour l'ordre correspondant à l'ordreId dans orderBooks (c'est à dire la variable d'ordre en cours) et les mises à jour // la propriété d'état à ORDER_STATE_CLOSED (c'est à dire fermé) hisBooks[orderId] = commande; // La commande terminée est enregistrée dans le carnet de commande historique, c'est-à-dire hisBooks, unifié, et le numéro de commande unique orderId supprimer ((orderBooks[orderId]); // Supprimer l'attribut du carnet d'ordres nommé orderId value. (L'ordre terminé est supprimé de celui-ci) orderBooksLen; // Réduction de la longueur du carnet de commandes continue; // Le code suivant saute la boucle. Je ne sais pas. Je ne sais pas. vari diff = _N(ordre.Type == ORDER_TYPE_BUY? (ticker.Buy - order.Price) : (ordre.Price - ticker.Sell)); // Diff est la différence entre le prix d'ouverture prévu de l'ordre dans le carnet d'ordres en cours et le prix d'ouverture en temps réel en cours.

        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.
        }
    }
};

}

fonction balanceAccount ((orgAccount, initAccount) { // Balance Account Function Parameter Initial account information when the strategy is started La fonction init est la suivante: CALL the custom function cancelPending ((() pour annuler toutes les commandes en attente. Var nowAccount = _C ((exchange.GetAccount); // Déclarer une variable nowAccount pour enregistrer les dernières informations sur le compte à l'heure actuelle. Var slidePrice = 0.2; // Set the slip price when placing the order as 0.2 Il est possible de modifier le prix de la commande en fonction de la valeur de la commande var ok = true; // Tag variable initialement défini comme vrai pendant (true) { // pendant boucle Var diff = _N ((nowAccount.Stocks - initAccount.Stocks); // Calculer la différence entre le compte courant et le compte initial Si la valeur absolue de la différence de devise est inférieure au volume de transaction minimum de l'échange, // le break saute hors de la boucle et n'effectue pas d'opérations d'équilibrage. Je ne sais pas. Je ne sais pas. Var depth = _C ((exchange.GetDepth); // Obtenez l'information de profondeur d'échange Assignez à la variable de profondeur déclarée 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 (equal to 0 will not be processed, it is break when it is judged to be less than GetMinStock) // vends l'ordre de vente en profondeur (équivalent à 0 ne sera pas traité, il est brisé quand il est jugé être inférieur à GetMinStock) // La différence entre les pièces est supérieure à 0 pour vendre le solde, alors regardez le tableau des ordres d'achat // la différence entre les pièces est inférieure à 0 est l'inverse. Var n = 0; // Statement n initial est 0 Var prix = 0; // Statement prix initial 0 pour (var i = 0; i < books.length; i++) { // Traversant le tableau des ordres de vente ou de vente n += books[i].Amount; // Accumuler le montant (la quantité de commande) pour chaque commande basée sur l'index traversé si (n >= Math.abs ((diff)) { // Si la quantité d'ordre cumulative n est supérieure ou égale à la différence de monnaie, alors: Le prix de l'ordre indexé actuel, assigner à prix break; // Jump out of the current for traversal cycle (Sauvez le courant pour le cycle de traversation) Je ne sais pas. Je ne sais pas. Var pfn = diff > 0? Sell: exchange.Buy; // Pass the sell order API (exchange.Sell) or the next buy order API (exchange.Buy) reference to the declared pfn (Exchange.Buy) est une référence à l'ordre de vente de l'API (exchange.Buy) // basé sur la différence de devise supérieure ou inférieure à 0 Var amount = Math.abs ((diff); // Le montant de l'ordre à équilibrer est diff, la différence dans la monnaie, assignée à la variable de montant déclaré. var price = diff > 0? (prix - slidePrice) : (prix + slidePrice); // The direction of buying and selling according to the difference in the currency, increase or decrease the // prix de glissement basé sur le prix (le prix de glissement est de le rendre plus facile à négocier), et puis l'assigner au prix Log ((start the balance, (diff > 0? sell: buy), amount, of coins); // Le nombre de coins que le log de sortie balance. si (diff > 0) { // Selon la direction de l'achat et de la vente, déterminer si la monnaie du compte ou le montant de pièces est suffisant. Pour les pièces de monnaie en cours d'achat, le montant de la commande doit être supérieur à la quantité de monnaie disponible. Je ne sais pas. Assurez-vous que le montant de l'ordre placé ne dépasse pas le montant d'argent disponible dans le compte courant. Je ne sais pas. si (amount < exchange.GetMinStock()) { // Vérifiez si la quantité de commande finale est inférieure à la quantité de commande minimale autorisée par l'échange Log (( Insufficient funds, unable to balance to the initial state); // Si la quantité de commande est trop petite, l'information est imprimée. OK = faux; // équilibre des balises a échoué break; // Jump out of the while loop - Sauter hors de la boucle pendant Je ne sais pas. pfn ((price, amount); // API d'exécution de l'ordre (référence pfn) Sleep ((1000); // Pause pour une seconde Cancel Pending ((); // Annuler toutes les commandes en attente. nowAccount = _C ((exchange.GetAccount); // Obtenez des informations sur le compte actuel Je ne sais pas. if (ok) { // Exécuter le code à l'intérieur des parenthèses en boucles quand ok est vrai (balance is successful) LogProfit ((_N ((nowAccount.Balance - orgAccount.Balance)); // Utilisez la propriété Balance du paramètre entrant orgAccount (information de compte avant équilibrage) // pour soustraire la propriété Balance de l'information du compte courant, c'est-à-dire la différence dans le montant de l'argent. // That is, profit and loss (car le nombre de pièces ne change pas, il y a une légère erreur parce que certains petits // les quantités ne peuvent pas être équilibrées) Log (l'équilibre est terminé, nowAccount); // The output log is balanced. Je ne sais pas. Je ne sais pas.

var STATE_WAIT_OPEN = 0; // Utilisé pour l' état de chaque nœud dans le fishTable le nombre de fois où le système est désactivé. le nombre de fois où le système est désactivé. Var ProfitCount = 0; // Compte des résultats Var BuyFirst = vrai; // Paramètres d'interface initiaux var IsSupportGetOrder = true; // déterminer le support d'échange de la fonction GetOrder API, une variable globale, utilisée pour déterminer le début de la fonction principale var LastBusy = 0; // Enregistrer le dernier objet de temps traité

fonction setBusy() { // Définir le temps d'occupation LastBusy = new Date(); // Assigner LastBusy à l'objet de l'heure en cours Je ne sais pas.

la fonction isTimeout() { // Détermine si elle est à temps si (MaxIdle <= 0) { // Temps d'inactivité maximal (en fonction du déplacement automatique de la grille), // si le temps d'arrêt maximal MaxIdle est inférieur ou égal à 0 retourner false; // retourne false, ne juge pas le temps d'arrêt. c'est-à-dire toujours retourner false sans temps d'arrêt. Je ne sais pas. var now = new Date ((); // Obtenir l'objet de l'heure actuelle si (((now.getTime() - LastBusy.getTime()) / 1000) >= MaxIdle) { // Utilisez la fonction getTime de l'objet temps en cours pour obtenir l'horodatage et l'horodatage de LastBusy pour calculer la différence, // Divisez par 1000 pour calculer le nombre de secondes entre les deux objets de temps. // Détermine si elle est supérieure au temps d'inactivité maximal MaxIdle LastBusy = maintenant; // Si elle est supérieure à, mettre à jour LastBusy à l'objet de temps actuel maintenant retourner true; // retourne true, qui est un temps mort. Je ne sais pas. retourner false; // retourner false sans délai d'attente Je ne sais pas.

fonction onexit() { // La fonction de fermeture lorsque le programme sort. si (CancelAllWS) { // Pour annuler toutes les commandes en attente lors de l'arrêt, appelez cancelPending() pour annuler toutes les commandes en attente. Log ((Sortir, essayer d'annuler toutes les commandes en attente); annulerEn attente ((); Je ne sais pas. Log ((Stratégie arrêtée avec succès); Log ((_C(exchange.GetAccount)); // Imprimez les informations de position du compte lorsque vous quittez le programme. Je ne sais pas.

fonction pêche ((orgCompte, poissonCompte) { // Paramètres de la mise en mer: informations sur le compte, nombre de prises en mer setBusy(); // Réglez LastBuys à l'horodatage actuel var compte = _C(exchange.GetAccount); // Déclarer une variable de compte pour obtenir les informations du compte courant et l'assigner. Log ((account); // Sortie des informations du compte au début de l'appel à la fonction de pêche. Var InitAccount = compte; // Déclarer une variable InitAccount et l'assigner avec compte. // cette coulée, utilisée pour calculer les bénéfices et pertes flottants.
var ticker = _C(exchange.GetTicker); // Obtenez la valeur de cotation attribuée à la variable ticker déclarée var amount = _N(AmountOnce); // Selon le nombre de paramètres d'interface, utilisez _N pour traiter les décimales (_N par défaut à 2 bits) et les attribuer à amount. var amountB = [amount]; // Déclarer une variable appelée amountB est un tableau, initialiser un élément avec amount Var amountS = [amount]; // Déclarer une variable appelée amountS... si (typeof(AmountType)!== undefined && AmountType == 1) { // Selon le montant personnalisé, le type de taille de commande, si ce paramètre d'interface n'est pas indéfini, // Et AmountType est réglé sur une quantité personnalisée sur l'interface, c'est-à-dire que la valeur AmountType est 1 (l'index de la boîte déroulante) pour (var idx = 0; idx < AllNum; idx++) { // Le nombre total de AllNum. Si vous définissez une quantité personnalisée, cycle amountB/amountS dans le tableau de quantité d'ordre en fonction du nombre total de cycles. quantitéB[idx] = BAmountOnce; // Assigner une valeur au tableau des ordres d'achat à l'aide des paramètres d'interface quantitéS[idx] = SAmountOnce; //... à l'ordre de vente... Je ne sais pas. { \ pos (192,220) } autre { \ pos (192,220) } autre pour (var idx = 1; idx < AllNum; idx++) { // Cycles basés sur le nombre total de grilles. switch (AmountCoefficient[0]) { // Selon la différence de paramètre d'interface, le premier caractère de la chaîne, AmountCoefficient[0] est +, -, , / cas +: // Selon les paramètres de l'interface, une grille avec une seule addition et un incrément est construite. quantitéB[idx] = quantitéB[idx - 1] + parseFloat ((AmountCoefficient.substring))); une rupture; cas -: //... quantitéB[idx] = quantitéB[idx - 1] - parseFloat ((AmountCoefficient.substring(1)); une rupture; cas : La valeur de l'échantillon est calculée à partir de la valeur de l'échantillon. une rupture; cas /: quantitéB[idx] = quantitéB[idx - 1] / parseFloat(AmountCoefficient.substring(1)); une rupture; Je ne sais pas. quantitéB[idx] = _N(quantitéB[idx], AmountDot); // ordre d'achat, montant d'achat, et traiter les données à la décimale. Le montantS[idx] = le montantB[idx]; // Affectation Je ne sais pas. Je ne sais pas. si (FirstPriceAuto) { // Si le premier paramètre est automatiquement réglé sur true si le paramètre d'interface est réglé, le code à l'intérieur des crochets if est exécuté. Le premier prix = acheter le premier? _N(ticker.Buy - PriceGrid, précision) : _N(ticker.Sell + PriceGrid, précision); // Le paramètre d'interface FirstPrice définit le premier prix selon la variable globale BuyFirst (l'énoncé initial est vrai, // et a été attribué en fonction de l'opType au début du principal). // Le prix est défini par le ticker de prix et le paramètre de prix PriceGrid intervalle de prix.
Je ne sais pas. // Initialisez la table des poissons
Var fishTable = {}; // Déclarer un objet de grille Var uuidTable = {}; // Objet de la table de code d'identification Var needStocks = 0; // Variable des pièces requises Var needMoney = 0; // Variable de l'argent requis Var actuelNeedMoney = 0; // En fait besoin d'argent var actualNeedStocks = 0; // Les pièces réellement nécessaires var notEnough = false; // Variante de balise sous-financée, initialement définie sur false Var canNum = 0; // Grille disponible pour (var idx = 0; idx < AllNum; idx++) { // La structure est traversée selon le nombre de grille AllNum. Var prix = _N((BuyFirst? FirstPrice - (idx * PriceGrid) : FirstPrice + (idx * PriceGrid)), Précision); // Lors de la traversée de la construction, le prix idx de l'indice actuel est défini selon BuyFirst. needStocks += amountS[idx]; // Le nombre de pièces vendues s'accumule progressivement avec le cycle. (accumulé par le tableau de quantité des ordres de vente à needStocks un par un) needMoney += prix * quantitéB[idx]; // La quantité d'argent nécessaire à l'achat est progressivement accumulée avec le cycle. si (BuyFirst) { // Traitement de l' achat en premier si (_N(needMoney) <= _N ((account.Balance)) { // Si la grille nécessite moins d'argent que le montant disponible sur le compte actualNeedMondy = needMoney; // Assigné au montant réel de l'argent requis actualisNeedStocks = needStocks; // Assignation au nombre réel de pièces requises. canNum++; // Nombre cumulé de grilles disponibles } else { // _N(needMoney) <= _N(account.Balance) Si cette condition n'est pas remplie, régler la variable de la balise sous-financée sur vrai notEnough = vrai; Je ne sais pas. { \ pos (192,230) } autre { \ pos (192,230) } Traitement de la vente en premier si (_N(needStocks) <= _N(account.Stocks)) { // Vérifiez si le nombre de pièces requis est inférieur au nombre de pièces disponibles sur le compte ActuelNeedMondy = besoin d'argent; // affectation Les stocks actuels de besoins = stocks de besoins; canNum++; // Nombre cumulé de grilles disponibles { \ pos (192,230) } autre notEnough = true; // S'il n'est pas satisfait aux conditions de financement Je ne sais pas. Je ne sais pas. fishTable[idx] = STATE_WAIT_OPEN; // Selon l'index idx actuel, définir l'état du membre idx (nœud de la grille) de l'objet de la grille, // initialement STATE_WAIT_OPEN (attendant d'ouvrir la position) uuidTable[idx] = -1; // L'objet numéroté initie également sa propre valeur idx (le nœud correspondant au fishTable) à -1 en fonction de l'idx actuel. Je ne sais pas. si (!EnableAccountCheck && (canNum < AllNum)) { // Si la vérification des fonds n'est pas activée, et le nombre de grilles (le nombre total de nœuds) où le nœud est plus petit // que le paramètre d'interface peut être ouvert. Log ((Avertissement, les fonds courants ne peuvent être effectués que, canNum, of Grids, total des besoins de la grille, (BuyFirst? needMoney : needStocks), Please keep sufficient funds); // Log produit un message d'avertissement. canNum = AllNum; // Mettre à jour le nombre de paramètres d'interface Je ne sais pas. si (acheter en premier) { // acheter en premier si (EnableProtectDiff && (FirstPrice - ticker.Sell) > ProtectDiff) { // Ouvrez une protection contre le spread et entrez le prix de marché moins le prix d' enchère actuel plus de // la protection des prix d'entrée sur le marché
lancer Le premier prix d'achat est supérieur au prix de vente du marché + _N(FirstPrice - ticker.Sell, Precision) + dollar; // Lancer un message d'erreur. } autre si (EnableAccountCheck && account.Balance < _N(needMoney)) { // Si la vérification des fonds est activée et que le montant disponible pour le compte est inférieur à // le montant d'argent requis pour le réseau. si (fishCount == 1) { // Si c'est la première fois que vous lancez la grille lancer Insuffisants fonds, besoin + _N(needMoney) + dollar; // Lancer une erreur, insuffisants fonds { \ pos (192,220) } autre Log ((Insufficient funds, need, _N(needMoney), dollar, le programme ne fait que, canNum, of grids #ff0000); // Si ce n'est pas la première fois que vous lancez une grille, sortez un message. Je ne sais pas. Dans d'autres cas, il n'y a pas de contrôle des capitaux, de protection des prix, etc. Log ((Utilisation estimée des fonds: , _N ((needMoney), dollar); // La production devrait utiliser des fonds. Je ne sais pas. } else { // vendre d'abord, Ce qui suit est similaire à acheter d'abord si (EnableProtectDiff && (ticker.Buy - FirstPrice) > ProtectDiff) { lancer Le premier prix de vente est supérieur au prix d'achat du marché + _N(ticker.Buy - FirstPrice, Precision) + dollar; } autre si (ActiverCompteVérifier && compte.Stocks < _N(needStocks)) { si (nombre de poissons == 1) { lancer des fonds insuffisants, besoin + _N(needStocks) + de pièces ; { \ pos (192,220) } autre Log ((Insuffisance de fonds, besoin, _N(needStocks), de pièces, programme seulement faire, canNum, de grilles #ff0000); Je ne sais pas. { \ pos (192,220) } autre Log ((Utilisation estimée des fonds: , _N(needStocks), coins, approximativement, _N(needMoney), dollar); Je ne sais pas. Je ne sais pas.

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

En savoir plus