Utilisez un plug-in de terminal pour faciliter les transactions manuelles

Auteur:Le foin, Créé: 2020-02-29 21:04:52, Mis à jour: 2023-10-12 21:21:40

[TOC] Je vous en prie.img

Nom de famille

FMZ est une plate-forme de négociation quantitative, principalement destinée à servir les traders programmés. Mais il fournit également un terminal de négociation de base, qui, bien que fonctionnellement simple, peut parfois être très utile, par exemple, si l'échange est occupé et ne peut pas être ouvert, mais l'API peut fonctionner, à ce moment-là, vous pouvez retirer, passer une commande, consulter le compte de transaction, etc. Pour améliorer l'expérience du terminal de négociation, des fonctionnalités de plug-in sont maintenant ajoutées.

img

Le principe du plugin

Le plugin fonctionne en deux modes: instantané et en arrière-plan. L'instantanéité équivaut à la création d'un robot (frais normaux). Le principe de l'instantanéité est le même que celui du débogage: l'hôte qui envoie un morceau de code à la page du terminal de transaction l'exécute et prend en charge les graphiques et les tableaux de retour (l'outil de débogage est également actuellement mis à niveau). Le même ne peut être exécuté que pendant 5 minutes, sans frais ni limitation de langue.

Lors de l'écriture des stratégies, il est nécessaire de choisir le type de stratégie comme plugin.Le résultat de la fonction principale du plug-in apparaît à la fin de l'exécution dans le terminal et prend en charge les chaînes, les diagrammes et les tableaux. Comme les exécutions du plug-in ne sont pas visibles dans les journaux, le résultat de l'exécution du plug-in peut être retourné.

Utilisation

  • 1.添加策略

Si vous cherchez directement dans la zone de recherche, vous trouverez ici une liste de tous les sites Web qui ont été créés par Google.Remarque: les stratégies de type de plug-in de transaction ne peuvent être exécutées queLes plugins sont disponibles en ligne sur le site officiel de l'entreprise, puis cliquez sur Ajouter.https://www.fmz.com/square/21/1

img img

  • 2.运行插件

