Mengajar anda untuk menaik taraf pengumpul pasaran backtest sumber data tersuai

Penulis:Kebaikan, Dicipta: 2020-06-06 08:53:02, Dikemas kini: 2023-11-01 20:28:58

img

Artikel sebelumnyaMengajar anda untuk melaksanakan pengumpul sebut harga pasaranKami telah melaksanakan program robot yang mengumpul sebut harga pasaran bersama-sama.

Bagaimana untuk menggunakan data pasaran selepas kita mengumpulnya? ia akan menggunakan untuk sistem backtest. Bergantung pada fungsi sumber data tersuai FMZ platform sistem backtest, kita boleh menggunakan data yang dikumpulkan secara langsung sebagai sumber data sistem backtest, supaya kita boleh membiarkan sistem backtest menggunakan di mana-mana pasaran di mana kita ingin backtest data sejarah.

Oleh itu, kita boleh memberikan Market Quote Collector peningkatan! biarkan pengumpul pasaran juga boleh berfungsi sebagai sumber data tersuai untuk menyediakan data kepada sistem backtest.

Bersedialah

Ia berbeza dengan kerja persediaan dalam artikel sebelumnya. Kali terakhir adalah program docker yang berjalan di komputer MAC tempatan saya, memasang pangkalan data mongodb untuk memulakan perkhidmatan pangkalan data. Kali ini kami menukar persekitaran operasi ke VPS dan menggunakan pelayan Alibaba Cloud Linux untuk menjalankan set program kami.

  • Pangkalan Data Mongodb

Seperti dalam artikel sebelumnya, kita perlu memasang pangkalan data mongodb pada peranti di mana program pengumpul pasaran sedang berjalan dan memulakan perkhidmatan. Ia pada dasarnya sama dengan memasang mongodb pada komputer MAC. Terdapat banyak tutorial di Internet, anda boleh google, ia sangat mudah.

  • Masang Python 3

Program ini menggunakan python3, perhatikan penggunaan beberapa perpustakaan python, jika mereka tidak dipasang, anda perlu memasangnya terlebih dahulu.

Pymongo http urllib

  • Docker

FMZ berlari akan cukup.

Mengubah Market Quote Collector

Pengumpul sebut harga pasaran adalah ini:https://www.fmz.com/strategy/199120(RecordsCollector) strategi.

Mari kita buat beberapa pengubahsuaian kepadanya:

Sebelum program memasuki gelung sementara untuk mengumpul data, perpustakaan berbilang benang digunakan, dan pelaksanaan serentak memulakan perkhidmatan untuk memantau permintaan data sistem backtest platform FMZ.

