В предыдущей статье мы вместе разработали простую стратегию хеджирования, а теперь мы узнаем, как ее модернизировать. Изменения в стратегии не будут значительными, однако детали изменения требуют внимания.
A交易所->B交易所
,B交易所->A交易所
Если мы используем прямой диапазон, то мы можем использовать горизонтальный диапазон, который запускает диапазон.画线类库
Мы также учимся использовать FMZ, потому что это очень просто и удобно.模版类库
Функции.В следующий раз мы будем реализовывать эти проекты поэтапно.
Использование кода для переключения на реальную рыночную дисковую систему.exchanges[i].IO
, вводить параметрыtrade_normal
Переход на рычаг, передачаtrade_super_margin
Переход на полный рычаг, не поддерживается повторное измерение.
Вmain
Приготовление к началу функции увеличивается:
// 切换杠杆模式
for (var i = 0 ; i < exchanges.length ; i++) { // 遍历检测所有添加的交易所对象
if (exchanges[i].GetName() == "Binance" && marginType != 0) { // 如果当前i索引代表的交易所对象是币安现货,并且策略界面参数marginType选择的不是「普通币币」选项,执行切换
if (marginType == 1) {
Log(exchanges[i].GetName(), "设置为杠杆逐仓")
exchanges[i].IO("trade_normal")
} else if (marginType == 2) {
Log(exchanges[i].GetName(), "设置为杠杆全仓")
exchanges[i].IO("trade_super_margin")
}
}
}
Здесь в политику добавлен только код для маневренной маневренной маневренной маневренной маневренной маневренной маневренной маневренной маневренной маневренной маневренной маневренной маневренной маневренной маневренной маневренной маневренной маневренной маневренной маневренной маневренной маневки.
Использование уже упакованных шаблонов очень просто.画线类库
На сайте FMZ можно найти информацию прямо на платформе FMZ.
Например, вы можете посмотреть на видео, сделанное на веб-сайте Facebook.https://www.fmz.com/strategy/27293На странице копирования этой формы можно перейти к следующему:
Нажатие кнопки позволяет скопировать эту библиотеку шаблонов в свою собственную библиотеку стратегий.
Затем на странице редактирования стратегии в панели шаблонов вы можете выбрать нужную библиотеку шаблонов. После набора вы можете сохранить политику, которая ссылается на эту модель. Это просто краткое описание использования библиотеки шаблонов, которая уже ссылается на эту модель, поэтому не нужно повторять действия.画线类库
Например, вы можете написать, что у вас есть опыт работы в сфере телевидения.
Мы учимся использовать их.画线类库
Функция для рисования.
Мы планируемA->B
Посмотрите на это.B->A
Для того, чтобы изобразить разницу, необходимо нарисовать две линии (настоящая разница от A до B, от B до A), две горизонтальные линии (начальная разница), как обычно.
Мы создаем односторонние хеджировки.A->B
иB->A
Если вы не можете использовать дизайн, описанный в предыдущей статье, вы не можете использовать этот дизайн.
В предыдущей статье:
var targetDiffPrice = hedgeDiffPrice
if (diffAsPercentage) {
targetDiffPrice = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentage
}
Только одна разница в ценеtargetDiffPrice
Я не знаю.
Так что здесь мы должны изменить код, сначала изменить параметры.
Но я не могу сказать, что это было так просто.
var targetDiffPriceA2B = hedgeDiffPriceA2B
var targetDiffPriceB2A = hedgeDiffPriceB2A
if (diffAsPercentage) {
targetDiffPriceA2B = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentageA2B
targetDiffPriceB2A = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentageB2A
}
Это означает, что цены на продукты будут расти в зависимости от того, что вы покупаете.targetDiffPrice
Один из них превратился в два.targetDiffPriceA2B
、targetDiffPriceB2A
Я не знаю.
Далее можно использовать функцию DrawLine в библиотеке DrawLine, чтобы нарисовать данные на графике.
// 画图
$.PlotHLine(targetDiffPriceA2B, "A->B") // 该函数第一个参数是水平线在Y轴方向上的值,第二个参数是显示文本
$.PlotHLine(targetDiffPriceB2A, "B->A")
Посмотрите на график, показывающий, что стратегия работает.
Далее рисуется кривая дифференциации в режиме реального времени, чтобы избежать избыточного рисования.
if (ts - lastKeepBalanceTS > keepBalanceCyc * 1000) {
nowAccs = _C(updateAccs, exchanges)
var isBalance = keepBalance(initAccs, nowAccs, [depthA, depthB])
cancelAll()
if (isBalance) {
lastKeepBalanceTS = ts
if (isTrade) {
var nowBalance = _.reduce(nowAccs, function(sumBalance, acc) {return sumBalance + acc.Balance}, 0)
var initBalance = _.reduce(initAccs, function(sumBalance, acc) {return sumBalance + acc.Balance}, 0)
LogProfit(nowBalance - initBalance, nowBalance, initBalance, nowAccs)
isTrade = false
}
}
$.PlotLine("A2B", depthA.Bids[0].Price - depthB.Asks[0].Price) // 画实时差价曲线
$.PlotLine("B2A", depthB.Bids[0].Price - depthA.Asks[0].Price) // 第一个参数是曲线名称,第二个参数是曲线当前时刻的值,即当前时刻Y轴方向上的值
}
Таким образом, графический код содержит всего четыре строки, что позволяет показать график при выполнении политики.
В статье упоминается, что триггерная линия была преобразована в две линии, контролируемые друг другом.A->B
В то же время, многие из них не хотят, чтобы они были в центре внимания.B->A
В этом случае не используется предыдущий алгоритм ценообразования, а используется способ сдвига цены с расчета.
if (depthA.Bids[0].Price - depthB.Asks[0].Price > targetDiffPriceA2B && Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount) >= minHedgeAmount) { // A -> B 盘口条件满足
var priceSell = depthA.Bids[0].Price - slidePrice
var priceBuy = depthB.Asks[0].Price + slidePrice
var amount = Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount)
if (nowAccs[0].Stocks > minHedgeAmount && nowAccs[1].Balance * 0.8 / priceSell > minHedgeAmount) {
amount = Math.min(amount, nowAccs[0].Stocks, nowAccs[1].Balance * 0.8 / priceSell, maxHedgeAmount)
Log("触发A->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[1].Balance * 0.8 / priceSell, nowAccs[0].Stocks) // 提示信息
hedge(exB, exA, priceBuy, priceSell, amount)
cancelAll()
lastKeepBalanceTS = 0
isTrade = true
}
} else if (depthB.Bids[0].Price - depthA.Asks[0].Price > targetDiffPriceB2A && Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount) >= minHedgeAmount) { // B -> A 盘口条件满足
var priceBuy = depthA.Asks[0].Price + slidePrice
var priceSell = depthB.Bids[0].Price - slidePrice
var amount = Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount)
if (nowAccs[1].Stocks > minHedgeAmount && nowAccs[0].Balance * 0.8 / priceBuy > minHedgeAmount) {
amount = Math.min(amount, nowAccs[1].Stocks, nowAccs[0].Balance * 0.8 / priceBuy, maxHedgeAmount)
Log("触发B->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[0].Balance * 0.8 / priceBuy, nowAccs[1].Stocks) // 提示信息
hedge(exA, exB, priceBuy, priceSell, amount)
cancelAll()
lastKeepBalanceTS = 0
isTrade = true
}
}
Так как цена покупки и продажи разделена на две цифры, то для хеджированияhedge
Но это не означает, что мы не можем изменить ситуацию.
function hedge(buyEx, sellEx, priceBuy, priceSell, amount) {
var buyRoutine = buyEx.Go("Buy", priceBuy, amount)
var sellRoutine = sellEx.Go("Sell", priceSell, amount)
Sleep(500)
buyRoutine.wait()
sellRoutine.wait()
}
Есть также некоторые мелкие корректировки на основе этих изменений, которые не описаны здесь.
Добавить взаимодействие в стратегию, чтобы она могла в реальном времени изменять триггерную линию разницы. Это необходимо для разработки полуавтоматической стратегии, которая также реализована здесь в качестве демонстрации обучения. Дизайн взаимодействия с политикой также очень прост: сначала на странице редактирования политики добавьте ей интерактивные элементы.
Добавлены два контроля, один называется A2B, другой называется B2A. После ввода числа в поле ввода контроля нажмите кнопку ввода справа.123
НажмитеA2B
Эта кнопка сразу же отправляет инструкции в политику.
A2B:123
Дизайн интерактивного обнаружения и обработки кода в стратегическом коде.
// 交互
var cmd = GetCommand() // 每次循环执行到这里时,都检测有没有交互指令过来,没有则返回空字符串
if (cmd) { // 检测到有交互指令,例如:A2B:123
Log("接收到命令:", cmd)
var arr = cmd.split(":") // 拆分出交互控件名称和输入框中的值,arr[0]就是A2B,arr[1]就是123
if (arr[0] == "A2B") { // 判断触发的交互控件是不是A2B
Log("修改A2B的参数,", diffAsPercentage ? "参数为差价百分比" : "参数为差价:", arr[1])
if (diffAsPercentage) {
hedgeDiffPercentageB2A = parseFloat(arr[1]) // 修改触发差价线
} else {
hedgeDiffPriceA2B = parseFloat(arr[1]) // 修改触发差价线
}
} else if (arr[0] == "B2A") { // 检测到触发的控件是B2A
Log("修改B2A的参数,", diffAsPercentage ? "参数为差价百分比" : "参数为差价:", arr[1])
if (diffAsPercentage) {
hedgeDiffPercentageA2B = parseFloat(arr[1])
} else {
hedgeDiffPriceB2A = parseFloat(arr[1])
}
}
}
Это позволяет более упорядочить и легко наблюдать данные, отображаемые в статусе.
var tbl = {
"type" : "table",
"title" : "数据",
"cols" : ["交易所", "币", "冻结币", "计价币", "冻结计价币", "触发差价", "当前差价"],
"rows" : [],
}
tbl.rows.push(["A:" + exA.GetName(), nowAccs[0].Stocks, nowAccs[0].FrozenStocks, nowAccs[0].Balance, nowAccs[0].FrozenBalance, "A->B:" + targetDiffPriceA2B, "A->B:" + (depthA.Bids[0].Price - depthB.Asks[0].Price)])
tbl.rows.push(["B:" + exB.GetName(), nowAccs[1].Stocks, nowAccs[1].FrozenStocks, nowAccs[1].Balance, nowAccs[1].FrozenBalance, "B->A:" + targetDiffPriceB2A, "B->A:" + (depthB.Bids[0].Price - depthA.Asks[0].Price)])
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
Реакция - это только тест-стратегия, предварительная функция обнаружения, многие БУГы на этапе реакции могут быть протестированы. Не нужно слишком заботиться о результатах реакции, в конечном итоге стратегия все еще требует реального оружия, который должен быть обнаружен в реальной среде.
Источник стратегии:https://www.fmz.com/strategy/302834
15570686905Эта стратегия заключается в том, чтобы добавить контрактную функцию, и это хорошо, потому что мы можем добавить постоянные контракты, контракты на процентные ставки.
Легкие облака.Ошибка: Не удалось прочитать свойство 'SetPrecision' undefined
Стратегия хеджирования наличности в различных валютах Ver1.1
Изобретатели количественного измерения - мечтыХорошо, у меня есть возможность преподать уроки.
Легкие облака.Понимаю, спасибо, Дмитрий.
Изобретатели количественного измерения - мечтыДобавить два обменных объекта.