3
tập trung vào
1444
Người theo dõi

Giải thích chi tiết về tối ưu hóa tham số chiến lược lưới hợp đồng vĩnh viễn

Được tạo ra trong: 2023-12-08 17:00:38, cập nhật trên: 2023-12-14 17:07:42
comments   1
hits   2862

Giải thích chi tiết về tối ưu hóa tham số chiến lược lưới hợp đồng vĩnh viễn

Chiến lược lưới vĩnh cửu là một chiến lược cổ điển phổ biến trên nền tảng này. So với lưới giao ngay, không cần phải giữ tiền xu và có thể thêm đòn bẩy, thuận tiện hơn nhiều so với lưới giao ngay. Tuy nhiên, vì không thể kiểm tra ngược trực tiếp trên Nền tảng định lượng Inventor nên không có lợi cho việc sàng lọc tiền tệ và xác định tối ưu hóa tham số. Bài viết này sẽ giới thiệu toàn bộ quy trình kiểm tra ngược Python, bao gồm thu thập dữ liệu, khung kiểm tra ngược, hàm kiểm tra ngược, tối ưu hóa tham số, v.v. Bạn có thể tự mình thử nghiệm trong sổ tay juypter.

Thu thập dữ liệu

Nhìn chung, dữ liệu K-line là đủ. Để có độ chính xác, chu kỳ K-line càng nhỏ thì càng tốt. Tuy nhiên, thời gian kiểm tra ngược và khối lượng dữ liệu phải cân bằng. Bài viết này sử dụng dữ liệu 5 phút từ hai năm qua để kiểm tra ngược . Khối lượng dữ liệu cuối cùng vượt quá 200.000 hàng. Chọn DYDX. Tất nhiên, bạn có thể lựa chọn loại tiền tệ cụ thể và thời hạn K-line theo sở thích của mình.

import requests
from datetime import date,datetime
import time
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import requests, zipfile, io
%matplotlib inline

def GetKlines(symbol='BTC',start='2020-8-10',end='2021-8-10',period='1h'):
    Klines = []
    start_time = int(time.mktime(datetime.strptime(start, "%Y-%m-%d").timetuple()))*1000
    end_time = int(time.mktime(datetime.strptime(end, "%Y-%m-%d").timetuple()))*1000
    while start_time < end_time:
        res = requests.get('https://fapi.binance.com/fapi/v1/klines?symbol=%sUSDT&interval=%s&startTime=%s&limit=1000'%(symbol,period,start_time))
        res_list = res.json()
        Klines += res_list
        start_time = res_list[-1][0]
    return pd.DataFrame(Klines,columns=['time','open','high','low','close','amount','end_time','volume','count','buy_amount','buy_volume','null']).astype('float')

df = GetKlines(symbol='DYDX',start='2022-1-1',end='2023-12-7',period='5m')
df = df.drop_duplicates()

Khung kiểm tra ngược

Backtest tiếp tục sử dụng khuôn khổ được sử dụng phổ biến trước đây, hỗ trợ nhiều loại tiền tệ của hợp đồng vĩnh viễn USDT, đơn giản và dễ sử dụng.

