Dalam artikel sebelumnya, kami menjalankan saringan awal mata wang pada platform DATADATA berdasarkan amplitud dan naik dan turun. Seterusnya, kami akan meneroka faktor utama dalam perdagangan grid - menetapkan bilangan grid. Bilangan grid menentukan kekerapan transaksi dan jumlah dana untuk setiap transaksi, yang seterusnya mempengaruhi jumlah pulangan dan tahap risiko perdagangan grid. Oleh itu, cara menetapkan bilangan grid secara munasabah untuk mencapai titik imbangan terbaik adalah isu penting yang perlu dipertimbangkan oleh setiap peniaga grid.
Terlalu sedikit grid: Jika bilangan grid ditetapkan terlalu kecil, selang antara grid akan menjadi lebih besar, yang bermaksud bahawa harga perlu turun naik lebih banyak untuk mencapai grid seterusnya. Walaupun jumlah urus niaga setiap grid lebih besar dan boleh menangkap keuntungan turun naik yang lebih besar, disebabkan peluang dagangan yang lebih sedikit, beberapa keuntungan yang dibawa oleh turun naik yang lebih kecil mungkin terlepas. Oleh itu, keuntungan keseluruhan mungkin lebih rendah daripada jangkaan.
Terlalu banyak grid: Apabila bilangan grid ditetapkan terlalu banyak, julat harga setiap grid adalah lebih kecil, peluang dagangan meningkat, dan jual beli boleh dilakukan dengan lebih kerap. Walau bagaimanapun, disebabkan jumlah modal yang kecil yang terlibat dalam setiap transaksi, strategi sedemikian sering memerlukan perdagangan frekuensi tinggi untuk membuat keuntungan. Ini dengan mudah boleh membawa kepada yuran transaksi yang lebih tinggi, dan perdagangan yang terlalu kerap boleh menjadikan turun naik pasaran yang kecil sebagai sumber utama keuntungan, dengan had atas keuntungan yang terhad.
Bilangan grid yang munasabah: Bilangan grid yang sesuai perlu mengambil kira turun naik pasaran, saiz akaun dan kekerapan dagangan yang dijangkakan. Apabila turun naik pasaran adalah tinggi, meningkatkan bilangan grid dengan sewajarnya boleh menangkap turun naik dengan lebih baik, manakala apabila dana besar, menetapkan bilangan grid yang lebih kecil boleh menghasilkan jumlah transaksi tunggal yang lebih tinggi dan mengurangkan tekanan yuran transaksi. Dengan mengimbangi jarak grid dan kos dagangan yang kerap, pulangan strategi dan kawalan risiko boleh dimaksimumkan.
Ciri teras perdagangan grid adalah untuk memperuntukkan dana kepada setiap selang dengan menetapkan berbilang selang grid. Apabila menentukan bilangan grid, anda perlu mengira selang antara setiap grid dan jumlah dana dalam setiap grid. Penetapan bilangan grid bukan sahaja mempengaruhi jumlah dana dalam setiap grid, tetapi juga menentukan julat harga belian dan jualan setiap grid.
Dana akaun merupakan faktor penting dalam menentukan bilangan grid. Dana akaun yang lebih besar membolehkan lebih banyak grid disediakan, manakala dana akaun yang lebih kecil memerlukan had pada bilangan grid untuk mengelakkan peruntukan dana yang terlalu tersebar, mengakibatkan jumlah dana yang terlalu kecil dalam setiap grid dan ketidakupayaan untuk membuat keuntungan dengan berkesan.
Selain itu, strategi pengurusan risiko perdagangan grid juga perlu mengambil kira penetapan bilangan grid. Terutama apabila pasaran turun naik dengan kuat, terlalu banyak grid boleh menyebabkan kerugian yang lebih besar, jadi bilangan grid harus dikawal dengan munasabah untuk mengelakkan perdagangan yang berlebihan.
Dalam aplikasi sebenar strategi perdagangan grid, terutamanya apabila mengoptimumkan keseimbangan antara bilangan grid dan kadar pulangan, DQL (Bahasa Pertanyaan Datadata) platform Datadata memberikan fleksibiliti yang hebat. DQL bukan sahaja menyokong pertanyaan, pemprosesan dan analisis data yang cekap, tetapi juga membantu pedagang mensimulasikan dan menguji belakang prestasi strategi perdagangan grid untuk mencari nombor grid yang paling sesuai dan konfigurasi parameter lain.
Melalui DQL, kami boleh mendapatkan data K-line sejarah dengan mudah daripada pelbagai bursa (seperti Binance) dan melaraskan strategi perdagangan grid berdasarkan data ini. Dengan cara ini, strategi perdagangan grid yang optimum boleh disaring dengan tepat mengikut persekitaran pasaran yang berbeza dan turun naik mata wang tertentu.
Sebelum kita mula menguji balik strategi perdagangan grid, kita perlu mendapatkan data pasaran untuk mata wang sasaran terlebih dahulu. Berikut ialah kod untuk menanyakan data K-line bagi mata wang tertentu daripada pangkalan data:
# 获取目标币种的K线数据
data = query("select * from klines.spot_1d where Exchange = 'Binance' and Symbol = '???_usdt' order by Time")
Terangkan:
???_usdt
) pada platform dagangan Binance (termasuk masa, harga pembukaan, harga tertinggi, harga terendah dan harga penutupan, dsb.). Ini menyediakan data asas untuk pelaksanaan strategi.Teras strategi perdagangan grid adalah untuk berdagang menggunakan kuantiti grid pratetap dan julat harga. Langkah-langkah khusus adalah seperti berikut:
Kira selang grid (jurang) dan jumlah transaksi setiap grid (notional):
Jarak grid (jurang): Dikira berdasarkan nisbah antara harga tertinggi dan terendah dalam pasaran. Formulanya adalah seperti berikut:
[
\text{gap} = \frac{\log(\text{max_p} / \text{min_p})}{\text{grid_num}}
]
dalam,max_p
Untuk harga tertinggi,min_p
Untuk harga terendah,grid_num
ialah bilangan grid.
Jumlah urus niaga setiap grid (nosional):Jumlah urus niaga setiap grid dikira mengikut jumlah dana dan bilangan grid. Formulanya ialah: [ \text{notional} = \frac{\text{balance}}{\text{grid_num}} ]
Harga permulaan dan akhir grid:
exp(gap)
, dan seterusnya.Operasi Perdagangan:
Yuran Transaksi: Dengan mengandaikan yuran pengendalian bagi setiap transaksi ialah 0.0001, kami perlu mengira dan mengumpul yuran pengendalian bagi setiap transaksi.
def grid_trading_strategy(
raw,
grid_num, # 网格数量
min_p, # 最低价格
max_p, # 最高价格
):
"""
执行网格交易策略的函数
"""
# 初始化变量
balance = 1000 # 初始资金
raw = raw[['Time', 'Open', 'High', 'Low', 'Close']] # 只选择相关列
# 网格交易策略的设置
gap = math.log(max_p / min_p) / grid_num # 计算网格间隔
notional = balance / grid_num # 每个网格的交易额
# 初始化网格
net = []
for i in range(grid_num):
net.append({
'start_p': min_p * math.exp(i * gap), # 每个网格的起始价格
'end_p': min_p * math.exp((i + 1) * gap), # 每个网格的结束价格
'amt': notional / (min_p * math.exp(i * gap)), # 每个网格的购买量
'status': 'idle' # 初始状态为闲置
})
# 记录状态
state = {
'stock': 0, # 当前持仓
'fee': 0, # 交易费用
'longTradeVol': 0, # 长期交易量
'shortTradeVol': 0, # 短期交易量
'profitTbl': [], # 存储每个时刻的利润
'feeTbl': [], # 存储每个时刻的费用
'netCnt': 0, # 记录净交易次数
'idx': 0 # 当前数据的索引
}
# 检查开盘交易
def check_open_orders(state, net):
for i in range(len(net)):
if net[i]['status'] == 'idle' and raw['Low'][state['idx']] <= net[i]['start_p'] and raw['Open'][state['idx']] > net[i]['start_p']:
net[i]['status'] = 'taken' # 网格被占用
tradeVol = net[i]['amt'] * net[i]['start_p']
state['stock'] += net[i]['amt']
state['longTradeVol'] += tradeVol
state['fee'] += tradeVol * 0.0001 # 假设手续费为0.0001
# 检查平仓交易
def check_close_orders(state, net):
for i in range(len(net)):
if net[i]['status'] == 'taken' and raw['High'][state['idx']] >= net[i]['end_p'] and raw['Open'][state['idx']] < net[i]['end_p']:
net[i]['status'] = 'idle' # 网格状态恢复为空闲
tradeVol = net[i]['amt'] * net[i]['end_p']
state['stock'] -= net[i]['amt']
state['shortTradeVol'] += tradeVol
state['fee'] += tradeVol * 0.0001 # 假设手续费为0.0001
state['netCnt'] += 1
# 日志记录利润和费用
def log(state):
addVol = state['stock'] * raw['Close'][state['idx']] # 当前仓位的总价值
pl = state['shortTradeVol'] - state['longTradeVol'] + addVol # 计算利润
state['profitTbl'].append(pl)
state['feeTbl'].append(state['fee'])
# 主交易循环
for i in range(len(raw)):
state['idx'] = i
if raw['Close'][state['idx']] >= raw['Open'][state['idx']]:
check_open_orders(state, net)
check_close_orders(state, net)
else:
check_close_orders(state, net)
check_open_orders(state, net)
log(state)
# 将利润和费用数据整理为DataFrame
pl = DataFrame({'pl' : state['profitTbl'], 'fee' : state['feeTbl']})
pl['time'] = raw['Time']
pl['pl-net'] = pl['pl'] - pl['fee']
return pl
Untuk mata wang sasaran, kami memilih mata wang ‘oax_usdt’ Selepas menyemak kod dalam artikel sebelumnya, mata wang ini mengekalkan amplitud yang tinggi untuk jangka masa yang panjang tanpa menunjukkan arah aliran unilateral yang ketara. Contohnya, dengan mengira untung bersih (pl-net) untuk setiap nombor grid, kita boleh menilai nombor grid yang boleh membawa pulangan terbaik dalam persekitaran pasaran semasa. Berikut ialah kod untuk menjalankan backtest:
grid_nums = [5*i+5 for i in range(5)]
out = []
for g in grid_nums:
pl = grid_trading_strategy(
data,
grid_num=g,
min_p=min(data['Close']),
max_p=max(data['Close'])
)
out.append({
'num': g,
'pl-net': pl['pl-net'][-1],
'min_pl': min(pl['pl-net']),
'max_pl': max(pl['pl-net'])
})
return out
Selepas ujian belakang dengan konfigurasi nombor grid yang berbeza, kami memperoleh keputusan berikut:
Analisis:
Menetapkan bilangan grid dengan betul adalah tugas penting dalam strategi perdagangan grid. Dengan mengoptimumkan bilangan grid, prestasi keuntungan strategi perdagangan grid boleh dipertingkatkan dengan berkesan dan risiko boleh dikawal dengan lebih baik. Artikel ini menganalisis tetapan nombor grid dan menyediakan kaedah pengiraan dan kod sampel khusus, dengan harapan dapat membantu semua orang mengoptimumkan strategi perdagangan grid dan meningkatkan kestabilan dan keuntungan strategi.
Nota: Kod ujian belakang grid dalam artikel ini disesuaikan daripada Zhihu Da Shen Halcyon, sila rujuk artikel untuk penjelasan kod sumberDiari Amalan Perdagangan Algoritma (XVIII) - Butiran dalam Perdagangan Grid: Hubungan antara Nombor Grid dan Pulangan Jangka Panjang。