Cliquez sur la stratégie pour accéder à l'interface de configuration des paramètres. Si aucun paramètre n'est utilisé, la stratégie s'exécute directement, le gestionnaire, la paire de transactions et le cycle de ligne K sélectionnés par le terminal sont les paramètres correspondants par défaut. Cliquez sur la stratégie d'exécution pour commencer à exécuter, en sélectionnant le mode d'exécution instantanée de l'appareil (se souvenir du mode d'exécution par défaut).

img

  • 3.停止插件

Cliquer sur la position indiquée pour arrêter le plugin, car tous les plugins sont exécutés dans un processus d'outil de débogage.

img

Exemples d'utilisation des plugins

Les plugins permettent d'exécuter du code pendant un certain temps, d'exécuter des opérations simples, et souvent des opérations manuelles qui nécessitent une répétition peuvent être réalisées avec un plug-in, ce qui facilite les transactions.

Coopération de couverture à long terme

La couverture à long terme est une stratégie très courante, car la fréquence n'est pas très élevée et beaucoup de gens l'opèrent manuellement, nécessitant un contrat de plus, un contrat de moins et une analyse de l'évolution des écarts.

La première étape consiste à créer un plugin de différence de prix:

var chart = { 
   __isStock: true,    
   title : { text : '差价分析图'},                     
   xAxis: { type: 'datetime'},                 
   yAxis : {                                        
       title: {text: '差价'},                   
       opposite: false,                             
   },
   series : [                    
       {name : "diff", data : []}, 

   ]
}
function main() {
   exchange.SetContractType('quarter')
   var recordsA = exchange.GetRecords(PERIOD_M5) //周期可以自行定制
   exchange.SetContractType('this_week')
   var recordsB = exchange.GetRecords(PERIOD_M5)
   
   for(var i=0;i<Math.min(recordsA.length,recordsB.length);i++){
       var diff = recordsA[recordsA.length-Math.min(recordsA.length,recordsB.length)+i].Close - recordsB[recordsB.length-Math.min(recordsA.length,recordsB.length)+i].Close
       chart.series[0].data.push([recordsA[recordsA.length-Math.min(recordsA.length,recordsB.length)+i].Time, diff])
   }
   return chart
}

Cliquez ici pour voir les derniers écarts de prix et l'adresse de copie du code source du plugin:https://www.fmz.com/strategy/187755 img

Avec l'analyse des écarts, vous découvrez que les écarts sont en train de converger, c'est une opportunité de faire des contrats de trimestre vide, de faire plusieurs jours par semaine, c'est une opportunité qui peut être utilisée avec un plug-in de couverture d'un bouton, cliquez dessus, et vous aidera automatiquement à passer plusieurs jours par trimestre vide, beaucoup plus rapidement que l'opération manuelle. Le principe de mise en œuvre de la stratégie est de glisser le prix pour ouvrir le même nombre de positions, de pouvoir exécuter plusieurs fois, d'atteindre lentement les positions dont vous avez besoin, d'éviter d'avoir un impact sur le marché, de changer les paramètres par défaut, pour atteindre une vitesse plus rapide.https://www.fmz.com/strategy/191348

function main(){
    exchange.SetContractType(Reverse ? Contract_B : Contract_A)
    var ticker_A = exchange.GetTicker()
    if(!ticker_A){return 'Unable to get quotes'}
    exchange.SetDirection('buy')
    var id_A = exchange.Buy(ticker_A.Sell+Slip, Amount)
    exchange.SetContractType(Reverse ? Contract_B : Contract_A)
    var ticker_B = exchange.GetTicker()
    if(!ticker_B){return 'Unable to get quotes'}
    exchange.SetDirection('sell')
    var id_B = exchange.Sell(ticker_B.Buy-Slip, Amount)
    if(id_A){
        exchange.SetContractType(Reverse ? Contract_B : Contract_A)
        exchange.CancelOrder(id_A)
    }
    if(id_B){
        exchange.SetContractType(Reverse ? Contract_B : Contract_A)
        exchange.CancelOrder(id_B)
    }
    return 'Position: ' + JSON.stringify(exchange.GetPosition())
}

En attendant que les différences se rapprochent, vous devez faire le pari, vous pouvez exécuter un plug-in de pari en un clic, le pari le plus rapide.


function main(){
    while(ture){
        var pos = exchange.GetPosition()
        var ticker = exchange.GetTicekr()
        if(!ticker){return '无法获取ticker'}
        if(!pos || pos.length == 0 ){return '已无持仓'}
        for(var i=0;i<pos.length;i++){
            if(pos[i].Type == PD_LONG){
                exchange.SetContractType(pos[i].ContractType)
                exchange.SetDirection('closebuy')
                exchange.Sell(ticker.Buy, pos[i].Amount - pos[i].FrozenAmount)
            }
            if(pos[i].Type == PD_SHORT){
                exchange.SetContractType(pos[i].ContractType)
                exchange.SetDirection('closesell')
                exchange.Buy(ticker.Sell, pos[i].Amount - pos[i].FrozenAmount)
            }
        }
        var orders = exchange.Getorders()
        Sleep(500)
        for(var j=0;j<orders.length;j++){
            if(orders[i].Status == ORDER_STATE_PENDING){
                exchange.CancelOrder(orders[i].Id)
            }
        }
    }
}

Traitement auxiliaire

Le plus commun est l'envoi d'une montagne de glace, qui décompose le gros bloc en petits blocs, bien qu'il puisse être exécuté par un robot, mais un plugin de 5 minutes est en fait suffisant. Il existe deux types d'envoi d'une montagne de glace, l'un est un bloc de nourriture, l'autre est un bloc de colis, si vous avez des avantages sur les frais d'entretien, vous pouvez choisir un bloc de colis, c'est-à-dire plus de temps d'exécution.

Le code ci-dessous est le code d'achat du plugin Iceberg:https://www.fmz.com/strategy/191771Le code source est vendu:https://www.fmz.com/strategy/191772

function main(){
    var initAccount = _C(exchange.GetAccount)
    while(true){
        var account = _C(exchange.GetAccount)
        var dealAmount = account.Stocks - initAccount.Stocks
        var ticker = _C(exchange.GetTicker)
        if(BUYAMOUNT - dealAmount >= BUYSIZE){
            var id = exchange.Buy(ticker.Sell, BUYSIZE)
            Sleep(INTERVAL*1000)
            if(id){
                exchange.CancelOrder(id) // May cause error log when the order is completed, which is all right.
            }else{
                throw 'buy error'
            }
        }else{
            account = _C(exchange.GetAccount)
            var avgCost = (initAccount.Balance - account.Balance)/(account.Stocks - initAccount.Stocks)
            return 'Iceberg order to buy is done, avg cost is '+avgCost
        }
        
    }
}

L'occupation d'un achat ou d'une vente est également une façon de procéder lentement, avec un impact relativement faible sur le marché. Cette stratégie a également été améliorée en modifiant manuellement la quantité minimale de transactions ou la précision. Pour acheter:https://www.fmz.com/strategy/191582Il est vendu:https://www.fmz.com/strategy/191730

function GetPrecision(){
    var precision = {price:0, amount:0}
    var depth = exchange.GetDepth()
    for(var i=0;i<exchange.GetDepth().Asks.length;i++){
        var amountPrecision = exchange.GetDepth().Asks[i].Amount.toString().indexOf('.') > -1 ? exchange.GetDepth().Asks[i].Amount.toString().split('.')[1].length : 0
        precision.amount = Math.max(precision.amount,amountPrecision)
        var pricePrecision = exchange.GetDepth().Asks[i].Price.toString().indexOf('.') > -1 ? exchange.GetDepth().Asks[i].Price.toString().split('.')[1].length : 0
        precision.price = Math.max(precision.price,pricePrecision)
    }
    return precision
}

function main(){
    var initAccount = exchange.GetAccount()
    if(!initAccount){return '无法获取账户信息'}
    var precision = GetPrecision()
    var buyPrice = 0
    var lastId = 0
    var done = false
    while(true){
        var account = _C(exchange.GetAccount)
        var dealAmount = account.Stocks - initAccount.Stocks
        var ticker = _C(exchange.GetTicker)
        if(BuyAmount - dealAmount > 1/Math.pow(10,precision.amount) && ticker.Buy > buyPrice){
            if(lastId){exchange.CancelOrder(lastId)}
            var id = exchange.Buy(ticker.Buy, _N(BuyAmount - dealAmount,precision.amount))
            if(id){
                lastId = id
            }else{
                done = true
            }
        }
        if(BuyAmount - dealAmount <= 1/Math.pow(10,precision.amount)){done = true}
        if(done){
            var avgCost = (initAccount.Balance - account.Balance)/dealAmount
            return 'order is done, avg cost is ' + avgCost  // including fee cost
        }
        Sleep(Intervel*1000)
    }
}

Parfois, il est possible de suspendre plusieurs commandes à intervalles réguliers afin de vendre un meilleur prix d'expédition ou d'attendre que les offres soient suspendues. Ce plugin peut également être utilisé pour les offres futures.https://www.fmz.com/strategy/190017


function main() {
    var ticker = exchange.GetTicker()
    if(!ticker){
        return  'Unable to get price'
    }
    for(var i=0;i<N;i++){
        if(Type == 0){
            if(exchange.GetName().startsWith('Futures')){
                exchange.SetDirection('buy')
            }
            exchange.Buy(Start_Price-i*Spread,Amount+i*Amount_Step)
        }else if(Type == 1){
            if(exchange.GetName().startsWith('Futures')){
                exchange.SetDirection('sell')
            }
            exchange.Sell(Start_Price+i*Spread,Amount+i*Amount_Step)
        }else if(Type == 2){
            exchange.SetDirection('closesell')
            exchange.Buy(Start_Price-i*Spread,Amount+i*Amount_Step)
        }
        else if(Type == 3){
            exchange.SetDirection('closebuy')
            exchange.Sell(Start_Price+i*Spread,Amount+i*Amount_Step)
        }
        Sleep(500)
    }
    return 'order complete'
}

Commodity futures auxiliaires

Les logiciels de négociation à terme couramment utilisés ont souvent de nombreuses fonctionnalités avancées de l'ordre de suspension, telles que l'ordre de suspension, l'ordre de suspension, etc., qui peuvent être facilement écrits en plug-in.https://www.fmz.com/strategy/187736

var buy = false
var trade_amount = 0
function main(){
    while(true){
        if(exchange.IO("status")){
            exchange.SetContractType(Contract)
            if(!buy){
                buy = true
                if(Direction == 0){
                    exchange.SetDirection('buy')
                    exchange.Buy(Open_Price, Amount)
                }else{
                    exchange.SetDirection('sell')
                    exchange.Sell(Open_Price, Amount)
                }
            }
            var pos = exchange.GetPosition()
            if(pos && pos.length > 0){
                for(var i=0;i<pos.length;i++){
                    if(pos[i].ContractType == Contract && pos[i].Type == Direction && pos[i].Amount-pos[i].FrozenAmount>0){
                        var cover_amount = math.min(Amount-trade_amount, pos[i].Amount-pos[i].FrozenAmount)
                        if(cover_amount >= 1){
                            trade_amount += cover_amount
                            if(Direction == 0){
                                exchange.SetDirection('closebuy_today')
                                exchange.Sell(Close_Price, cover_amount)
                            }else{
                                exchange.SetDirection('closesell_today')
                                exchange.Buy(Close_Price, cover_amount)
                            }
                        }
                    }
                }
            }
        } else {
            LogStatus(_D(), "未连接CTP !")
            Sleep(10000)
        }
        if(trade_amount >= Amount){
            Log('任务完成')
            return
        }
        Sleep(1000)
    }
}

Résumé

Après avoir vu toutes ces petites fonctionnalités, vous devriez avoir votre propre idée, peut-être écrire un plugin pour faciliter vos transactions manuelles.


Relationnée

Plus de

- Je vous en prie.Quelles sont les causes de l'erreur? Error: Futures_OP 0: 400: {"error_message":"Open orders exist","code":35017,"error_code":"35017","message:"Open orders exist"} Buy ((5000, 0.1): 400: {"error_message":"order_size error","result":"true","error_code":"35063","order_id":"-1"}

Le foinVérifiez les documents de l'échange ou consultez le service client de l'échange.