Mengajarkan Anda untuk meningkatkan market collector backtest sumber data kustom

Penulis:Kebaikan, Dibuat: 2020-06-06 08:53:02, Diperbarui: 2023-11-01 20:28:58

img

Artikel sebelumnyaMengajarkan Anda untuk menerapkan pasar kutipan kolektorKami telah menerapkan program robot yang mengumpulkan penawaran pasar bersama-sama.

Bagaimana menggunakan data pasar setelah kita mengumpulkannya? itu akan digunakan untuk sistem backtest. Bergantung pada fungsi sumber data kustom dari sistem backtest platform FMZ, kita dapat secara langsung menggunakan data yang dikumpulkan sebagai sumber data dari sistem backtest, sehingga kita dapat membiarkan sistem backtest digunakan di pasar mana pun di mana kita ingin backtest data historis.

Oleh karena itu, kita dapat memberikan Market Quote Collector upgrade! biarkan market collector juga dapat berfungsi sebagai sumber data kustom untuk memberikan data ke sistem backtest.

Bersiaplah

Ini berbeda dari pekerjaan persiapan di artikel sebelumnya. terakhir kali adalah program docker yang berjalan di komputer MAC lokal saya, menginstal database mongodb untuk memulai layanan database. kali ini kami mengubah lingkungan operasi menjadi VPS dan menggunakan server Alibaba Cloud Linux untuk menjalankan serangkaian program kami.

  • Pangkalan data Mongodb

Seperti di artikel sebelumnya, kita perlu menginstal database mongodb pada perangkat di mana program market collector sedang berjalan dan memulai layanan. pada dasarnya sama dengan menginstal mongodb pada komputer MAC. ada banyak tutorial di Internet, Anda dapat google itu, sangat sederhana.

  • Menginstal Python 3

Program ini menggunakan python3, perhatikan penggunaan beberapa pustaka python, jika tidak diinstal, Anda perlu menginstalnya terlebih dahulu.

Pymongo http Urllib

  • Docker

FMZ docker berjalan akan cukup.

Mengubah Market Quote Collector

Pengumpul kutipan pasar adalah ini:https://www.fmz.com/strategy/199120(RecordsCollector) strategi.

Mari kita membuat beberapa modifikasi untuk itu:

Sebelum program memasuki loop sementara untuk mengumpulkan data, sebuah perpustakaan multi-threaded digunakan, dan eksekusi bersamaan memulai layanan untuk memantau permintaan data dari sistem backtest platform FMZ.

RecordsCollector (upgrade untuk menyediakan fungsi sumber data khusus)

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)

Tes

Mengkonfigurasi robot

img

Jalankan robot, jalankan kolektor penawaran pasar.

img

Buka strategi uji untuk backtest. Misalnya:

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 opsi backtest, mengatur pertukaran ke Binance karena sumber data kustom sementara belum dapat merumuskan nama pertukaran sendiri, Anda hanya dapat meminjam salah satu konfigurasi pertukaran dalam daftar, backtest menunjukkan bahwa Binance, yang sebenarnya Ini adalah data pasar simulasi WexApp.

img

Bandingkan apakah grafik yang dihasilkan oleh sistem backtest berdasarkan pengumpul kutipan pasar sebagai sumber data kustom sama dengan grafik K-line 1 jam di halaman pertukaran wexApp.

img img

Dengan cara ini, robot di VPS dapat mengumpulkan data K-line sendiri, dan kita dapat mendapatkan data yang dikumpulkan kapan saja dan backtest langsung di sistem backtest.

Anda dapat terus memperluas, misalnya, mencoba tingkat nyata backtest sumber data kustom, dan multi-varietas, multi-pasar pengumpulan data dan fungsi lainnya.


Berkaitan

Lebih banyak