Type/to search
8
Follow
1361
Followers
Анализ стратегии уборки лука-порея (2)
HFT
Created 2020-11-16 10:03:52  Updated 2024-12-05 22:03:01
 23
 8482

img

Анализ стратегии уборки лука-порея (2)

затемПредыдущее содержаниеобъяснять.

Третья добавленная функция:

python
self.balanceAccount = function() { var account = exchange.GetAccount() if (!account) { return } self.account = account var now = new Date().getTime() if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)) { self.preCalc = now var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks)) if (net != self.preNet) { self.preNet = net LogProfit(net) } } self.btc = account.Stocks self.cny = account.Balance self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny) var balanced = false if (self.p < 0.48) { Log("开始平衡", self.p) self.cny -= 300 if (self.orderBook.Bids.length >0) { exchange.Buy(self.orderBook.Bids[0].Price + 0.00, 0.01) exchange.Buy(self.orderBook.Bids[0].Price + 0.01, 0.01) exchange.Buy(self.orderBook.Bids[0].Price + 0.02, 0.01) } } else if (self.p > 0.52) { Log("开始平衡", self.p) self.btc -= 0.03 if (self.orderBook.Asks.length >0) { exchange.Sell(self.orderBook.Asks[0].Price - 0.00, 0.01) exchange.Sell(self.orderBook.Asks[0].Price - 0.01, 0.01) exchange.Sell(self.orderBook.Asks[0].Price - 0.02, 0.01) } } Sleep(BalanceTimeout) var orders = exchange.GetOrders() if (orders) { for (var i = 0; i < orders.length; i++) { if (orders[i].Id != self.tradeOrderId) { exchange.CancelOrder(orders[i].Id) } } } }

КонструкторLeeksReaper()При построении объекта добавьтеbalanceAccount()Функция заключается в обновлении информации об активах счета, хранящейся вself.account, то есть построенный объектaccountсвойство. Регулярно рассчитывайте и распечатывайте значение прибыли. Затем на основе последней информации об активах счета рассчитывается соотношение баланса спотовой валюты (баланс спотовой позиции). При срабатывании порога отклонения закрывается небольшой ордер для восстановления валюты (позиции) до сбалансированного состояния. Подождите определенный период времени для завершения транзакции, затем отмените все отложенные ордера. Следующий раунд выполнения этой функции снова проверит баланс и выполнит соответствующую обработку.

Давайте рассмотрим код этой функции построчно:
Первое предложениеvar account = exchange.GetAccount()Он объявляет локальную переменнуюaccountи вызовите интерфейс API Inventorexchange.GetAccount()Функция, получить последние данные текущего счета и назначить егоaccountпеременная. Тогда судитеaccountЭта переменная, если переменнаяnullЕсли значение (такое как тайм-аут, сеть, исключение интерфейса обмена и т. д.) не может быть получено, оно будет возвращено напрямую (соответствующееif (!account){...}здесь).

self.account = accountЭто предложение заключается в том, чтобы поместить локальную переменнуюaccountПрисвоено построенному объектуaccountАтрибуты используются для записи последней информации об учетной записи в созданный объект.

var now = new Date().getTime()Этот оператор объявляет локальную переменнуюnowи вызовите объект времени и даты языка JavaScriptgetTime()Функция возвращает текущую временную метку. Назначитьnowпеременная.

if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)) {...}Этот код определяет, превышает ли разница между текущей временной меткой и последней записанной временной меткой параметрCalcNetInterval * 1000Это означает, что с момента последнего обновления по настоящее время болееCalcNetInterval * 1000миллисекунда(CalcNetIntervalсекунд), чтобы достичь функции синхронизации печати дохода. Поскольку цена первой ставки используется при расчете дохода, условия также ограничиваютself.orderBook.Bids.length > 0Это условие (данные о глубине, в списке ордеров на покупку должна быть действительная информация о снастях). Когда срабатывает условие оператора if, выполнитьself.preCalc = nowОбновите переменную метки времени последнего дохода от печатиself.preCalcТекущая временная меткаnow. Статистика доходов здесь использует метод расчета чистой стоимости, код:var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks)), то есть конвертировать монету в деньги (знаменатель) в соответствии с текущей ценой покупки, а затем добавить ее к сумме денег на счете и присвоить ее объявленной локальной переменнойnet. Определите, соответствует ли текущая общая чистая стоимость общей чистой стоимости, зарегистрированной в прошлый раз:

