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

Solution de partage des cotations de marché multi-robot

Auteur:La bonté, Créé: 2020-07-25 09:24:50, Mis à jour: 2024-12-10 10:14:09

img

Lorsque vous utilisez des robots de trading quantitatif de devises numériques, lorsqu'il y a plusieurs robots en cours d'exécution sur un serveur, si vous visitez différents échanges, le problème n'est pas grave à ce moment-là, et il n'y aura pas de problème de fréquence de demande d'API. Si vous avez besoin d'avoir plusieurs robots en cours d'exécution en même temps, et ils sont tous visitez le même échange avec la même stratégie de trading de paire quantitative. À ce moment-là, il y aura des problèmes de limitation de fréquence de demande d'API. Alors, comment résoudre le problème de l'interface d'accès multi-robot avec le moins de serveurs?

Nous pouvons implémenter un robot d'expédition de cotation de marché, et accéder à l'interface d'échange pour obtenir des cotations de marché et d'autres données ne peuvent être complétées que par ce robot.

Exemple de robot de transmission de citations

Il est uniquement responsable de l'accès à l'interface de cotation du marché de change pour obtenir des données et fournir des cotations de marché à d'autres robots.

import _thread
import threading
import json
import math
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import parse_qs, urlparse

Records = None
lock = threading.RLock()
Counter = {}

def url2Dict(url):
    query = urlparse(url).query  
    params = parse_qs(query)  
    result = {key: params[key][0] for key in params}  
    return result

class Provider(BaseHTTPRequestHandler):
    def do_GET(self):
        global Records, lock, Counter
        try:
            self.send_response(200)
            self.send_header("Content-type", "application/json")
            self.end_headers()

            dictParam = url2Dict(self.path)
            # Log("The service receives the request, self.path:", self.path, "query parameter:", dictParam)
            lock.acquire()
            # Recording
            if dictParam["robotId"] not in Counter:
                Counter[dictParam["robotId"]] = {"NumberOfRequests" : 0}
            Counter[dictParam["robotId"]]["NumberOfRequests"] += 1
            lock.release()
            
            # Write data response
            self.wfile.write(json.dumps(Records).encode())
        except BaseException as e:
            Log("Provider do_GET error, e:", e)


def createServer(host):
    try:
        server = HTTPServer(host, Provider)
        Log("Starting server, listen at: %s:%s" % host)
        server.serve_forever()
    except BaseException as e:
        Log("createServer error, e:", e)
        raise Exception("stop")

def main():
    global Records, Counter
    LogReset(1)
    try:
        # _thread.start_new_thread(createServer, (("localhost", 9090), ))         # local computer test
        _thread.start_new_thread(createServer, (("0.0.0.0", 9090), ))             # Test on VPS server
        Log("Start service", "#FF0000")
    except BaseException as e:
        Log("Failed to start service!")
        Log("Error message:", e)
        raise Exception("stop")
    while True:
        r = exchange.GetRecords()
        if not r :
            Log("K-line market quotation failed", "#FF0000")
            continue
        else :
            Records = r
        # Counter
        tbl = {
            "type" : "table", 
            "title" : "Statistics", 
            "cols" : ["ID of the robot requesting data", "Number of requests"], 
            "rows" : [], 
        }
        for k in Counter:
            tbl["rows"].append([k, Counter[k]["NumberOfRequests"]])
        LogStatus(_D(), "Data collection!", "\n", "`" + json.dumps(tbl) + "`")
        Sleep(500)

Code de stratégie du robot de demande de données

Le robot qui demande des données est un robot de stratégie de trading, mais nous l'utilisons pour tester. Nous écrivons uniquement les données demandées (données de ligne K) et dessinons les données. Vous pouvez l'écrire en JavaScript. Pour dessiner une image, vous devez vérifier la bibliothèque de dessin de ligne. Cherchez et copiez cette bibliothèque de classe dans Strategy Square. Après avoir copié, vous pouvez la sélectionner dans la colonne de référence du modèle sur la page d'édition de stratégie.

var FuncGetRecords = exchange.GetRecords
exchange.GetRecords = function() {
    // You can fill in the IP address of the device where the "quote forwarding robot" is located xxx.xxx.xxx.xxx
    var ret = HttpQuery("http://xxx.xxx.xxx.xxx:9090?robotId=" + _G())  
    var records = null
    try {
        records = JSON.parse(ret)
    } catch(e) {
        Log(e)
        records = null
    }
    return records 
}

function main(){
    LogReset(1)
    while(1) {
        var records = exchange.GetRecords()
        LogStatus(_D(), "Robot ID:", _G())
        if (!records) {
            Log("Failed to get data!", "#FF0000")
            Sleep(1000)
            continue
        }
        Log(records)
        $.PlotRecords(records, "K")
        Sleep(1000)
    }
}

Opération réelle

Démarrez le robot de distribution

img

Démarrer le robot d'essai, ID: 206353

img

Démarrez le robot d'essai, ID: 206359

img

De cette façon, trois ou même N robots peuvent partager les données de la ligne K d'une certaine paire de négociation.


Relationnée

Plus de