class Exchange:
    
    def __init__(self, trade_symbols, fee=0.0004, initial_balance=10000):
        self.initial_balance = initial_balance #初始的资产
        self.fee = fee
        self.trade_symbols = trade_symbols
        self.account = {'USDT':{'realised_profit':0, 'unrealised_profit':0, 'total':initial_balance, 'fee':0}}
        for symbol in trade_symbols:
            self.account[symbol] = {'amount':0, 'hold_price':0, 'value':0, 'price':0, 'realised_profit':0,'unrealised_profit':0,'fee':0}
            
    def Trade(self, symbol, direction, price, amount):
        
        cover_amount = 0 if direction*self.account[symbol]['amount'] >=0 else min(abs(self.account[symbol]['amount']), amount)
        open_amount = amount - cover_amount
        self.account['USDT']['realised_profit'] -= price*amount*self.fee #扣除手续费
        self.account['USDT']['fee'] += price*amount*self.fee
        self.account[symbol]['fee'] += price*amount*self.fee

        if cover_amount > 0: #先平仓
            self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount  #利润
            self.account[symbol]['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount
            
            self.account[symbol]['amount'] -= -direction*cover_amount
            self.account[symbol]['hold_price'] = 0 if self.account[symbol]['amount'] == 0 else self.account[symbol]['hold_price']
            
        if open_amount > 0:
            total_cost = self.account[symbol]['hold_price']*direction*self.account[symbol]['amount'] + price*open_amount
            total_amount = direction*self.account[symbol]['amount']+open_amount
            
            self.account[symbol]['hold_price'] = total_cost/total_amount
            self.account[symbol]['amount'] += direction*open_amount
                    
    
    def Buy(self, symbol, price, amount):
        self.Trade(symbol, 1, price, amount)
        
    def Sell(self, symbol, price, amount):
        self.Trade(symbol, -1, price, amount)
        
    def Update(self, close_price): #对资产进行更新
        self.account['USDT']['unrealised_profit'] = 0
        for symbol in self.trade_symbols:
            self.account[symbol]['unrealised_profit'] = (close_price[symbol] - self.account[symbol]['hold_price'])*self.account[symbol]['amount']
            self.account[symbol]['price'] = close_price[symbol]
            self.account[symbol]['value'] = abs(self.account[symbol]['amount'])*close_price[symbol]
            self.account['USDT']['unrealised_profit'] += self.account[symbol]['unrealised_profit']
        self.account['USDT']['total'] = round(self.account['USDT']['realised_profit'] + self.initial_balance + self.account['USDT']['unrealised_profit'],6)

Chức năng kiểm tra ngược lưới

Nguyên lý của chiến lược lưới rất đơn giản: bán khi giá tăng và mua khi giá giảm. Nó bao gồm ba thông số cụ thể: giá ban đầu, khoảng cách lưới và giá trị giao dịch. Biến động thị trường của DYDX rất lớn. Nó đã giảm từ 8,6U ban đầu xuống 1U và đã tăng trở lại 3U trong thị trường tăng giá gần đây. Giá ban đầu mặc định của chiến lược là 8,6U, rất bất lợi cho lưới điện chiến lược, nhưng tham số mặc định là kiểm tra ngược Tổng lợi nhuận trong hai năm là 9200U và có thời điểm lỗ 7500U. Giải thích chi tiết về tối ưu hóa tham số chiến lược lưới hợp đồng vĩnh viễn

symbol = 'DYDX'
value = 100
pct = 0.01

def Grid(fee=0.0002, value=100, pct=0.01, init = df.close[0]):
    e = Exchange([symbol], fee=0.0002, initial_balance=10000)
    init_price = init
    res_list = [] #用于储存中间结果
    for row in df.iterrows():
        kline = row[1] #这样会测一根K线只会产生一个买单或一个卖单,不是特别精确
        buy_price = (value / pct - value) / ((value / pct) / init_price + e.account[symbol]['amount']) #买单价格,由于是挂单成交,也是最终的撮合价格
        sell_price = (value / pct + value) / ((value / pct) / init_price + e.account[symbol]['amount'])
        if kline.low < buy_price: #K线最低价低于当前挂单价,买单成交
            e.Buy(symbol,buy_price,value/buy_price)
        if kline.high > sell_price:
            e.Sell(symbol,sell_price,value/sell_price)
        e.Update({symbol:kline.close})
        res_list.append([kline.time, kline.close, e.account[symbol]['amount'], e.account['USDT']['total']-e.initial_balance,e.account['USDT']['fee'] ])
    res = pd.DataFrame(data=res_list, columns=['time','price','amount','profit', 'fee'])
    res.index = pd.to_datetime(res.time,unit='ms')
    return res

Giải thích chi tiết về tối ưu hóa tham số chiến lược lưới hợp đồng vĩnh viễn

Tác động của giá ban đầu

Thiết lập giá ban đầu ảnh hưởng đến vị thế ban đầu của chiến lược. Giá ban đầu mặc định của backtest vừa rồi là giá ban đầu khi khởi động, tức là không có vị thế nào được giữ khi khởi động. Chúng tôi biết rằng chiến lược lưới sẽ mang lại toàn bộ lợi nhuận khi giá trở lại mức ban đầu, vì vậy nếu chiến lược có thể dự đoán chính xác thị trường tương lai khi ra mắt thì lợi nhuận sẽ tăng đáng kể. Ở đây chúng tôi đặt giá ban đầu là 3U và sau đó tiến hành kiểm tra ngược. Mức giảm tối đa cuối cùng là 9200U và lợi nhuận cuối cùng là 13372U. Chiến lược cuối cùng không giữ vị thế. Lợi nhuận này là toàn bộ lợi nhuận biến động và sự khác biệt giữa lợi nhuận của các tham số mặc định và lợi nhuận này là tổn thất vị thế do phán đoán không chính xác về giá cuối cùng.

Tuy nhiên, nếu giá ban đầu được đặt ở mức 3U, chiến lược sẽ đi vào trạng thái bán khống ngay từ đầu và nắm giữ một số lượng lớn các vị thế bán khống. Trong ví dụ này, một vị thế bán khống 17.000 U được nắm giữ trực tiếp, do đó, nó phải đối mặt với rủi ro lớn hơn.

Giải thích chi tiết về tối ưu hóa tham số chiến lược lưới hợp đồng vĩnh viễn

Thiết lập khoảng cách lưới

Khoảng cách lưới xác định khoảng cách giữa các lệnh đang chờ xử lý. Rõ ràng, khoảng cách càng nhỏ thì giao dịch càng thường xuyên, lợi nhuận của một giao dịch càng thấp và phí xử lý càng cao. Nhưng điều đáng chú ý là khi khoảng cách lưới trở nên nhỏ hơn và giá trị lưới không đổi, tổng vị thế sẽ tăng lên khi giá thay đổi và rủi ro phải đối mặt hoàn toàn khác. Do đó, để kiểm tra ngược lại hiệu ứng của khoảng cách lưới, cần phải chuyển đổi giá trị lưới.

Vì thử nghiệm ngược sử dụng dữ liệu dòng 5mK và chỉ có một giao dịch được thực hiện trên dòng K. Điều này rõ ràng là không phù hợp với thực tế, đặc biệt là vì tính biến động của tiền kỹ thuật số rất lớn. Khoảng cách nhỏ hơn sẽ bỏ lỡ nhiều giao dịch trong quá trình kiểm tra ngược so với giao dịch thực tế. Chỉ có khoảng cách lớn hơn mới có giá trị tham chiếu. Theo cơ chế kiểm tra ngược này, các kết luận đưa ra là không chính xác. Thông qua việc kiểm tra ngược dữ liệu luồng lệnh ở mức tích tắc, khoảng cách lưới tối ưu phải là 0,005-0,01.

for p in [0.0005, 0.001 ,0.002 ,0.005, 0.01, 0.02, 0.05]:
    res = Grid( fee=0.0002, value=value*p/0.01, pct=p, init =3)
    print(p, round(min(res['profit']),0), round(res['profit'][-1],0), round(res['fee'][-1],0))
    
0.0005 -8378.0 144.0 237.0
0.001 -9323.0 1031.0 465.0
0.002 -9306.0 3606.0 738.0
0.005 -9267.0 9457.0 781.0
0.01 -9228.0 13375.0 550.0
0.02 -9183.0 15212.0 309.0
0.05 -9037.0 16263.0 131.0

Giá trị giao dịch lưới

Như đã đề cập trước đó, khi độ biến động giống nhau, giá trị nắm giữ càng lớn thì phương pháp tỷ lệ rủi ro càng cao. Tuy nhiên, miễn là không phải là sự suy giảm nhanh chóng, 1% tổng số tiền kết hợp với 1% khoảng cách lưới phải có khả năng ứng phó với hầu hết các điều kiện thị trường. Trong ví dụ DYDX này, mức giảm gần 90% cũng gây ra lệnh gọi ký quỹ. Nhưng xin lưu ý rằng DYDX chủ yếu giảm. Khi nó giảm, chiến lược lưới sẽ tăng và mức giảm tối đa là 100%. Tuy nhiên, không có giới hạn tăng và rủi ro cao hơn nhiều. Do đó, chiến lược lưới khuyến nghị người dùng nên chọn các loại tiền tệ mà họ cho là có tiềm năng và chỉ mua vào.

Giá hồi quy biến đổi

Giá hồi quy là giá ban đầu. Sự khác biệt giữa giá hiện tại và giá ban đầu và kích thước lưới xác định vị thế nên được giữ ở mức nào. Nếu giá hồi quy được đặt cao hơn giá hiện tại, chiến lược lưới sẽ đi dài và ngược lại. Giá hồi quy mặc định là mức giá mà chiến lược được bắt đầu. Để giảm rủi ro, nên sử dụng lưới chỉ dài. Một ý tưởng tự nhiên là liệu có thể thay đổi giá hồi quy để ngay cả khi giá tăng, bạn vẫn có thể giữ các vị thế dài mà không cần phải điều chỉnh chúng bản thân bạn. Lấy thị trường BTC năm nay làm ví dụ, nó đã tăng từ 15.000 vào đầu năm lên 43.000 vào cuối năm. Nếu bạn bắt đầu chạy chiến lược lưới từ đầu năm, giá lợi nhuận mặc định là 15.000 và bạn thực hiện cả giao dịch dài hạn và ngắn hạn. Lợi nhuận cụ thể được thể hiện như trong hình bên dưới. Bạn sẽ mất tiền hoàn toàn vì BTC tăng lên. Ngay cả khi chế độ chỉ mua không được thiết lập đúng cách, giá vẫn có thể nhanh chóng vượt quá giới hạn nếu không giữ được vị thế. Giải thích chi tiết về tối ưu hóa tham số chiến lược lưới hợp đồng vĩnh viễn

Đầu tiên, khi chiến lược được bắt đầu, giá hồi quy được đặt ở mức 1,6 lần giá tại thời điểm khởi động. Theo cách này, chiến lược lưới sẽ coi giá giảm từ 1,6 lần xuống giá hiện tại và bắt đầu giữ giá dài vị trí do phần chênh lệch giá này gây ra. Nếu giá tiếp theo vượt quá Khi giá trả về là /1,6, giá ban đầu được thiết lập lại, do đó ít nhất 60% chênh lệch luôn có sẵn cho các vị thế mua. Kết quả kiểm tra ngược như sau: Giải thích chi tiết về tối ưu hóa tham số chiến lược lưới hợp đồng vĩnh viễn

Tất nhiên, nếu bạn lạc quan hơn về thị trường, bạn có thể đặt tỷ lệ này thành giá trị lớn hơn và lợi nhuận cuối cùng sẽ tăng theo. Tất nhiên, nếu thị trường giảm, thiết lập này cũng sẽ làm tăng rủi ro nắm giữ vị thế.