Ketika aku menulisPenelitian tentang Strategi Hedging Multi-Valuta Binance Futures, Saya juga merilis mesin backtest. Dan laporan pertama didasarkan pada backtest K-line satu jam, yang memverifikasi efektivitas strategi. Tapi waktu tidur dari strategi sumber terbuka sebenarnya adalah
Pertama-tama, apa itu garis K historis? Data garis K berisi empat harga tinggi, terbuka, rendah, dekat, dua
Yang pertama adalah masalah waktu. Waktu harga tertinggi dan harga terendah dari data K-line tidak diberikan dan tidak perlu dipertimbangkan, tetapi harga pembukaan dan penutupan yang paling penting bukanlah waktu pembukaan dan penutupan. Bahkan varietas perdagangan yang kurang populer sering tidak memiliki perdagangan selama lebih dari sepuluh detik, dan ketika kita backtest strategi multi-varietas, kita sering berasumsi bahwa harga pembukaan dan harga penutupan mereka sama, yang juga didasarkan pada backtest harga penutupan.
Bayangkan menggunakan garis tingkat menit K untuk backtest arbitrase dua varietas. Perbedaan antara mereka biasanya 10 yuan ((atau dolar). Sekarang, pada pukul 10:01, harga penutupan kontrak A adalah 100, kontrak B adalah 112, dan perbedaannya adalah 12 yuan. Jadi strategi mulai lindung nilai. Pada saat tertentu, perbedaan harga kembali, dan strategi menghasilkan laba laba 2 yuan.
Tapi situasi sebenarnya mungkin adalah bahwa pada pukul 10:00:45, kontrak A menghasilkan transaksi 100 yuan, setelah itu tidak ada transaksi, kontrak B memiliki transaksi 112 yuan pada pukul 10:00:58, pada pukul 10:01:00 Kedua harga tidak ada.101.9
untuk102.1
, dan tidak ada perbedaan 2 yuan sama sekali.
Masalah kedua adalah masalah pencocokan. Pencocokan yang sebenarnya adalah prioritas harga dan prioritas waktu. Jika pembeli melebihi harga
Yang terakhir adalah dampak dari strategi itu sendiri pada pasar. Jika itu adalah backtest dana jumlah kecil, dampaknya tidak besar. Tapi jika volume transaksi besar, itu akan berdampak pada pasar. Tidak hanya akan tergelincir harga besar ketika Anda menempatkan pesanan volume besar, jika Anda membeli pesanan panjang yang dilaksanakan, tindakan semacam ini benar-benar merebut pesanan dari pedagang lain yang awalnya ingin membeli, efek
FMZ menyediakan backtest tingkat nyata, yang dapat memperoleh sejarah nyata20 layer depth price
, real-time tingkat keduaTicks
, Each Individual Transaction
Berdasarkan fitur ini, FMZ membuat fungsi pemutaran transaksi real-time.
Jumlah data backtest ini sangat besar, dan kecepatan backtest juga sangat lambat, umumnya hanya dapat backtest selama dua hari. Untuk strategi yang relatif frekuensi tinggi atau waktu kritis, backtest tingkat pasar nyata diperlukan. Pasangan perdagangan dan waktu perdagangan yang dikumpulkan oleh FMZ tidak terlalu lama, tetapi masih ada lebih dari 70 miliar data historis.
Mekanisme pencocokan saat ini adalah bahwa jika pesanan pembelian lebih besar dari
Ada terlalu sedikit informasi di garis K, dan kedalaman harga juga bisa menjadi kedalaman palsu, tapi ada jenis data yang merupakan pasar Each Individual Transaction
Artikel ini akan mengusulkan sistem backtest frekuensi tinggi berdasarkan aliran pesanan, yang akan sangat mengurangi volume data backtest tingkat pasar riil, dan sampai batas tertentu mensimulasikan dampak volume perdagangan di pasar.
Saya mengunduh transaksi 5 hari terakhir Binance XTZ kontrak abadi (Alamat download:https://www.fmz.com/upload/asset/1ff487b007e1a848ead.csv), sebagai varietas yang tidak populer, memiliki total 213000 data transaksi, pertama-tama mari kita lihat komposisi data:
[['XTZ', 1590981301905, 2.905, 0.4, 'False\n'],
['XTZ', 1590981303044, 2.903, 3.6, 'True\n'],
['XTZ', 1590981303309, 2.903, 3.7, 'True\n'],
['XTZ', 1590981303738, 2.903, 238.1, 'True\n'],
['XTZ', 1590981303892, 2.904, 0.1, 'False\n'],
['XTZ', 1590981305250, 2.904, 0.1, 'False\n'],
['XTZ', 1590981305643, 2.903, 197.3, 'True\n'],
Data adalah daftar dua dimensi, disortir dalam urutan kronologis. Makna spesifiknya adalah sebagai berikut: nama varietas, harga transaksi, timestamp transaksi, jumlah transaksi, apakah itu adalah transaksi aktif pesanan penjualan. Ada sisi membeli dan menjual, dan setiap transaksi mencakup pembeli dan penjual. Jika pembeli adalah pasarMaker
dan penjual adalah aktifTaker
, data terakhir adalahTrue
.
Pertama-tama, sesuai dengan arah transaksi, Anda dapat dengan cukup akurat berspekulasi tentang
Menurut aliran pesanan, dapat disesuaikan dengan cara ini: mengambil pesanan pembelian sebagai contoh, harga adalahprice
, jumlah pesanan adalahamount
, maka beli dan jual 1 pada saat ini adalahbid
danask
Jikaprice
lebih rendah dariask
dan lebih tinggi daribid
, maka dinilai sebagaimaker
pertama, dan prioritas dapat dicocokkan untuk membuat kesepakatan, maka semua transaksi dengan harga transaksi lebih rendah dari atau sama denganprice
selama waktu keberadaan order akan dicocokkan dengan order ini (jikaprice
adalah kurang dari atau sama denganbid
, tidak ada prioritas yang diberikan kepada transaksi.price
disesuaikan dengan urutan ini.)
Harga yang cocok adalahprice
, dan volume adalah volume transaksiEach Individual Transaction
, sampai pesanan selesai atau pesanan dibatalkan.ask
, dianggap sebagaitaker
Setelah itu, selama waktu ketika pesanan ada, semua transaksi dengan harga transaksi lebih rendah dari atau sama denganprice
yang cocok dengan pesanan ini, dan harga yang cocok adalah harga transaksi dariEach Individual Transaction
Perbedaan antaramaker
dantaker
strategi frekuensi tinggi, perbedaan ini harus dipertimbangkan.
Sangat mudah untuk melihat masalah dengan jenis pencocokan ini.taker
, situasi sebenarnya adalah bahwa hal itu dapat dilaksanakan segera, daripada menunggu pesanan baru untuk dicocokkan dengan itu. pertama-tama, kita tidak mempertimbangkan volume pesanan yang tertunda, bahkan jika ada beberapa data, langsung menilai transaksi juga telah mengubah kedalaman harga, mempengaruhi pasar.
Berdasarkan pencocokan pesanan baru, ini setara dengan mengganti pesanan yang ada dalam sejarah dengan pesanan Anda. Dalam hal apapun, itu tidak akan melebihi batas volume perdagangan pasar sendiri, dan keuntungan akhir tidak dapat melebihi keuntungan maksimum yang dihasilkan oleh pasar. Bagian dari mekanisme pencocokan juga mempengaruhi volume pesanan, yang pada gilirannya mempengaruhi pendapatan strategi, secara kuantitatif mencerminkan kapasitas strategi. Tidak akan ada backtest tradisional, ketika jumlah dana berlipat ganda dan keuntungan berlipat ganda.
Masih ada beberapa detail kecil. Jika harga pembelian pesanan sama dengan
Objek pertukaran dapat merujuk pada pengenalan di awal, pada dasarnya tidak berubah, hanya menambahkan perbedaan antaramaker
dantaker
Biaya, dan mengoptimalkan kecepatan backtest. Berikut ini terutama akan memperkenalkan kode pencocokan.
symbol = 'XTZ'
loop_time = 0
intervel = 1000 # The sleep time of the strategy is 1000ms
init_price = data[0][2] # Initial price
e = Exchange([symbol],initial_balance=1000000,maker_fee=maker_fee,taker_fee=taker_fee,log='') # Initialize the exchange
depth = {'ask':data[0][2], 'bid':data[0][2]} # depth
order = {'buy':{'price':0,'amount':0,'maker':False,'priority':False,'id':0},
'sell':{'price':0,'amount':0,'maker':False,'priority':False,'id':0}} # order
for tick in data:
price = int(tick[2]/tick_sizes[symbol])*tick_sizes[symbol] # executed price
trade_amount = tick[3] # executed volume
time_stamp = tick[1] # executed timestamp
if tick[4] == 'False\n':
depth['ask'] = price
else:
depth['bid'] = price
if depth['bid'] < order['buy']['price']:
order['buy']['priority'] = True
if depth['ask'] > order['sell']['price']:
order['sell']['priority'] = True
if price > order['buy']['price']:
order['buy']['maker'] = True
if price < order['sell']['price']:
order['sell']['maker'] = True
# Order network delay can also be used as one of the matching conditions, not considered here
cond1 = order['buy']['priority'] and order['buy']['price'] >= price and order['buy']['amount'] > 0
cond2 = not order['buy']['priority'] and order['buy']['price'] > price and order['buy']['amount'] > 0
cond3 = order['sell']['priority'] and order['sell']['price'] <= price and order['sell']['amount'] > 0
cond4 = not order['sell']['priority'] and order['sell']['price'] < price and order['sell']['amount'] > 0
if cond1 or cond2:
buy_price = order['buy']['price'] if order['buy']['maker'] else price
e.Buy(symbol, buy_price, min(order['buy']['amount'],trade_amount), order['buy']['id'], order['buy']['maker'])
order['buy']['amount'] -= min(order['buy']['amount'],trade_amount)
e.Update(time_stamp,[symbol],{symbol:price})
if cond3 or cond4:
sell_price = order['sell']['price'] if order['sell']['maker'] else price
e.Sell(symbol, sell_price, min(order['sell']['amount'],trade_amount), order['sell']['id'], order['sell']['maker'])
order['sell']['amount'] -= min(order['sell']['amount'],trade_amount)
e.Update(time_stamp,[symbol],{symbol:price})
if time_stamp - loop_time > intervel:
order = get_order(e,depth,order) # Trading logic, not given here
loop_time += int((time_stamp - loop_time)/intervel)*intervel
Beberapa detail untuk dicatat:
Ketika ada transaksi baru, kita harus terlebih dahulu mencocokkan pesanan, dan kemudian menempatkan pesanan sesuai dengan harga terbaru.
Setiap order memiliki dua atribut: makermaker
, dan ketika harga beli lebih besar dari Priority matching
, priority
menentukan apakah harga sama dengan harga beli atau tidak, dan pembuat menentukan biaya transaksi.
Peraturanmaker
danpriority
Jika pembelian besar dilakukan dan melebihi kapasitas pasar. Ketika harga lebih besar dari harga pembelian, volume yang tersisa akanmaker
.
Strategiinterval
diperlukan, itu bisa mewakili penundaan pasar.
Akhirnya, ini adalah tahap backtest yang sebenarnya. Mari kita backtest salah satu strategi grid paling klasik di sini untuk melihat apakah kita dapat mencapai hasil yang diharapkan. Prinsip strategi adalah bahwa setiap kali harga naik sebesar 1%, kita memegang pesanan pendek dari nilai tertentu (sebaliknya, kita memegang pesanan panjang), menghitung pesanan beli dan jual terlebih dahulu. saya tidak akan menunjukkan kode sumber. mereka semua dikemas ke dalamGrid('XTZ', 100, 0.3, 1000, maker_fee=-0.00002, taker_fee=0.0003)
Fungsi, parameter adalah: pasangan perdagangan, harga menyimpang dari nilai kepemilikan 1%, kepadatan pesanan tertunda adalah 0,3%, interval tidurms
, biaya order yang belum selesai dan biaya order yang telah dilaksanakan.
Harga pasar XTZ
Pertama kita melakukan backtest efek dari posisi kepemilikan yang berbeda pada laba kembali. laba kembali yang diuji oleh mekanisme backtest tradisional pasti akan meningkat sebanding dengan peningkatan posisi kepemilikan.
e1 = Grid('XTZ',100,0.3,1000,maker_fee=-0.00002,taker_fee=0.0003)
print(e1.account['USDT'])
e2 = Grid('XTZ',1000,0.3,1000,maker_fee=-0.00002,taker_fee=0.0003)
print(e2.account['USDT'])
e3 = Grid('XTZ',10000,0.3,1000,maker_fee=-0.00002,taker_fee=0.0003)
print(e3.account['USDT'])
e4 = Grid('XTZ',100000,0.3,1000,maker_fee=-0.00002,taker_fee=0.0003)
print(e4.account['USDT'])
Secara total empat kelompok diuji kembali, nilai posisi memegang adalah 100, 1000, 10000, 100.000, dan total waktu uji kembali adalah 1,3 s. Hasilnya adalah sebagai berikut:
{'realised_profit': 28.470993031132966, 'margin': 0.7982662957624465, 'unrealised_profit': 0.0104554474048441, 'total': 10000028.481448, 'leverage': 0.0, 'fee': -0.3430967859046398, 'maker_fee': -0.36980249726699727, 'taker_fee': 0.026705711362357405}
{'realised_profit': 275.63148945320177, 'margin': 14.346335829979132, 'unrealised_profit': 4.4382117331794045e-14, 'total': 10000275.631489, 'leverage': 0.0, 'fee': -3.3102045933457784, 'maker_fee': -3.5800688964477048, 'taker_fee': 0.2698643031019274}
{'realised_profit': 2693.8701498889504, 'margin': 67.70120400534114, 'unrealised_profit': 0.5735269329348516, 'total': 10002694.443677, 'leverage': 0.0001, 'fee': -33.984021415250744, 'maker_fee': -34.879233866850974, 'taker_fee': 0.8952124516001403}
{'realised_profit': 22610.231198585603, 'margin': 983.3853688758861, 'unrealised_profit': -20.529965947304365, 'total': 10022589.701233, 'leverage': 0.002, 'fee': -200.87094000385412, 'maker_fee': -261.5849078470078, 'taker_fee': 60.71396784315319}
Hal ini juga sesuai dengan situasi yang sebenarnya. Semakin besar nilai posisi kepemilikan, semakin besar nilai pesanan yang sedang menunggu, semakin besar kemungkinan transaksi parsial akan terjadi, dan semakin kecil keuntungan akhir yang direalisasikan relatif terhadap jumlah pesanan yang sedang menunggu. Bagan berikut adalah perbandingan laba relatif nilai posisi masing-masing 100 dan 10000:
Kita juga dapat melakukan backtest dampak dari parameter yang berbeda pada pendapatan backtest, seperti kepadatan pesanan yang menunggu, waktu tidur, biaya transaksi, dll. Ambil waktu tidur sebagai contoh, ubah menjadi 100ms, dan bandingkan waktu tidur dengan 1000ms untuk melihat laba kembali. Hasil backtest adalah sebagai berikut:
{'realised_profit': 29.079440803790423, 'margin': 0.7982662957624695, 'unrealised_profit': 0.0104554474048441, 'total': 10000029.089896, 'leverage': 0.0, 'fee': -0.3703702128662524, 'maker_fee': -0.37938946377435134, 'taker_fee': 0.009019250908098965}
pendapatan telah meningkat sedikit, karena strategi hanya mengirim satu set pesanan, beberapa pesanan tidak akan dapat melaksanakan harga berfluktuasi karena mereka tidak memiliki waktu untuk berubah, dan pengurangan waktu tidur memperbaiki masalah ini.
Artikel ini secara inovatif mengusulkan sistem backtest baru berdasarkan aliran order, yang dapat sebagian mensimulasikan situasi pencocokan order yang tertunda, order yang dieksekusi, order yang dieksekusi sebagian, penundaan, dll, dan sebagian mencerminkan dampak dari jumlah dana strategi pada pendapatan. Untuk strategi frekuensi tinggi dan lindung nilai, Ini memiliki nilai referensi yang penting.