Phương pháp tối ưu hóa các tham số lưới hợp đồng bền vững

Tác giả:Cỏ nhỏ, Tạo: 2023-12-08 17:00:38, Cập nhật: 2023-12-14 17:07:42

img

Chiến lược lưới vĩnh cửu là một chiến lược cổ điển rất phổ biến trên nền tảng. Không sử dụng tiền xu so với lưới hiện tại, có thể được sử dụng để nâng cấp và dễ dàng hơn so với lưới hiện tại. Nhưng do không thể xác định lại trực tiếp trên nền tảng định lượng của nhà phát minh, không lợi cho việc lọc loại tiền tệ và xác định tối ưu hóa các tham số, bài viết này sẽ giới thiệu quy trình kiểm tra lại Python đầy đủ, bao gồm mọi khía cạnh của việc thu thập dữ liệu, kiểm tra lại khung, kiểm tra các chức năng, tối ưu hóa các tham số, bạn có thể tự thử trong máy tính xách tay juypter.

Thu thập dữ liệu

Thông thường, dữ liệu đường K là đủ, để chính xác hơn, chu kỳ đường K càng nhỏ càng tốt, nhưng cân bằng thời gian và số lượng dữ liệu, bài viết này sử dụng dữ liệu 5min trong hai năm gần đây để kiểm tra lại dữ liệu, và cuối cùng số lượng dữ liệu vượt quá 20W.

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 lại

Đánh giá tiếp tục chọn khuôn khổ hỗ trợ USDT liên tục hợp đồng đa đồng tiền, đơn giản và hữu ích.

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 tìm lại lưới

Phương pháp của chiến lược lưới rất đơn giản, tăng bán, giảm mua, cụ thể liên quan đến ba thông số: giá ban đầu, khoảng cách lưới, giá trị giao dịch. DYDX biến động rất lớn, giảm 1U từ mức thấp ban đầu 8.6U, thị trường bò gần đây quay trở lại 3U, chiến lược mặc định giá ban đầu là 8.6U, điều này rất bất lợi đối với chiến lược lưới, nhưng thông số mặc định cho thấy tổng lợi nhuận 9200U trong hai năm, mất 7500U trong thời gian đó.img

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

img

Ảnh hưởng của giá khởi điểm

Cài đặt giá khởi điểm ảnh hưởng đến chiến lược nắm giữ ban đầu, giá khởi điểm mặc định vừa được lặp lại là giá khởi điểm khi khởi động, tức là không nắm giữ khi khởi động. Và chúng ta biết rằng chiến lược lưới sẽ thu được tất cả lợi nhuận khi giá trở lại ban đầu, vì vậy nếu chiến lược được khởi động có khả năng tiên đoán đúng về thị trường trong tương lai, lợi nhuận sẽ tăng lên đáng kể.

Tuy nhiên, khi đặt giá ban đầu là 3U, chiến lược sẽ giữ một lượng lớn hàng không trống ngay từ đầu, trong trường hợp này là giữ đơn hàng trống 17,000U, do đó, người có rủi ro lớn hơn.

img

Đặt khoảng cách lưới

Khoảng cách lưới quyết định khoảng cách đặt hàng, rõ ràng là khoảng cách nhỏ hơn giao dịch càng thường xuyên, lợi nhuận đơn lẻ càng thấp, chi phí thủ tục càng cao. Tuy nhiên, đáng chú ý, khoảng cách lưới càng nhỏ nhưng giá lưới không thay đổi, khi giá thay đổi, tổng cổ phần sẽ tăng, rủi ro hoàn toàn khác nhau. Vì vậy, để xác định lại vai trò của khoảng cách lưới, bạn cần phải tính giá lưới.

Do việc sử dụng dữ liệu đường 5mK và chỉ giao dịch một lần trên một đường K. Điều này rõ ràng không phù hợp với thực tế, đặc biệt là tỷ lệ biến động 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 việc kiểm tra lại so với thực tế, chỉ cần tăng khoảng cách mới có giá trị tham chiếu. Trong cơ chế kiểm tra lại này, kết luận không chính xác.

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 đây, khi biến động đồng thời, giá trị nắm giữ càng lớn, rủi ro và các phương pháp tỷ lệ, nhưng miễn là không giảm nhanh, 1% tổng vốn hỗ trợ 1% khoảng cách lưới nên đối phó với hầu hết các thị trường. Trong ví dụ này, DYDX giảm gần 90% và kích hoạt tăng giá. Nhưng hãy lưu ý rằng DYDX chủ yếu là giảm, giảm nhiều chiến lược lưới, giảm tối đa là 100% và tăng không giới hạn, rủi ro rất cao.

Giá quay trở lại

Giá quay trở lại 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 quyết định số lượng vị trí nên được giữ, nếu giá quay trở lại được thiết lập cao hơn giá hiện tại, chiến lược lưới sẽ làm nhiều hơn và ngược lại sẽ trống. Giá quay trở lại mặc định là giá khi chiến lược được khởi động. Để giảm rủi ro, khuyến cáo chỉ làm nhiều lưới, một ý tưởng tự nhiên là có thể thay đổi giá quay trở lại, để ngay cả khi giá tăng, vẫn giữ nhiều cổ phiếu, không tự điều chỉnh.img

Khi bắt đầu chiến lược, đặt giá quay trở lại là 1.6 lần giá khởi động, để chiến lược lưới bắt đầu nắm giữ nhiều vị trí gây ra phần chênh lệch này khi giá giảm từ 1.6 lần xuống giá hiện tại, nếu giá sau vượt quá giá quay trở lại / 1.6, thì đặt lại giá ban đầu, luôn giữ ít nhất 60% chênh lệch được sử dụng để làm nhiều. Kết quả quay trở lại như sau:img

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 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, cách thiết lập này cũng làm tăng rủi ro nắm giữ.


Thêm nữa

ĐEEETại sao fmz không thể trực tiếp truy cập lại các chính sách lưới?