Sumber dimuat naik... memuat...

Perincian parameter optimum strategi grid kontrak kekal

Penulis:Rumput, Dicipta: 2023-12-08 17:00:38, Dikemas kini: 2023-12-14 17:07:42

img

Strategi grid kekal adalah strategi klasik platform yang sangat popular. Tidak menggunakan koin berbanding grid langsung, ia boleh dimanfaatkan dan lebih mudah daripada grid langsung. Tetapi kerana tidak dapat mengutip semula secara langsung di platform pencipta, tidak menguntungkan untuk menyaring mata wang dan menentukan pengoptimuman parameter, artikel ini akan memperkenalkan proses pengutipan semula Python yang lengkap, yang merangkumi semua aspek pengumpulan data, pengutipan semula kerangka, fungsi pengutipan, pengoptimuman parameter, dan lain-lain. Anda boleh mencuba sendiri di buku nota juypter.

Pengumpulan data

Secara amnya data K-line sudah cukup, untuk ketepatan, lebih baik tempoh K-line yang lebih kecil, tetapi untuk mengimbangi masa dan kuantiti data, artikel ini menggunakan data 5min untuk mengulangi masa dan kuantiti data dua tahun kebelakangan ini, dan jumlah data akhirnya melebihi 20W baris, mata wang memilih DYDX. Sudah tentu mata wang tertentu dan tempoh K-line boleh dipilih mengikut minat anda sendiri.

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()

Rangka Kerja Ujian Kembali

Ujian semula terus memilih kerangka kerja yang biasa digunakan sebelum ini untuk menyokong USDT untuk kontrak jangka panjang multi mata wang, mudah digunakan.

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)

Fungsi pengulangan grid

Prinsip strategi grid adalah mudah, menjual lebih banyak, membeli lebih sedikit, dan melibatkan tiga parameter: harga awal, selang grid, nilai dagangan. DYDX mempunyai turun naik yang sangat besar, turun 1U dari minimum awal 8.6U, pasaran lembu baru-baru ini kembali ke 3U, strategi harga awal lalai adalah 8.6U, yang sangat tidak menguntungkan untuk strategi grid, tetapi parameter lalai menunjukkan keuntungan 9200U selama dua tahun, kehilangan 7500U pada satu masa.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

Kesan harga awal

Tetapan harga awal mempengaruhi pegangan awal strategi, harga awal lalai yang baru diulas adalah harga awal ketika dimulakan, iaitu tidak memegang pegangan pada permulaan. Dan kita tahu bahawa strategi grid akan menjana semua keuntungan pada saat harga mula kembali, jadi jika strategi dimulakan dapat meramalkan dengan betul mengenai keadaan masa depan, pendapatan akan meningkat dengan ketara. Tetapan harga awal di sini 3U diulang.

Tetapi harga awal ditetapkan pada 3U, strategi akan kosongkan dari awal dan memegang banyak stok kosong, dalam contoh ini memegang secara langsung 17,000 U kosong, dan oleh itu juga menghadapi risiko yang lebih besar.

img

Tetapan jarak grid

Jarak kisi menentukan jarak pesanan yang diikat, jelas bahawa jarak yang lebih kecil adalah lebih kerap berdagang, keuntungan yang lebih rendah untuk satu sen, dan kos prosedur yang lebih tinggi. Tetapi perlu diperhatikan, jarak kisi menjadi lebih kecil dan nilai kisi tidak berubah, apabila harga berubah, jumlah pegangan akan meningkat, risiko yang dihadapi sama sekali berbeza. Oleh itu, untuk mengkaji semula peranan jarak kisi, perlu menukar nilai kisi.

Oleh kerana retest menggunakan data baris 5mK dan hanya berdagang sekali pada satu baris K. Ini jelas tidak sesuai dengan realiti, terutamanya apabila turun naik mata wang digital sangat besar, selang yang lebih kecil akan kehilangan banyak transaksi dalam retest berbanding dengan rak sebenar, dan hanya selang yang lebih besar yang mempunyai nilai rujukan. Di bawah mekanisme retest ini, kesimpulan tidak tepat. Dengan retest aliran data pesanan peringkat tik, selang grid yang optimum harus berada di 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

Nilai Perdagangan Grid

Seperti yang telah disebutkan di atas, apabila turun naik pada masa yang sama, nilai yang dipegang lebih besar, risiko dan lain-lain kaedah perbandingan, tetapi selagi tidak penurunan pesat, 1% daripada jumlah modal keseluruhan dengan 1% selisih grid harus dapat menangani kebanyakan pasaran. Dalam contoh DYDX ini, penurunan hampir 90% juga mencetuskan ledakan.

Harga Kembali Berubah

Harga kembalikan adalah harga permulaan, perbezaan antara harga semasa dan harga awal dan saiz grid menentukan berapa banyak kedudukan yang harus dipegang, jika harga kembalikan ditetapkan lebih tinggi daripada harga semasa, strategi grid akan melakukan lebih banyak, dan sebaliknya akan kosong. Harga kembalikan lalai adalah harga ketika strategi dimulakan. Untuk mengurangkan risiko, direkomendasikan untuk melakukan hanya banyak grid, satu idea semula jadi adalah, boleh atau tidak mengubah harga kembalikan, sehingga walaupun harga meningkat, masih memegang banyak saham, tidak disesuaikan secara automatik.img

Pada permulaan strategi, harga pulangan ditetapkan pada 1.6 kali harga permulaan, supaya strategi grid akan memegang banyak kedudukan yang disebabkan oleh perbezaannya ini apabila harga jatuh dari 1.6 kali harga semasa, dan jika harga kemudian melebihi harga pulangan / 1.6, ia diset semula pada harga awal, sehingga sentiasa mengekalkan sekurang-kurangnya 60% perbezaan untuk melakukan banyak; hasil retesting adalah sebagai berikut:img

Sudah tentu jika anda lebih optimis dengan pasaran, anda boleh menetapkan peratusan ini lebih besar, dan hasil akhir akan meningkat dengan sewajarnya, tentu saja jika pasaran jatuh, pengaturan ini juga meningkatkan risiko memegang.


Lebih lanjut

NanSegKenapa fmz tidak boleh mengulangi strategi grid secara langsung?