Давайте продолжим объяснение содержания последней главы (https://www.fmz.com/bbs-topic/9725).
Третья дополнительная функция:
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 ( \"\" Start Balance \"\", 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 ( \"\" Start Balance \"\", 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
и называет функциюexchange.GetAccount
Получить последние данные текущего счета и назначить его переменнойaccount
Тогда судите о переменной.account
. Если переменнаяnull
(например, тайм-аут, сеть, исключение интерфейса обмена и т. д.), он вернется (соответствующийif (!account) {...}
) непосредственно.
self.account = account
это назначить локальную переменнуюaccount
кaccount
атрибут построенного объекта для записи последней учетной информации в построенном объекте.
Var now = new Date().getTime ()
объявляет локальную переменнуюnow
и зоветgetTime()
Функция объекта JavaScript now
.
if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)){...}
определяет, что если разница между текущей временной меткой и временной меткой, записанной в последний раз, превышает параметрCalcNet Interval * 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
. Оценить, соответствует ли текущая общая чистая стоимость итоговой чистой стоимости, зафиксированной в последний раз:
if (net != self.preNet) {
self.preNet = net
LogProfit(net)
}
Если это не последовательно, то есть,net! = self.preNet
является истинным, обновить атрибутself.preNet
используется для записи чистой стоимости с переменнойnet
. Затем напечатайте общую чистую суммуnet
данные к графику кривой доходности робота платформы торговли FMZ QuantLogProfit
Функция может быть запрошена в документе FMZ API).
Если регулярная печать заработной платы не запускается, продолжайте следующий процесс для записиaccount.Stocks
(валюта, имеющаяся на текущем счете) иaccount.Balance
(валюта, имеющаяся на текущем счете) вself.BTC
иself.CNY
. Вычислить скалу смещения и записать задание вself.p
.
self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny)
Алгоритм также очень прост, который рассчитывает процент текущей стоимости валюты к общей чистой стоимости счета.
А как насчет того, чтобы судить, когда запустить баланс денег (позицию)?
Здесь, я беру 50% плюс или минус 2 процентных пункта в качестве буфера, и выполняет баланс за буфером, то есть, еслиself.p < 0.48
, денежный баланс запускается отклонением. Если денег меньше, цена будет расти на 0,01 каждый раз от позиции покупки при открытии рынка, и три небольших заказов будут организованы. Аналогично, денежный балансself.p > 0.52
, если валюты больше, продать один и выпустить небольшие заказы.Sleep(BalanceTimeout)
в течение определенного времени в соответствии с параметрами.
Var orders = exchange. Get Orders () # Get all current makers, with orders variable
If (orders) { # If the variable orders used to obtain the current order data is not null
for (var i = 0; i < orders.length; I + +) { # Loop through orders and cancel orders one by one
if (orders[i].Id != self.tradeOrderId) {
Exchange. CancelOrder (orders [I]. Id) # Call exchange. CancelOrder to cancel orders based on orders [I]. Id
}
}
}
Четвертая дополнительная функция:
В основной части стратегии, здесь приходит главная игра.self.poll = function(){...}
Как мы уже говорили в предыдущей статье, перед началомmain()
функция начинает выполнять и входит в бесконечныйwhile
цикл, мы используемvar reaper = LeeksReaper()
чтобы построить объект leeksreaper, а затем выполнить цикл вызоваreaper.poll()
вmain()
function.
Вself.poll
функция начинает выполнять, выполняя некоторые подготовительные работы перед каждой петлей.self.numTick++
увеличивает количество.self.updateTrades()
обновляет последние отчеты о торговле на рынке и рассчитывает соответствующие данные об использовании.self.updateOrderBook()
обновляет данные о заказах и рассчитывает соответствующие данные.self.balanceAccount()
проверить денежный баланс (позицию).
Var burstPrice = self. Prices [self. Prices. Length-1] * BurstThresholdPct # Calculate Burst Price
Var bull = false # Declare a bull-marked variable, initially false
Var bear = false # Declare a bear marked variable, initially false
Var tradeAmount = 0 # Declare the transaction amount variable, initially 0
Следующий шаг - судить о том, является ли текущий краткосрочный рынок быком или медведем.
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
, _.max
, иslice
используются в коде и легко понять.
· _. min
: Функция состоит в том, чтобы найти минимальное значение в массиве параметров.
· _.max
: Функция состоит в том, чтобы найти максимальное значение в массиве параметров.
· slice
Функция является функцией-членом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)) // it will intercept the elements from 4 to 1 and return a new array: [4,3,2,1]
}
Условия для оценки медвежьего или бычьего рынка:
· Введениеself.numTick > 2
должна быть истинной, то есть, когда новый раунд цены обнаружения начинается, он должен быть задействован после не менее трех раундов обнаружения, чтобы избежать запуска в начале.
· Разница между последними данными вself.prices
Последовательность цен, то есть последние данные, и максимальная или минимальная цена в предыдущем диапазоне вself.prices
Массив должен превышать взрывную ценуburstPrice
.
Если все условия верны, отметьтеbull
илиbear
как true, и присвоить значение переменнойtradeAmount
чтобы спланировать сделку со Студом.
Тогда, согласноself.vol
обновлен и рассчитан в предыдущемself.updateTrades()
Функция,BurstThresholdVol
параметр определяет, следует ли уменьшить интенсивность транзакции (уменьшить планируемый объем транзакции).
if (self.vol < BurstThresholdVol) {
TradeAmount * = self. Vol/BurstThresholdVol //Reduce the planned volume by self. Vol/BurstThresholdVol times of the previous volume
}
if (self.numTick < 5) {
TradeAmount * = 0.8 // reduced to 80% of the plan
}
If (self. NumTick < 10) { // reduce to 80% of the plan
tradeAmount *= 0.8
}
Далее, судите, соответствуют ли торговый сигнал и объем требованиям:
If ( (!Bull && !Bear) | | tradeAmount < MinStock) { # If it is not a bull market and not a bear market, or the amount tradeAmount planned to trade is less than the minimum trading volume MinStock set by the parameter, the poll function returns without trading operations directly
return
}
После вышесказанного приговора, исполнитеvar tradePrice = bull ? self.bidPrice: self.askPrice
устанавливает цену сделки в зависимости от того, является ли это медвежьим рынком или бычьим рынком, и присваивает стоимость с соответствующей ценой коносамента.
Наконец,while
вводится цикл, и единственное условие остановки цикла заключается в том, что планируемый объем торговлиtradeAmount > = MinStock
меньше минимального объема торговли.
В петле, заказ выполняется в соответствии с текущим состоянием рынка.orderId
. Sleep(200)
Затем петля определяет, будет ли заказ выполнен в течение 200 миллисекунд.orderId
если true (если заказ не удается, то ID заказа не будет возвращен, и условие if не будет задействовано). Если условие true.self.tradeOrderId
.
Заявление переменнойorder
используется для хранения данных о заказах с начальным значениемnull
. Затем данные заказа ID получаются в петле, и судить, является ли заказ состояние производителя, если да, заказ ID отменяется, а если нет, петля обнаружения завершается.
Var order = null // Declare a variable to hold the order data
While (true) { // a while loop
Order = exchange. GetOrder (orderId) // Call GetOrder to query the order data whose order ID is orderId
If (order) { // If the order data is queried and the query fails and the order is null, the current if condition will not be triggered
If (order. Status = = ORDER _ STATE _ PENDING) { // Judge whether the order status is maker
Exchange. CancelOrder (orderId) // If the order is maker, cancel the order
Sleep(200)
} else { // otherwise execute break to end the current while loop
break
}
}
}
Затем выполняется следующий процесс:
Self. TradeOrderId = 0 // Reset self. TradeOrderId.
TradeAmount-= order. DealAmount // Update tradeAmount, subtract the quantity of the order on the bill of lading that has been completed
TradeAmount * = 0.9 //Decrease the order amount
If (order. Status = = ORDER _ STATE _ CANCELED) { // if the order is already cancelled
Self. UpdateOrderBook () // Update data such as order book
While (bull & & self. BidPrice-tradePrice > 0.1) { // In a bull market, if the updated bill of lading price exceeds the current trading price by 0.1, the trading amount will be reduced and the trading price will be adjusted slightly
tradeAmount *= 0.99
tradePrice += 0.1
}
While (bear & & self. AskPrice-tradePrice < -0.1) { // In a bear market, if the updated bill of lading price exceeds the current trading price by 0.1, the trading amount will be reduced and the trading price will be adjusted slightly
tradeAmount *= 0.99
tradePrice -= 0.1
}
}
Когда процесс программы заканчивается циклwhile (tradeAmount > = MinStock){...}
, это означает, что процесс сделки с ценовым взрывом завершен.
Выполнитьself.numTick = 0
, то есть, сброситьself.numTick
до 0.
ВLeeksReaper()
Конструктор возвращаетself
объект в конце исполнения, то есть, когдаvar reaper = LeeksReaper()
, он возвращается наreaper
.
До сих пор мы проанализировали, какLeeksReaper()
Конструктор конструирует объект LeeksReaper, каждый метод объекта LeeksReaper и процесс исполнения основных логических функций. Я считаю, что вы будете иметь четкое понимание этого высокочастотного алгоритма стратегии после прочтения этой статьи.