python
if (net != self.preNet) { self.preNet = net LogProfit(net) }

Если они несовместимы,net != self.preNetЕсли правда, используйтеnetОбновления переменных используются для записи свойств чистой стоимости.self.preNet. Тогда распечатайте этоnetДанные об общем чистом капитале для графика кривой прибыли количественной торговой платформы-робота изобретателя (можно запросить в документе FMZ API)LogProfitэта функция).

Если запланированный доход от печати не сработал, продолжайте следующий процесс.account.Stocks(количество монет, доступных на текущем счете),account.Balance(Текущая сумма денег, имеющаяся на счете) записывается вself.btcself.cny. Рассчитайте коэффициент смещения и присвойте значение записи.self.p

python
self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny)

Алгоритм также очень прост: он заключается в расчете текущей стоимости монеты в процентах от общей чистой стоимости счета.

Так как же определить, когда срабатывает баланс денег (позиция)?
Автор использует 2 процентных пункта выше и ниже 50% в качестве буфера и выполняет балансировку за пределами буфера, то естьself.p < 0.48Срабатывает отклонение баланса монет, и считается, что монет стало меньше, поэтому начните покупать по позиции на рынке и увеличивайте цену на 0,01 каждый раз, и разместите три небольших ордера. Аналогично, валютный балансself.p > 0.52Если вы считаете, что у вас слишком много монет, вы можете разместить небольшой ордер, продав их по цене открытия. Наконец, подождите определенное время в соответствии с настройками параметров.Sleep(BalanceTimeout)После этого все заказы будут отменены.

python
var orders = exchange.GetOrders() # 获取当前所有挂单,存在orders变量 if (orders) { # 如果获取当前挂单数据的变量orders不为null for (var i = 0; i < orders.length; i++) { # 循环遍历orders,逐个取消订单 if (orders[i].Id != self.tradeOrderId) { exchange.CancelOrder(orders[i].Id) # 调用exchange.CancelOrder,根据orders[i].Id取消订单 } } }

Четвертая добавленная функция:

Основная часть стратегии, ее суть здесь,self.poll = function() {...}Функция — это основная логика всей стратегии. Мы также говорили о ней в предыдущей статье.main()Функция начинает выполняться и входитwhileПеред бесконечным циклом мы используемvar reaper = LeeksReaper()Построил объект для сбора лука-порея, а затемmain()Цикл вызова функцииreaper.poll()Это вызываемая функция.

self.pollФункция начинает выполняться и выполняет некоторую подготовительную работу перед каждым циклом.self.numTick++Увеличьте количество,self.updateTrades()Обновите последние записи рыночных транзакций и рассчитайте соответствующие данные.self.updateOrderBook()Обновите данные книги заказов и рассчитайте соответствующие данные.self.balanceAccount()Проверьте баланс денег (позиции).

python
var burstPrice = self.prices[self.prices.length-1] * BurstThresholdPct # 计算爆发价格 var bull = false # 声明牛市标记的变量,初始为假 var bear = false # 声明熊市标记的变量,初始为假 var tradeAmount = 0 # 声明交易数量变量,初始为0

Следующий шаг — определить, является ли текущий краткосрочный рынок бычьим или медвежьим.

python
if (self.numTick > 2 && ( self.prices[self.prices.length-1] - _.max(self.prices.slice(-6, -1)) > burstPrice || self.prices[self.prices.length-1] - _.max(self.prices.slice(-6, -2)) > burstPrice && self.prices[self.prices.length-1] > self.prices[self.prices.length-2] )) { bull = true tradeAmount = self.cny / self.bidPrice * 0.99 } else if (self.numTick > 2 && ( self.prices[self.prices.length-1] - _.min(self.prices.slice(-6, -1)) < -burstPrice || self.prices[self.prices.length-1] - _.min(self.prices.slice(-6, -2)) < -burstPrice && self.prices[self.prices.length-1] < self.prices[self.prices.length-2] )) { bear = true tradeAmount = self.btc }

