Apabila saya menulisPenyelidikan mengenai Strategi Hedging Multi-mata wang Binance Futures, Saya juga mengeluarkan enjin backtest. Dan laporan pertama adalah berdasarkan backtest K-line satu jam, yang mengesahkan keberkesanan strategi. Tetapi masa tidur strategi sumber terbuka sebenar adalah
Pertama sekali, apakah garis K sejarah? Data K-line mengandungi empat harga tinggi, terbuka, rendah, dekat, dua
Yang pertama adalah isu masa. Masa harga tertinggi dan harga terendah data K-line tidak diberikan dan tidak perlu dipertimbangkan, tetapi harga pembukaan dan penutupan yang paling penting bukanlah masa pembukaan dan penutupan. Malah varieti perdagangan yang kurang popular sering tidak mempunyai perdagangan selama lebih dari sepuluh saat, dan apabila kita menguji strategi pelbagai varieti, kita sering menganggap bahawa harga pembukaan dan harga penutupan mereka adalah sama, yang juga berdasarkan ujian belakang harga penutupan.
Bayangkan menggunakan garis K tahap minit untuk menguji semula arbitrase dua jenis. Perbezaan antara mereka biasanya 10 yuan ((atau dolar). Sekarang, pada 10:01, harga penutupan kontrak A adalah 100, kontrak B adalah 112, dan perbezaannya adalah 12 yuan. Jadi strategi mula lindung nilai. Pada saat tertentu, perbezaan harga kembali, dan strategi menghasilkan keuntungan pulangan 2 yuan.
tetapi situasi sebenar mungkin ialah pada pukul 10:00:45, kontrak A menghasilkan transaksi 100 yuan, selepas itu tidak ada transaksi, kontrak B mempunyai transaksi 112 yuan pada pukul 10:00:58, pada 10:01:00 Kedua-dua harga tidak wujud. Apakah harga pasaran pada masa ini, dan berapa banyak operasi lindung nilai dapat mendapat? Saya tidak boleh tahu. Satu situasi yang mungkin adalah: pada pukul 10:00:58, harga pesanan menunggu 101.9
kepada102.1
, dan tiada perbezaan 2 yuan sama sekali. ini akan sangat mengelirukan optimasi strategi kita.
Kedua adalah masalah pencocokan. Pencocokan sebenar adalah keutamaan harga dan keutamaan masa. Jika pembeli melebihi harga
Yang terakhir adalah kesan strategi itu sendiri pada pasaran. Jika ia adalah backtest dana sejumlah kecil, kesannya tidak besar. Tetapi jika jumlah urus niaga besar, ia akan memberi kesan kepada pasaran. Bukan sahaja kemerosotan harga akan besar apabila anda meletakkan pesanan jumlah yang besar, jika anda membeli pesanan panjang dilaksanakan, tindakan semacam ini sebenarnya merebut pesanan pedagang lain yang pada asalnya ingin membeli, kesan
FMZ menyediakan backtest tahap sebenar, yang boleh mendapatkan sejarah sebenar20 layer depth price
, masa nyata tahap keduaTicks
, Each Individual Transaction
Berdasarkan ciri-ciri ini, FMZ membuat fungsi pemutaran transaksi masa nyata.
Jumlah data backtest ini sangat besar, dan kelajuan backtest juga sangat perlahan, biasanya hanya boleh backtest selama dua hari. Untuk strategi yang agak kerap atau kritikal masa, backtest tahap pasaran sebenar diperlukan. Pasangan perdagangan dan masa perdagangan yang dikumpulkan oleh FMZ tidak terlalu lama, tetapi masih ada lebih daripada 70 bilion data sejarah.
Mekanisme pencocokan semasa adalah bahawa jika pesanan pembelian lebih besar daripada
Terdapat terlalu sedikit maklumat dalam garis K, dan kedalaman harga juga boleh menjadi kedalaman palsu, tetapi terdapat sejenis data yang merupakan pasaranEach Individual Transaction
Artikel ini akan mencadangkan sistem backtest kekerapan tinggi berdasarkan aliran pesanan, yang akan mengurangkan jumlah data backtest tahap pasaran sebenar, dan hingga tahap tertentu mensimulasikan kesan jumlah dagangan di pasaran.
Saya memuat turun urus niaga 5 hari terakhir Binance XTZ kontrak kekal (alamat muat turun:https://www.fmz.com/upload/asset/1ff487b007e1a848ead.csv), sebagai jenis yang tidak popular, ia mempunyai jumlah data 213000 transaksi, pertama 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 senarai dua dimensi, disusun mengikut urutan kronologi. Makna khusus adalah sebagai berikut: nama varieti, harga transaksi, cap waktu transaksi, kuantiti transaksi, sama ada ia adalah urus niaga pesanan jualan aktif. Terdapat membeli dan menjual sisi, dan setiap urus niaga termasuk pembeli dan penjual. Jika pembeli adalah pasaranMaker
dan penjual adalah aktifTaker
, data terakhir adalahTrue
.
Pertama sekali, mengikut hala tuju transaksi, anda boleh membuat spekulasi dengan tepat mengenai
Menurut aliran pesanan, ia boleh disamakan dengan cara ini: mengambil pesanan pembelian sebagai contoh, harga adalahprice
, kuantiti pesanan adalahamount
, kemudian membeli dan menjual 1 pada masa ini adalahbid
danask
Jikaprice
adalah lebih rendah daripadaask
dan lebih tinggi daripadabid
, maka ia dinilai sebagaimaker
pertama, dan keutamaan boleh dipadankan untuk membuat perjanjian, maka semua urus niaga dengan harga urus niaga yang lebih rendah daripada atau sama denganprice
semasa masa wujud pesanan akan sepadan dengan pesanan ini (jikaprice
adalah kurang daripada atau sama denganbid
, tiada keutamaan diberikan kepada urus niaga.price
disamakan dengan urutan ini.)
Harga yang sepadan adalahprice
, dan jumlah adalah jumlah transaksiEach Individual Transaction
, sehingga pesanan selesai sepenuhnya atau pesanan dibatalkan.ask
, ia dinilai sebagaitaker
Selepas itu, semasa pesanan itu wujud, semua urus niaga dengan harga urus niaga lebih rendah daripada atau sama denganprice
adalah sepadan dengan pesanan ini, dan harga sepadan adalah harga transaksiEach Individual Transaction
. Perbezaan antaramaker
dantaker
adalah pada dasarnya kerana bursa menggalakkan pesanan menunggu dan terdapat diskaun untuk yuran urus niaga.
Adalah mudah untuk melihat masalah dengan jenis pencocokan ini.taker
, situasi sebenar adalah bahawa ia boleh dilaksanakan dengan serta-merta, dan bukannya menunggu pesanan baru untuk dipadankan dengan ia. pertama sekali, kita tidak mempertimbangkan jumlah pesanan menunggu, walaupun ada beberapa data, langsung menilai urus niaga juga telah berubah kedalaman harga, mempengaruhi pasaran.
Berdasarkan pencocokan pesanan baru, ia bersamaan dengan menggantikan pesanan yang ada dalam sejarah dengan pesanan anda. Dalam apa jua keadaan, ia tidak akan melebihi had jumlah dagangan pasaran sendiri, dan keuntungan akhir tidak boleh melebihi keuntungan maksimum yang dihasilkan oleh pasaran. Sebahagian daripada mekanisme pencocokan juga mempengaruhi jumlah pesanan, yang seterusnya mempengaruhi pendapatan strategi, secara kuantitatif mencerminkan kapasiti strategi. Tidak akan ada ujian belakang tradisional, apabila jumlah dana berlipat ganda dan keuntungan berlipat ganda.
Masih ada beberapa butiran kecil. Jika harga pembelian pesanan sama dengan
Objek pertukaran boleh merujuk kepada pengenalan di awal, pada dasarnya tidak berubah, hanya menambah perbezaan antaramaker
dantaker
berikut akan terutamanya memperkenalkan kod 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 butiran untuk diperhatikan:
Apabila ada urus niaga baru, kita mesti mencocokkan pesanan terlebih dahulu, dan kemudian meletakkan pesanan mengikut harga terkini.
Setiap pesanan mempunyai dua atribut: pembuatmaker
, dan apabila harga beli lebih besar daripada Priority matching
, priority
menentukan sama ada harga sama dengan harga pembelian atau tidak, dan pembuat menentukan yuran transaksi.
Peraturanmaker
danpriority
Jika pembelian besar telah diletakkan dan melebihi kapasiti pasaran. Apabila harga adalah lebih besar daripada harga pembelian, jumlah yang tersisa akan menjadimaker
.
Strategiinterval
perlu, ia boleh mewakili kelewatan pasaran.
Akhirnya, ia adalah peringkat backtest sebenar. Mari kita backtest salah satu strategi grid yang paling klasik di sini untuk melihat sama ada kita boleh mencapai hasil yang diharapkan. Prinsip strategi adalah bahawa setiap kali harga meningkat sebanyak 1%, kita memegang pesanan pendek nilai tertentu (sebaliknya, kita memegang pesanan panjang), mengira pesanan beli dan jual terlebih dahulu. saya tidak akan menunjukkan kod sumber. mereka semua dikemas dalamGrid('XTZ', 100, 0.3, 1000, maker_fee=-0.00002, taker_fee=0.0003)
fungsi, parameter adalah: pasangan dagangan, harga menyimpang dari nilai pegangan 1%, ketumpatan pesanan menunggu adalah 0.3%, selang tidurms
, yuran pesanan yang belum selesai dan yuran pesanan yang dilaksanakan.
Harga pasaran XTZ
Kita mula-mula menguji kesan kedudukan pegangan yang berbeza pada pulangan keuntungan. pulangan yang diuji dengan mekanisme backtest tradisional pasti akan meningkat berbanding dengan peningkatan kedudukan pegangan.
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'])
Sebanyak empat kumpulan diuji semula, nilai kedudukan memegang adalah 100, 1000, 10000, 100,000, dan jumlah masa ujian semula adalah 1.3s. Hasilnya adalah seperti 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}
Ia dapat dilihat bahawa keuntungan yang diwujudkan akhir adalah masing-masing 28.4%, 27.5%, 26.9% dan 22.6% daripada nilai kedudukan pegangan. Ini juga selaras dengan keadaan sebenar. Semakin besar nilai kedudukan pegangan, semakin besar nilai pesanan yang menunggu, semakin besar kemungkinan transaksi separa akan berlaku, dan semakin kecil keuntungan yang diwujudkan akhir berbanding dengan jumlah pesanan yang menunggu. Carta berikut adalah perbandingan pulangan relatif nilai kedudukan masing-masing 100 dan 10000:
Kita juga boleh backtest kesan parameter yang berbeza pada pendapatan backtest, seperti ketumpatan pesanan yang menunggu, masa tidur, yuran transaksi, dll. Ambil masa tidur sebagai contoh, ubah menjadi 100ms, dan bandingkan masa tidur kepada 1000ms untuk melihat pulangan keuntungan. Hasil backtest adalah seperti 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, kerana strategi hanya menghantar satu set pesanan, beberapa pesanan tidak akan dapat melaksanakan harga turun naik kerana mereka tidak mempunyai masa untuk berubah, dan pengurangan masa tidur memperbaiki masalah ini.
Artikel ini secara inovatif mencadangkan sistem backtest baru berdasarkan aliran pesanan, yang boleh sebahagian mensimulasikan keadaan pencocokan pesanan yang tertunda, perintah pelaksanaan, pesanan pelaksanaan separa, kelewatan, dan lain-lain, dan sebahagiannya mencerminkan kesan jumlah dana strategi pada pendapatan. Untuk strategi frekuensi tinggi dan lindung nilai, Ia mempunyai nilai rujukan yang penting.