Continuemos explicando el contenido del último capítulo (https://www.fmz.com/bbs-topic/9725).
La tercera función añadida:
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)
}
}
}
}
Cuando el constructorLeeksReaper ()
construye un objeto, elbalanceAccount ()
La función añadida al objeto actualiza la información del activo de la cuenta almacenada enself.account
, es decir, elaccount
el valor de los ingresos y imprimirlo a tiempo. Luego, de acuerdo con la última información de los activos de la cuenta, calcular la relación de saldo de divisas de los puntos (saldo de posición de los puntos), al activar el umbral de compensación, cerrar la posición con un pequeño pedido, de modo que la moneda (posición) de nuevo al estado de equilibrio. Espera un cierto tiempo para negociar, luego cancele todos los fabricantes, la próxima ronda de ejecución de la función, se comprobará el saldo y hacer el procesamiento correspondiente de nuevo.
Veamos el código de esta función oración por oración:
En primer lugar, la primera frasevar account = exchange.GetAccount ()
declara una variable localaccount
y llama a la función deexchange.GetAccount
Obtener los datos más recientes de la cuenta corriente y asignarlo a la variableaccount
Entonces juzgue la variable.account
. Si la variable esnull
(por ejemplo, tiempo de espera, red, interfaz de intercambio excepción, etc.), volverá (correspondiente aif (!account) {...}
) directamente.
self.account = account
es asignar la variable localaccount
En elaccount
atributo del objeto construido para registrar la información de cuenta más reciente en el objeto construido.
Var now = new Date().getTime ()
declara una variable localnow
y llama a lagetTime()
función del objeto de fecha de tiempo del lenguaje JavaScript para devolver la marca de tiempo actual.now
.
if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)){...}
determina que si la diferencia entre la marca de tiempo actual y la marca de tiempo registrada la última vez excede el parámetroCalcNet Interval * 1000
, significa que se ha actualizado desde la última vez.CalcNetInterval * 1000
el número de milisegundos (CalcNetInterval
En el caso de las empresas de impresión, el precio de compra de una impresión se utiliza para calcular el ingreso.self.orderBook.Bids.length > 0
Cuando se activa la condición de la instrucción if, la instrucción de la instrucción de la instrucción de la instrucción de la instrucción de la instrucción de la instrucción de la instrucción de la instrucción de la instrucción de la instrucción de la instrucción de la instrucción de la instrucción de la instrucción de la instrucción se activa.self.PreCalc = now
se ejecuta para actualizar la variable de marca de tiempo de la declaración de impuestos impresa más recientementeself.preCalc
a la fecha y hora actualesnow
En este caso, el método de cálculo del valor neto se utiliza en las estadísticas de retorno.var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks))
, es decir, convertir la moneda en dinero (moneda denominada) de acuerdo con el precio de compra actual, y luego añadirlo a la cantidad de dinero en la cuenta y asignarlo a la variable local declaradanet
. Juzgar si el valor neto total actual es consistente con el valor neto total registrado la última vez:
if (net != self.preNet) {
self.preNet = net
LogProfit(net)
}
Si no es consistente, es decir,net! = self.preNet
es cierto, actualizar el atributo deself.preNet
utilizado para registrar el valor neto con la variablenet
. Luego imprima el total neto denet
datos a la curva de rendimiento del gráfico del robot de la plataforma de negociación FMZ QuantLogProfit
la función puede consultarse en el documento de la API FMZ).
Si la impresión regular de las ganancias no se activa, continúe el siguiente proceso para registrar las ganancias.account.Stocks
(moneda disponible en la cuenta corriente) y elaccount.Balance
(moneda disponible en la cuenta corriente) en elself.BTC
yself.CNY
. Calcular la escala de desplazamiento y registrar la asignación en elself.p
.
self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny)
El algoritmo también es muy simple, que es calcular el porcentaje del valor corriente de la moneda al valor neto total de la cuenta.
¿Qué pasa con juzgar cuándo activar el balance de dinero (posición)?
Aquí, tomo el 50% más o menos 2 puntos porcentuales como el búfer, y ejecuta el saldo más allá del búfer, es decir, si elself.p < 0.48
Si el dinero es menor, el precio aumentará en 0.01 cada vez desde la posición de compra en la apertura del mercado, y se organizarán tres órdenes pequeñas.self.p > 0.52
, si la moneda es más, vender uno y liberar pedidos pequeños.Sleep(BalanceTimeout)
durante un cierto tiempo de acuerdo con los parámetros.
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
}
}
}
La cuarta función añadida:
En la parte central de la estrategia, aquí viene la jugada principal.self.poll = function(){...}
En este sentido, la estrategia de la Unión Europea para el desarrollo de la economía de la Unión Europea (UE) se basa en el principio de subsidiariedad y en el principio de subsidiariedad.main()
la función comienza a ejecutarse y entra en el infinitowhile
Loop, usamosvar reaper = LeeksReaper()
para construir el objeto de leeksreaper, y luego ejecutar la llamada de bucle dereaper.poll()
En elmain()
function.
Elself.poll
La función comienza a ejecutarse, haciendo algún trabajo preparatorio antes de cada bucle.self.numTick++
El número de personas que se encuentran en el centro de la ciudad aumenta.self.updateTrades()
La Comisión Europea, por su parte, ha informado a los Estados miembros y a la Comisión sobre la aplicación de las normas de seguridad y seguridad en el trabajo.self.updateOrderBook()
La Comisión actualizará los datos de los pedidos y calculará los datos pertinentes.self.balanceAccount()
comprobar el saldo monetario (posición).
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
El siguiente paso es juzgar si el mercado a corto plazo actual es un toro o un oso.
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
}
¿Recuerdas elself.updateOrderBook()
función del artículo anterior donde usamos un algoritmo de promedio ponderado para construir un ordenado por tiempoprices
Tres nuevas funciones:_.min
, _.max
, yslice
Se utilizan en el código y son fáciles de entender.
· _. min
: La función es encontrar el valor mínimo en la matriz de parámetros.
· _.max
: La función es encontrar el valor máximo en la matriz de parámetros.
· slice
: La función es una función miembro de laJavaScript
Se utiliza para devolver una parte de la matriz de acuerdo con el índice. Por ejemplo:
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]
}
Las condiciones para juzgar el mercado bajista o alcista son:
· Elself.numTick > 2
El valor de la diferencia entre el valor de la diferencia entre el valor de la diferencia y el valor de la diferencia entre el valor de la diferencia y el valor de la diferencia entre el valor de la diferencia y el valor de la diferencia entre el valor de la diferencia y el valor de la diferencia.
· La diferencia entre los últimos datos de laself.prices
El precio máximo o mínimo en el rango anterior en el rango de precios de la serie de precios, es decir, los datos más recientes, y el precio máximo o mínimo en el rango anterior en el rango de precios de la serie de precios.self.prices
El precio de salida de la matriz debe exceder el precio de salida de la matriz.burstPrice
.
Si todas las condiciones son ciertas, marquebull
o bienbear
como verdadero, y asignar un valor a la variabletradeAmount
para planear la transacción de Stud.
Entonces, de acuerdo con elself.vol
Se han actualizado y calculado en el último año.self.updateTrades()
La función, elBurstThresholdVol
el parámetro determina si hay que reducir la intensidad de la transacción (reducir el volumen de transacción previsto).
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
}
A continuación, juzgue si la señal de negociación y el volumen cumplen con los requisitos:
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
}
Después de la sentencia anterior, ejecutarvar tradePrice = bull ? self.bidPrice: self.askPrice
fija el precio de la transacción en función de si se trata de un mercado bajista o de un mercado alcista, y asigna el valor con el precio del conocimiento de embarque correspondiente.
Por último, unawhile
Se introduce un bucle, y la única condición para detener el bucle es que el volumen de negociación previsto detradeAmount > = MinStock
es inferior al volumen mínimo de negociación.
En el bucle, la orden se ejecuta de acuerdo con el estado actual del mercado.orderId
. Sleep(200)
El circuito entonces determina si el orden de cada uno de los circuitos es el mismo que el orden de cada uno.orderId
si es verdad (si el orden falla, el ID de orden no será devuelto, y la condición de si no se activará). Si la condición es verdad. Obtener el ID de orden y asignarlo a laself.tradeOrderId
.
Declarar una variableorder
utilizado para almacenar datos de pedidos, con un valor inicial denull
. Luego se obtienen los datos de orden del ID en un bucle, y juzgar si el orden es el estado creador, si es así, el orden del ID se cancela, y si no, el bucle de detección se termina.
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
}
}
}
Luego se realiza el siguiente proceso:
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
}
}
Cuando el proceso del programa termina el bucle dewhile (tradeAmount > = MinStock){...}
, indica que la ejecución de este proceso de transacción de explosión de precios se ha completado.
Ejecutar elself.numTick = 0
, es decir, restablecer elself.numTick
hasta 0.
ElLeeksReaper()
constructor devuelve elself
objeto al final de la ejecución, es decir, cuandovar reaper = LeeksReaper()
, se devuelve areaper
.
Hasta ahora, hemos analizado cómo elLeeksReaper()
constructor construye el objeto LeeksReaper, cada método del objeto LeeksReaper, y el proceso de ejecución de las funciones lógicas principales. Creo que tendrá una comprensión clara de este proceso de algoritmo de estrategia de alta frecuencia después de leer este artículo.