Помните, в предыдущей статьеself.updateOrderBook()функция, в которой мы используем алгоритм средневзвешенного значения для построения временного ряда с порядкомpricesМножество. В этом коде используются три новые функции_.min_.maxsliceЭти три функции также очень просты для понимания.

  • _.min: Его функция — найти наименьшее значение в массиве параметров.

  • _.max: Его функция — найти наибольшее значение в массиве параметров.

  • slice: Эта функция является функцией-членом объекта массива JavaScript. Ее функция — перехват части массива в соответствии с индексом и возврат ее. Например:

    javascript
    function main() { // index .. -8 -7 -6 -5 -4 -3 -2 -1 var arr = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] Log(arr.slice(-5, -1)) // 会截取 4 ~ 1 这几个元素,返回一个新数组:[4,3,2,1] }

    img

Условия оценки медведей и быков здесь следующие:

  • self.numTick > 2Чтобы быть установленным, это означает, что когда начинается новый раунд цен обнаружения, он должен быть запущен как минимум после трех раундов обнаружения, чтобы избежать запуска в самом начале.
  • Цена серииself.pricesПоследние данные вself.pricesРазницу между максимальной и минимальной ценой в предыдущем диапазоне в массиве необходимо разорвать.burstPriceЭто цена взрыва.

Если все условия выполнены, то отметьтеbullилиbear,дляtrue, и датьtradeAmountНазначьте переменные и спланируйте сделки по продаже жеребцов.

Согласно предыдущемуself.updateTrades()Обновлено и рассчитано в функцииself.vol, для параметраBurstThresholdVolРешите, следует ли снизить интенсивность торговли (уменьшить размер планируемых сделок).

python
if (self.vol < BurstThresholdVol) { tradeAmount *= self.vol / BurstThresholdVol // 缩减计划交易量,缩减为之前量的self.vol / BurstThresholdVol 倍 } if (self.numTick < 5) { tradeAmount *= 0.8 // 缩减为计划的80% } if (self.numTick < 10) { // 缩减为计划的80% tradeAmount *= 0.8 }

Далее определите, соответствуют ли торговый сигнал и объем торгов требованиям:

python
if ((!bull && !bear) || tradeAmount < MinStock) { # 如果非牛市并且也非熊市,或者计划交易的量tradeAmount小于参数设置的最小交易量MinStock,poll函数直接返回,不做交易操作 return }

После вышеизложенного решения, исполнитьvar tradePrice = bull ? self.bidPrice : self.askPriceУстановите цену сделки в зависимости от того, идет ли речь о медвежьем или бычьем рынке, и назначьте стоимость по соответствующей цене коносамента.

Наконец введитеwhileЕдинственное условие остановки цикла —tradeAmount >= MinStockПланируемый объем транзакции меньше минимального объема транзакции.
В этом цикле ордера размещаются в зависимости от того, является ли текущий рынок бычьим или медвежьим. И запишите идентификатор заказа в переменнуюorderId. После каждого раунда заказаSleep(200)Подождите 200 миллисекунд. Тогда судите в курсеorderIdЯвляется ли это истинным (если заказ не будет выполнен, идентификатор заказа не будет возвращен и условие if не будет выполнено), если условие истинно. Получите идентификатор заказа и присвойте егоself.tradeOrderId

Объявите переменную для хранения данных заказаorderНачальное значение равноnull. Затем выполните цикл, чтобы получить данные заказа этого идентификатора, и определите, находится ли заказ в статусе отложенного заказа. Если он находится в статусе отложенного заказа, отмените заказ этого идентификатора. Если он не находится в статусе отложенного заказа, выйдите из этого контур обнаружения.

pine
var order = null // 声明一个变量用于保存订单数据 while (true) { // 一个while循环 order = exchange.GetOrder(orderId) // 调用GetOrder查询订单ID为 orderId的订单数据 if (order) { // 如果查询到订单数据,查询失败order为null,不会触发当前if条件 if (order.Status == ORDER_STATE_PENDING) { // 判断订单状态是不是正在挂单中 exchange.CancelOrder(orderId) // 如果当前正在挂单,取消该订单 Sleep(200) } else { // 否则执行break跳出当前while循环 break } } }

Затем следуйте процедуре, описанной ниже:

pine
self.tradeOrderId = 0 // 重置self.tradeOrderId tradeAmount -= order.DealAmount // 更新tradeAmount,减去提单的订单已经成交的数量 tradeAmount *= 0.9 // 减小下单力度 if (order.Status == ORDER_STATE_CANCELED) { // 如果订单已经是取消了 self.updateOrderBook() // 更新订单薄等数据 while (bull && self.bidPrice - tradePrice > 0.1) { // 牛市时,更新后的提单价格超过当前交易价格0.1就减小交易力度,略微调整交易价格 tradeAmount *= 0.99 tradePrice += 0.1 } while (bear && self.askPrice - tradePrice < -0.1) { // 熊市时,更新后的提单价格超过当前交易价格0.1就减小交易力度,略微调整交易价格 tradeAmount *= 0.99 tradePrice -= 0.1 } }

Когда поток программы выскакиваетwhile (tradeAmount >= MinStock) {...}Этот цикл свидетельствует о том, что процесс транзакции по взрывному росту цен завершен.
осуществлятьself.numTick = 0, то есть сбросself.numTickравно 0.

LeeksReaper()Конструктор наконец выполняетсяselfВозвращенный объект —var reaper = LeeksReaper()Когда его вернулиreaper

До сих порLeeksReaper()Мы проанализировали, как конструктор создает объект leek harvester, различные методы объекта leek harvester и процесс выполнения основных логических функций. Я считаю, что после прочтения этой статьи у вас должно быть более четкое представление о высокочастотном алгоритм стратегии процесса. понять.

Related Recommendations
Comment
All comments (19)

    感谢梦总。梦总,请问韭菜收割机跟草神的高频机器人两者结合的思路有没有搞头啊?

    4 years ago

    草神有篇文章讲过,高频需要有市场环境。策略而言韭菜收割机跟草神的高频机器人有思路上的共同点。

    4 years ago

    说了一堆废话。核心的一句都没讲。

    4 years ago

    实在抱歉,这个文章主要是给入门初学者讲执行流程的,讲了一堆废话确实扎眼了,您忽略就行了。

    4 years ago

    有一点不明白,为什么一定要保持币和钱的平衡,如果没有达到平衡,就得操作买和卖。之后过BalanceTimeout又取消订单,不再平衡,而是进入下一个爆发环节。

    5 years ago

    下单命令在哪里。。。

    5 years ago

    之前看的云里雾里,用了一阵FMZ,重新看了一遍。总结思路来说。这个策略的思路是:
    监控盘口价格异动,发现价格爆发,顺着趋势的方向,以交易量大小作为参照计算出梭哈百分比,进行梭哈交易。梭哈交易完以后不持仓,长期保持一个币钱平衡的状态。
    我说的对吗,梦总?嘿嘿。

    5 years ago

    great !~

    5 years ago

    请教梦总,程序不停的在平衡币和钱,这个功能出于什么考虑?去掉balanceAccount()程序会怎样发展?

    5 years ago

    原版韭菜收割机是有一个平衡模块,可以考虑去掉。具体影响不太清楚了。

    5 years ago

    感谢梦总,fmz真的是大宝库

    5 years ago

    不客气 ~

    5 years ago

    还是看不明白

    5 years ago

    ~囧~

    5 years ago

    BurstThresholdVol 这个参数是干嘛的?该怎么设置啊

    6 years ago

    爆发量,这个是策略参数,人为设置的,详细看下策略、文章,就知道这个变量控制什么了。

    6 years ago

    细节满满,看了1小时才勉强理解细节,赞

    6 years ago

    梦总666,研究明白后我能写出跟print money 一样的韭菜收割机么

    6 years ago

    原理应该是差不多吧

    6 years ago
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)