RecordsCollector (tingkatkan untuk menyediakan fungsi sumber data tersuai)

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

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):
        try:
            self.send_response(200)
            self.send_header("Content-type", "application/json")
            self.end_headers()

            dictParam = url2Dict(self.path)
            Log("The custom data source service receives the request, self.path:", self.path, "query parameter:", dictParam)
            
            # At present, the backtesting system can only select the exchange name from the list. When adding a custom data source, set it to Binance, that is: Binance
            exName = exchange.GetName()                                     
            # Note that period is the bottom K-line period
            tabName = "%s_%s" % ("records", int(int(dictParam["period"]) / 1000))  
            priceRatio = math.pow(10, int(dictParam["round"]))
            amountRatio = math.pow(10, int(dictParam["vround"]))
            fromTS = int(dictParam["from"]) * int(1000)
            toTS = int(dictParam["to"]) * int(1000)
            
            
            # Connect to the database
            Log("Connect to the database service to obtain data, the database:", exName, "table:", tabName)
            myDBClient = pymongo.MongoClient("mongodb://localhost:27017")
            ex_DB = myDBClient[exName]
            exRecords = ex_DB[tabName]
            
            
            # Request data
            data = {
                "schema" : ["time", "open", "high", "low", "close", "vol"],
                "data" : []
            }
            
            # Construct query condition: greater than a certain value{'age': {'$gt': 20}} Less than a certain value{'age': {'$lt': 20}}
            dbQuery = {"$and":[{'Time': {'$gt': fromTS}}, {'Time': {'$lt': toTS}}]}
            Log("Query conditions:", dbQuery, "Number of inquiries:", exRecords.find(dbQuery).count(), "Total number of databases:", exRecords.find().count())
            
            for x in exRecords.find(dbQuery).sort("Time"):
                # Need to process data accuracy according to request parameters round and vround
                bar = [x["Time"], int(x["Open"] * priceRatio), int(x["High"] * priceRatio), int(x["Low"] * priceRatio), int(x["Close"] * priceRatio), int(x["Volume"] * amountRatio)]
                data["data"].append(bar)
            
            Log("data:", data, "Respond to backtest system requests.")
            # Write data reply
            self.wfile.write(json.dumps(data).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():
    LogReset(1)
    exName = exchange.GetName()
    period = exchange.GetPeriod()
    Log("collect", exName, "Exchange K-line data,", "K line cycle:", period, "second")
    
    # Connect to the database service, service address mongodb://127.0.0.1:27017 See the settings of mongodb installed on the server
    Log("Connect to the mongodb service of the hosting device, mongodb://localhost:27017")
    myDBClient = pymongo.MongoClient("mongodb://localhost:27017")   
    # Create a database
    ex_DB = myDBClient[exName]
    
    # Print the current database table
    collist = ex_DB.list_collection_names()
    Log("mongodb ", exName, " collist:", collist)
    
    # Check if the table is deleted
    arrDropNames = json.loads(dropNames)
    if isinstance(arrDropNames, list):
        for i in range(len(arrDropNames)):
            dropName = arrDropNames[i]
            if isinstance(dropName, str):
                if not dropName in collist:
                    continue
                tab = ex_DB[dropName]
                Log("dropName:", dropName, "delete:", dropName)
                ret = tab.drop()
                collist = ex_DB.list_collection_names()
                if dropName in collist:
                    Log(dropName, "failed to delete")
                else :
                    Log(dropName, "successfully deleted")
    
    # Start a thread to provide a custom data source service
    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("Open the custom data source service thread", "#FF0000")
    except BaseException as e:
        Log("Failed to start the custom data source service!")
        Log("Error message:", e)
        raise Exception("stop")
    
    # Create the records table
    ex_DB_Records = ex_DB["%s_%d" % ("records", period)]
    Log("Start collecting", exName, "K-line data", "cycle:", period, "Open (create) the database table:", "%s_%d" % ("records", period), "#FF0000")
    preBarTime = 0
    index = 1
    while True:
        r = _C(exchange.GetRecords)
        if len(r) < 2:
            Sleep(1000)
            continue
        if preBarTime == 0:
            # Write all BAR data for the first time
            for i in range(len(r) - 1):
                bar = r[i]
                # Write line by line, you need to determine whether the data already exists in the current database table, based on timestamp detection, if there is the data, then skip, if not write in
                retQuery = ex_DB_Records.find({"Time": bar["Time"]})
                if retQuery.count() > 0:
                    continue
                
                # Write bar to the database table
                ex_DB_Records.insert_one({"High": bar["High"], "Low": bar["Low"], "Open": bar["Open"], "Close": bar["Close"], "Time": bar["Time"], "Volume": bar["Volume"]})                
                index += 1
            preBarTime = r[-1]["Time"]
        elif preBarTime != r[-1]["Time"]:
            bar = r[-2]
            # Check before writing data, whether the data already exists, based on time stamp detection
            retQuery = ex_DB_Records.find({"Time": bar["Time"]})
            if retQuery.count() > 0:
                continue
            
            ex_DB_Records.insert_one({"High": bar["High"], "Low": bar["Low"], "Open": bar["Open"], "Close": bar["Close"], "Time": bar["Time"], "Volume": bar["Volume"]})
            index += 1
            preBarTime = r[-1]["Time"]
        LogStatus(_D(), "preBarTime:", preBarTime, "_D(preBarTime):", _D(preBarTime/1000), "index:", index)
        # adding drawing display
        ext.PlotRecords(r, "%s_%d" % ("records", period))
        Sleep(10000)

Ujian

Sesuaikan robot

img

Jalankan robot, jalankan pengumpul harga pasaran.

img

Buka strategi ujian untuk backtest. Contohnya:

function main() {
    Log(exchange.GetRecords())
    Log(exchange.GetRecords())
    Log(exchange.GetRecords())
    Log(exchange.GetRecords())
    Log(exchange.GetRecords())
    Log(exchange.GetRecords())
    Log(exchange.GetRecords().length)
}

Mengkonfigurasi pilihan backtest, menetapkan pertukaran ke Binance kerana sumber data khusus sementara belum dapat merumuskan nama pertukaran dengan sendirinya, anda hanya boleh meminjam salah satu konfigurasi pertukaran dalam senarai, backtest menunjukkan bahawa Binance, yang sebenar Ia adalah data pasaran simulasi WexApp.

img

Bandingkan sama ada carta yang dihasilkan oleh sistem backtest berdasarkan pengumpul sebut harga pasaran sebagai sumber data tersuai adalah sama dengan carta K-line 1 jam di halaman pertukaran wexApp.

img img

Dengan cara ini, robot di VPS boleh mengumpul data K-line sendiri, dan kita boleh mendapatkan data yang dikumpulkan pada bila-bila masa dan backtest terus dalam sistem backtest.

Anda boleh terus memperluaskan, sebagai contoh, cuba sumber data khusus backtest tahap sebenar, dan pelbagai, pengumpulan data pelbagai pasaran dan fungsi lain.


Berkaitan

Lebih lanjut