В предыдущей статье мы провели предварительный скрининг валют на платформе DATADATA на основе амплитуды и роста и падения. Далее мы рассмотрим ключевой фактор в торговле сетками — установление количества сеток. Количество сеток определяет частоту транзакций и объем средств по каждой транзакции, что в свою очередь влияет на общую доходность и уровень риска торговли в сетках. Поэтому то, как разумно установить количество сеток для достижения наилучшей точки баланса, является важным вопросом, который должен учитывать каждый трейдер сеток.
Слишком мало сеток: Если количество сеток слишком мало, интервалы между сетками будут больше, а это значит, что цене придется колебаться сильнее, чтобы достичь следующей сетки. Хотя объем транзакций в каждой сетке больше и может обеспечить большую прибыль от колебаний, из-за меньшего количества торговых возможностей часть прибыли, полученной в результате небольших колебаний, может быть упущена. Поэтому общая рентабельность может оказаться ниже ожидаемой.
Слишком много сеток: Если количество сеток слишком велико, диапазон цен каждой сетки становится меньше, торговые возможности увеличиваются, а покупки и продажи могут осуществляться чаще. Однако из-за небольшого объема капитала, вовлеченного в каждую сделку, такие стратегии часто требуют высокочастотной торговли для получения прибыли. Это может легко привести к повышению комиссий за транзакции, а слишком частая торговля может сделать небольшие колебания рынка основным источником прибыли, при этом верхний предел прибыли будет ограничен.
Разумное количество сеток: Соответствующее количество сеток должно учитывать волатильность рынка, размер счета и ожидаемую частоту торговли. Когда волатильность рынка высока, соответствующее увеличение количества сеток может лучше улавливать колебания, в то время как при больших объемах средств установка меньшего количества сеток может привести к более высоким суммам отдельных транзакций и снижению давления на комиссию за транзакции. Путем балансировки шага сетки и стоимости частой торговли можно максимизировать доходность стратегии и контроль рисков.
Основной особенностью торговли сеткой является распределение средств по каждому интервалу путем установки нескольких интервалов сетки. При определении количества сеток сначала необходимо рассчитать интервал между каждой сеткой и сумму средств в каждой сетке. Настройка количества сеток влияет не только на объем средств в каждой сетке, но и определяет диапазон цен покупки и продажи каждой сетки.
Денежные средства на счете являются важным фактором при определении количества сеток. Более крупные средства на счетах позволяют создавать больше сеток, в то время как меньшие средства на счетах требуют ограничения на количество сеток, чтобы избежать слишком рассредоточенного распределения средств, что приводит к слишком малому объему средств в каждой сетке и невозможности эффективного получения прибыли.
Кроме того, стратегия управления рисками сетевой торговли также должна учитывать установленное количество сетей. Особенно когда рынок подвержен резким колебаниям, слишком большое количество сеток может привести к большим потерям, поэтому количество сеток следует разумно контролировать, чтобы избежать чрезмерной торговли.
При реальном применении стратегий сетевой торговли, особенно при оптимизации баланса между количеством сеток и нормой прибыли, DQL (язык запросов Datadata) платформы Datadata обеспечивает большую гибкость. DQL не только поддерживает эффективный запрос, обработку и анализ данных, но и помогает трейдерам моделировать и тестировать на исторических данных эффективность стратегий торговли сеткой, чтобы найти наиболее подходящее число сетки и другие конфигурации параметров.
С помощью DQL мы можем легко получить исторические данные K-line с нескольких бирж (например, Binance) и скорректировать стратегии торговли на основе этих данных. Таким образом, можно точно подобрать оптимальную стратегию сетевой торговли с учетом различных рыночных условий и волатильности конкретных валют.
Прежде чем приступить к бэктестингу нашей стратегии сетевой торговли, нам необходимо получить рыночные данные по целевой валюте. Ниже приведен код для запроса данных K-строки указанной валюты из базы данных:
# 获取目标币种的K线数据
data = query("select * from klines.spot_1d where Exchange = 'Binance' and Symbol = '???_usdt' order by Time")
Объяснение:
???_usdt
) на торговой платформе Binance (включая время, цену открытия, максимальную цену, минимальную цену и цену закрытия и т. д.). Это обеспечивает основные данные для реализации стратегии.Суть стратегии торговли по сетке заключается в торговле с использованием заранее заданного количества и ценового диапазона сетки. Конкретные шаги следующие:
Рассчитайте интервал сетки (разрыв) и сумму транзакции на сетку (условную):
Интервал сетки (зазор): Рассчитывается на основе соотношения самой высокой и самой низкой цены на рынке. Формула выглядит следующим образом:
[
\text{gap} = \frac{\log(\text{max_p} / \text{min_p})}{\text{grid_num}}
]
в,max_p
По самой высокой цене,min_p
По самой низкой цене,grid_num
— это количество сеток.
Сумма транзакции по сетке (условная):Сумма транзакции каждой сетки рассчитывается по общему объему средств и количеству сеток. Формула такова: [ \text{notional} = \frac{\text{balance}}{\text{grid_num}} ]
Начальные и конечные цены сети:
exp(gap)
, и так далее.Торговые операции:
Комиссии за транзакции: Предполагая, что комиссия за обработку каждой транзакции составляет 0,0001, нам необходимо рассчитать и суммировать комиссию за обработку каждой транзакции.
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
В качестве целевой валюты мы выбираем валюту ‘oax_usdt’. После проверки кода в предыдущей статье эта валюта сохраняет высокую амплитуду в течение длительного периода времени, не показывая существенного одностороннего тренда. Мы можем попробовать использовать разные номера сетки (например: 5, 10, 15 и т. д.) для имитационного бэктестинга, чтобы увидеть эффекты разных номеров сетки, а затем найти подходящий номер сетки. Например, рассчитав чистую прибыль (pl-net) для каждого номера сетки, мы можем оценить, какие номера сетки могут принести наилучшую прибыль в текущих рыночных условиях. Вот код для запуска бэктеста:
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
После бэктестинга с различными конфигурациями номеров сетки мы получили следующие результаты:
Анализ:
Правильная настройка количества сеток является важной задачей в стратегии сетевой торговли. Оптимизировав количество сеток, можно существенно повысить прибыльность стратегий сетевой торговли и лучше контролировать риски. В этой статье анализируются настройки номеров сетки и приводятся конкретные методы расчета и примеры кодов, которые помогут каждому оптимизировать стратегии торговли сеткой и повысить стабильность и прибыльность стратегий.
Примечание: Код бэктестинга сетки в этой статье адаптирован из Zhihu Da Shen Halcyon, пожалуйста, обратитесь к статье для получения объяснения исходного кода.Дневник практики алгоритмической торговли (XVIII) - Подробности в сетевом трейдинге: взаимосвязь между номером сетки и долгосрочной доходностью。