A estratégia de comércio de redes
(www.fmz.com)
A ideia básica da negociação em rede é muito direta. Em vez de colocar um comércio, colocamos vários negócios formando um padrão de rede. Normalmente, estes são inseridos como ordens
O que é o comércio de redes e como funciona? A negociação em rede é um jogo sobre a volatilidade do mercado. Há duas razões pelas quais é favorecida pelos traders. A primeira é que não requer que você tenha uma previsão definitiva sobre a direção do mercado.
A segunda é que funciona bem em mercados voláteis, onde não há uma tendência clara. Estas condições são muito comuns nos mercados de divisas.
A negociação em grade é um tipo de negociação de análise técnica que se baseia no movimento dentro de padrões específicos de grade. A negociação em grade é popular na negociação de câmbio.
Grade pode personalizar a direção
Operação comercial básica: comprar primeiro e depois vender.
A rede começará a enviar ordens de compra no preço que está abaixo do primeiro preço, que é o preço seguido pelo primeiro preço (segundo último preço de compra, terceiro último preço de compra...e assim por diante). Cada ordem de compra é separada pelo parâmetro
Após qualquer ordem de compra é concluída, o programa será com base no preço de compra, adicionar o preço do parâmetro
Vender em curto primeiro e depois comprar para cobrir: a operação é exatamente o oposto
O maior risco desta estratégia é quando a tendência do mercado é unilateral e as flutuações de preços excedem a grelha.
O código a seguir fez a grade com perda automática de parada e função de movimento.
Observações:
A estratégia usa um projeto de ordem pendente virtual, que fornece uma grande quantidade de processamento para a troca para limitar o número de ordens pendentes e resolve o problema de forma flexível.
A lógica da grade é flexível em design e inteligente em estrutura.
Cálculo de lucro e perda, cada algoritmo estatístico numérico pode ser usado como referência e cada projeto de detecção de condição é rigoroso. (para minimizar a possibilidade de BUG)
O código fonte vale muito a pena ser aprendido.
Para mais informações, consulte:
https://www.fmz.com/strategy/112633
Código de origem:
// Código de origem: /* Parâmetros de interface (indicados como variáveis globais no código) OpType Grid Direção Caixa suspensa (selecionada) Compre primeiro e depois venda. FirstPriceAuto preço inicial automático booleano (verdadeiro/falso) verdadeiro FirstPrice@!FirstPriceAuto preço inicial numérico (número) 100 Todos Número total Número numérico (número) 10 PriceGrid Intervalo numérico (número) 1 Preço diferencial numérico (número) 2 quantidade Tipo de ordem tamanho caixa suspensiva (selecionado) comprar e vender a mesma quantidade Número (número) da quantidade de transacção única 0.1 BAmountOnce@AmountType==1 Ordem de compra Tamanho numérico (número) 0.1 SAmountOnce@AmountType==1 Tamanho numérico da ordem de venda (número) 0.1 AmountCoefficient@AmountType==0 Diferença de quantidade Corda (corda) *1 AmountDot Número com ponto decimal 3 AtivarProtectDiff Ativar a proteção da propagação Booleano (verdadeiro/falso) falso ProtectDiff@EnableProtectDiff Propagação de entrada Proteção de preço numérica (número) 20 CancelAllWS stop cancela todas as ordens pendentes Booleano (verdadeiro/falso) verdadeiro CheckInterval número de intervalo numérico (número) 2000 Intervalo de falha de reatendimento (número) 1300 RestoreProfit restaura o último lucro Booleano (verdadeiro/falso) falso LastProfit@RestoreProfit Último lucro numérico (número) 0 ProfitAsOrg@RestoreProfit Último lucro contado como preço médio Booleano (verdadeiro/falso) falso EnableAccountCheck habilitar verificação de saldo booleano (verdadeiro/falso) verdadeiro EnableStopLoss@EnableAccountCheck aberto Stop Loss Booleano (verdadeiro/falso) falso StopLoss@EnableStopLoss perda flutuante máxima numérica (número) 100 StopLossMode@EnableStopLoss Operação de perda pós-parada Caixa suspensa (selecionada) Reciclar e sair EnableStopWin@EnableAccountCheck Ativar Take Profit Booleano (verdadeiro/falso) falso StopWin@EnableStopWin Lucro flutuante máximo Tipo de número (número) 120 StopWinMode@EnableStopWin caixa suspensa de operação pós-tomada de lucro (selecionada) Reciclar e sair. AutoMove@EnableAccountCheck autoMove Boolean (verdadeiro/falso) falso MaxDistance@AutoMove distância máxima numérica (número) 20 MaxIdle@AutoMove (segundos) numérico (número) 7200 EnableDynamic Gira em ordens pendentes dinâmicas Boolean (verdadeiro/falso) falso DynamicMax@EnableDynamic Distância de expiração da ordem Número (número) 30 ResetData limpa todos os dados na inicialização Boolean (verdadeiro/falso) verdadeiro Precisão do preço comprimento decimal numérico (número) 5 */
função hasOrder ((ordens, orderId) { // Verifique se há uma ordem com ID de ordem em ordens de parâmetros para (var i = 0; i < ordens.length; i++) { // Traverse ordens para verificar se existem ids iguais, se houver, em seguida, retornar verdadeiro se (ordens[i].Id == orderId) { retornar verdadeiro; - Não. - Não. retornar falso; // Todos atravessados, sem gatilho se significa não encontrou a ordem com o ID de ordemId, retornar falso - Não.
função cancelPending() { // Cancelar todas as funções pendentes da ordem var ret = false; // Defina a variável de retorno da etiqueta de sucesso enquanto (verdadeiro) { // enquanto loop se (ret) { // Se ret é verdade então dormir por um certo tempo Dormir (intervalo); - Não. var ordens = _C(exchange.GetOrders); // Chame a API para obter as informações de ordem que a troca não executou. se (ordens.length == 0) { // Se uma matriz vazia for devolvida, a troca não tem ordens não executadas. interrupção; // Sair do loop enquanto - Não.
for (var j = 0; j < orders.length; j++) { // Traverse the unfinished order array and use orders[j].Id one by one to cancel the order based on the index j.
exchange.CancelOrder(orders[j].Id, orders[j]);
ret = true; // Once there is a cancel operation, ret is assigned a value of true. Used to trigger above Sleep, wait for re-exchange.GetOrders detection
}
}
return ret; // return ret
}
função valuesToString(valores, pos) { // Valor convertido para uma cadeia
var result =
Função Trader() { // Função Trader, usando fechamentos.
var vId = 0; // ID de incremento de ordem
var orderBooks = []; // Livro de encomendas
var hisBooks = []; // Livro de ordens históricas
var orderBooksLen = 0; // comprimento do livro de ordens
this.Buy = função ((preço, quantidade, extra) { // Função de compra, parâmetros: preço, quantidade, informação alargada
if (typeof(extra) ===
se (ordens[i].Id == order.Id) { // Quando você encontrar uma ordem com o mesmo id de ordem em orderBooks, atribuir um valor de verdadeiro para encontrar, o que significa encontrar.
encontrado = verdadeiro;
Break; // Sair do loop atual
- Não.
- Não.
se (!found) { // Se não for encontrado, empurre orderBooks[orderId] para ordens.
orders.push ((orderBooks[orderId]); // Por que você quer empurrar assim?
- Não.
- Não.
ordens de devolução; // ordens de devolução
- Não.
this.GetOrder = função ((orderId) { // Obter ordem
se (typeof(orderId) ===
var pfn = order.Type == ORDER_TYPE_BUY ? exchange.Buy : exchange.Sell; // Assign the corresponding API function reference to pfn according to the type of the order.
// That is, if the order type is a buy order, pfn is a reference to the exchange.Buy function, the same as the sell order.
if (order.Id == 0 && diff <= priceDiff) { // If the order order in the order book is not activated (ie Id is equal to 0) and the current price is less than or
// equal to the order plan price, the priceDiff passed in the parameter.
var realId = pfn(order.Price, order.Amount, order.Extra + "(distance: " + diff + (order.Type == ORDER_TYPE_BUY ? (" ask price: " + ticker.Buy) : (" bid price: " + ticker.Sell))+")");
// Execute order function, parameter passing price, quantity, order extension information + pending order distance + market data (ask price or bid price), return exchange order id
if (typeof(realId) === 'number') { // If the returned realId is a numeric type
order.Id = realId; // Assign the Id attribute of the current order order to the order book.
}
} else if (order.Id > 0 && diff > (priceDiff + 1)) { // If the order is active and the current distance is greater than the distance passed in by the parameter
var ok = true; // Declare a variable for tagging Initially set true
do { // Execute "do" first and then judge while
ok = true; // Ok assign true
exchange.CancelOrder(order.Id, "unnecessary" + (order.Type == ORDER_TYPE_BUY ? "buying" : "selling"), "placed order price:", order.Price, "volume:", order.Amount, ", distance:",
diff, order.Type == ORDER_TYPE_BUY ? ("ask price: " + ticker.Buy) : ("bid price: " + ticker.Sell));
// Cancel the pending order that is out of range. After canceling the order, print the current order information and the current distance diff.
Sleep(200); // Wait 200 milliseconds
orders = _C(exchange.GetOrders); // Call the API to get an uncompleted order in the exchange.
for (var i = 0; i < orders.length; i++) { // Traverse these unfinished orders.
if (orders[i].Id == order.Id) { // If the cancelled order is found in the list of orders that have not been completed by the exchange
ok = false; // Assign ok this variable to false, that is, no cancellation is successful.
}
}
} while (!ok); // If ok is false, then !ok is true and while will continue to repeat the loop, continue to cancel the order,
// and check if the cancellation is successful.
order.Id = 0; // Assigning a value of 0 to order.Id means that the current order is inactive.
}
}
};
}
function balanceAccount ((orgAccount, initAccount) { // Balance Account Function Parameter Initial account information when the strategy is started { // Balance Account Function Parameter Informação inicial da conta quando a estratégia é iniciada }
Call the custom function cancelPending() to cancel all pending orders (Chamar a função custom para cancelar todas as ordens pendentes).
var nowAccount = _C ((exchange.GetAccount); // Declare a variable nowAccount to record the latest information about the account at the moment.
Var slidePrice = 0.2; // Set the slip price when placing the order as 0.2
var ok = true; // Tag variable inicialmente definido como verdadeiro
while (true) { // enquanto loop
var diff = _N ((nowAccount.Stocks - initAccount.Stocks); // Calcule a difference between the current account and the initial account diff
If (Math.abs(diff) < exchange.GetMinStock()) { // If the absolute value of the currency difference is less than the minimum transaction volume of the exchange, o valor absoluto da diferença de moeda é inferior ao volume mínimo de transações da exchange, e o valor absoluto da diferença de moeda é inferior ao volume mínimo de transações da exchange.
// the break jumps out of the loop e não executa operações de equilíbrio.
O que é que ele está a fazer?
Não.
var depth = _C ((exchange.GetDepth); // Get the exchange depth information Assign to the declared depth variable (Verificar a profundidade da troca)
var books = diff > 0? depth.Bids : depth.Asks; // According the difference of the currency is greater than 0 or less than 0, extract the buy order array or
// sell order array in depth (equal to 0 will not be processed, it is break when it is judged to be less than GetMinStock) // sell order array in depth (equal to 0 will not be processed, it is break when it is judged to be less than GetMinStock)
// A diferença entre as moedas é maior que 0 para vender o saldo, então olhe para a matriz de ordens de compra,
// the difference between the coins is less than 0 is the opposite. // a diferença entre as moedas é menor que 0 é o oposto.
var n = 0; // Declaração n inicial is 0
Var price = 0; // Preço inicial da declaração 0
for (var i = 0; i < books.length; i++) { // Traversing the buy or sell order array
n += books[i].Amount; // Accumulate Amount (order quantity) for each order based on the index i traversed (Amount: // Acumule quantidade de ordem) para cada ordem baseada no índice i atravessado
If (n >= Math.abs ((diff)) { // If the cumulative order quantity n is greater than or equal to the currency difference, then:
// Get the price of the current indexed order, assign it to price (Get the price of the current indexed order, assign it to price) // Obtenha o preço da ordem indexada atual, atribui-o ao preço
break; // Jump out of the current for traversal cycle (Jump fora da corrente para o ciclo de travessia)
Não.
Não.
Var pfn = diff > 0? exchange.Sell : exchange.Buy; // Passar a API de ordem de venda (exchange.Sell) ou a próxima API de ordem de compra (exchange.Buy) referência ao pfn declarado
// baseado na diferença de moeda maior que 0 ou menor que 0
var amount = Math.abs ((diff); // The amount of the order to be balanced is diff, the difference in the currency, assigned to the declared amount variable. O valor da ordem a ser equilibrada é o diferencial na moeda, atribuído à variável de quantidade declarada.
var price = diff > 0? (price - slidePrice) : (price + slidePrice); // The direction of buying and selling according to the difference in the currency, increase or decrease the
// Slip price based on the price (slip price is to make it easier to trade), and then assign it to price (preço de deslize é para tornar mais fácil o comércio), e então atribui-o ao preço
Log ((
var STATE_WAIT_OPEN = 0; // Usado para o estado de cada nó no fishTable var STATE_WAIT_COVER = 1; //... var STATE_WAIT_CLOSE = 2; //... var ProfitCount = 0; // Registo de lucros e perdas var BuyFirst = true; // Parâmetros iniciais da interface var IsSupportGetOrder = true; // determinar o suporte de troca da função GetOrder API, uma variável global, usada para determinar o início da função principal var LastBusy = 0; // Registre o último objeto de tempo processado
função setBusy() { // Configure tempo de trabalho LastBusy = new Date(); // Atribuir LastBusy para o objeto hora atual - Não.
função isTimeout() { // Determine se ele tempo fora se (MaxIdle <= 0) { // Tempo máximo de inatividade (com base em se a grade é movida automaticamente), // se o tempo máximo de inatividade MaxIdle for definido menor ou igual a 0 return false; // Retorna false, não julga o timeout. Ou seja, sempre retorna false sem timeout. - Não. var now = new Date ((); // Obtenha objeto de tempo atual se (((now.getTime() - LastBusy.getTime()) / 1000) >= MaxIdle) { // Use a função getTime do objeto de tempo atual para obter o carimbo de tempo e o carimbo de tempo de LastBusy para calcular a diferença, // Divida por 1000 para calcular o número de segundos entre os dois objetos de tempo. // Determine se é maior que o tempo máximo de inatividade MaxIdle LastBusy = agora; // Se for maior que, atualizar LastBusy para o objeto de tempo atual agora return true; // Retorna true, que é um timeout. - Não. Return false; // Return false não há timeout - Não.
função onexit() { // A função de fechamento quando o programa sai.
se (CancelAllWS) { // Para cancelar todas as ordens pendentes quando parar, chamar cancelPending() para cancelar todas as ordens pendentes.
Registo ((
Função de pesca ((orgConte, peixeConte) { // Parâmetros de lançamento: informações sobre a conta, número de lançamentos
setBusy(); // Configure LastBuys para o carimbo de hora atual
var account = _C(exchange.GetAccount); // Declare uma variável de conta para obter as informações da conta corrente e atribuí-la.
Log ((conta); // Exporta as informações da conta no início da chamada para a função de pesca.
var InitAccount = conta; // Declare uma variável InitAccount e atribuí-lo com conta.
// este casting, usado para calcular lucro e perda flutuantes.
var ticker = _C(exchange.GetTicker); // Obtenha o valor da cotação atribuído à variável ticker declarada
var amount = _N(AmountOnce); // De acordo com o número de parâmetros da interface, use _N para processar os lugares decimais (_N predefinições para 2 bits) e atribuí-los para quantidade.
var amountB = [amount]; // Declare uma variável chamada amountB é uma matriz, inicializar um elemento com amount
var amountS = [amount]; // Declare uma variável chamada amountS...
se (typeof(AmountType)!==
- Não.
// Iniciar a tabela de peixes
var fishTable = {}; // Declare um objeto de grade
var uuidTable = {}; // Objeto de tabela de código de identificação
var needStocks = 0; // Moedas necessárias variável
var needMoney = 0; // Variavel de dinheiro necessário
var actualNeedMoney = 0; // Realmente precisava de dinheiro
var actualNeedStocks = 0; // Moedas realmente necessárias
var notEnough = false; // Variável de tag subfinanciada, inicialmente definida como false
var canNum = 0; // Grade disponível
para (var idx = 0; idx < AllNum; idx++) { // A estrutura é percorrida de acordo com o número da grade AllNum.
var price = _N((BuyFirst? FirstPrice - (idx * PriceGrid) : FirstPrice + (idx * PriceGrid)), Precisão);
// Ao atravessar a construção, a configuração do preço idx do índice atual é definida de acordo com BuyFirst.
needStocks += amountS[idx]; // O número de moedas vendidas é gradualmente acumulado com o ciclo.
needMoney += preço * amountB[idx]; // A quantidade de dinheiro necessária para comprar é gradualmente acumulada com o ciclo. (....compre a matriz de quantidade de ordem um por um...)
se (BuyFirst) { // Manipulação comprar primeiro
se (_N(needMoney) <= _N ((account.Balance)) { // Se a rede requer menos dinheiro do que o montante disponível na conta
actualNeedMondy = needMoney; // Atribuído à quantidade real de dinheiro necessária
actualNeedStocks = needStocks; // Atribuindo ao número real de moedas necessárias.
canNum++; // Número acumulado de grades disponíveis
} else { // _N(needMoney) <= _N(account.Balance) Se esta condição não for cumprida, definir a variável de etiqueta de insuficiência de financiamento como true
notEnough = true;
- Não.
} outro { // Manuseio venda primeiro
se (_N(needStocks) <= _N(account.Stocks)) { // Verifique se o número de moedas requerido é menor do que o número de moedas disponíveis na conta
actualNeedMondy = needMoney; // Atribuição
actualNeedStocks = needStocks;
canNum++; // Número acumulado de grades disponíveis
Outra coisa
notEnough = true; // Definir true se as condições de financiamento não forem cumpridas
- Não.
- Não.
fishTable[idx] = STATE_WAIT_OPEN; // De acordo com o índice idx atual, defina o estado do membro idx (nodo da grade) do objeto da grade,
// inicialmente STATE_WAIT_OPEN (esperando para abrir a posição)
uuidTable[idx] = -1; // O objeto numerado também inicializa seu próprio valor idx (o nó correspondente ao fishTable) para -1 com base no idx atual.
- Não.
se (!EnableAccountCheck && (canNum < AllNum)) { // Se a verificação de fundos não estiver habilitada, e o número de grades (o número total de nós) onde o nó é menor
// do que a configuração do parâmetro de interface pode ser aberta.
Log ((
lançar
var trader = new Trader(); // Constructs a Trader object, assigning it to the trader variable declared here.
var OpenFunc = BuyFirst ? exchange.Buy : exchange.Sell; // According to whether to buy and sell first, set the open function OpenFunc to refer to exchange.Buy or exchange.Sell
var CoverFunc = BuyFirst ? exchange.Sell : exchange.Buy; // same as above
if (EnableDynamic) { // Set OpenFunc/CoverFunc again according to whether the interface parameter EnableDynamic is enabled.
OpenFunc = BuyFirst ? trader.Buy : trader.Sell; // The member function Buy that references the trader object is used for dynamic pending orders (mainly because
// some exchanges limit the number of pending orders, so virtual dynamic pending orders are required)
CoverFunc = BuyFirst ? trader.Sell : trader.Buy; // same as above
}
var ts = new Date(); // Create a time object at this time (assigned to ts) to record the time at the moment.
var preMsg = ""; // Declare a variable to record the last message, the initial set to empty string
var profitMax = 0; // Maximum return
while (true) { // The main logic after the grid is casted
var now = new Date(); // Record the time when the current cycle started
var table = null; // Declare a variable
if (now.getTime() - ts.getTime() > 5000) { // Calculate whether the difference between the current time now and the recorded time ts is greater than 5000 milliseconds
if (typeof(GetCommand) == 'function' && GetCommand() == "Receiving grid") { // Check if the strategy interaction control command "receives the grid" is received,
// stops and balances to the initial state.
Log("Start executing commands to perform grid operations"); // Output information
balanceAccount(orgAccount, InitAccount); // Perform a balancing function to balance the number of coins to the initial state
return false; // This time the grid function is fishing and return false
}
ts = now; // Update ts with current time now for next comparison time
var nowAccount = _C(exchange.GetAccount); // Declare the nowAccount variable and initially been set as the current account information.
var ticker = _C(exchange.GetTicker); // Declare the ticker variable and initially been set as the current market information.
if (EnableDynamic) { // If you enable dynamic pending orders
trader.Poll(ticker, DynamicMax); // Call the Poll function of the trader object to detect and process all orders based on the
// current ticker market and the interface parameter DynamicMax.
}
var amount_diff = (nowAccount.Stocks + nowAccount.FrozenStocks) - (InitAccount.Stocks + InitAccount.FrozenStocks); // Calculate the current coin difference
var money_diff = (nowAccount.Balance + nowAccount.FrozenBalance) - (InitAccount.Balance + InitAccount.FrozenBalance); // Calculate the current money difference
var floatProfit = _N(money_diff + (amount_diff * ticker.Last)); // Calculate the current floating profit and loss of this time of casting grid
var floatProfitAll = _N((nowAccount.Balance + nowAccount.FrozenBalance - orgAccount.Balance - orgAccount.FrozenBalance) + ((nowAccount.Stocks + nowAccount.FrozenStocks
- orgAccount.Stocks - orgAccount.FrozenStocks) * ticker.Last));
// Calculate the overall floating profit and loss
var isHold = Math.abs(amount_diff) >= exchange.GetMinStock(); // If the absolute value of the coin difference at this moment is greater than the minimum trading
// volume of the exchange, it means that the position has been held.
if (isHold) { // If you have already held a position, execute the setBusy() function, which will update the LastBusy time.
setBusy(); // That is, after opening the position, the opening of the opening mechanism is started.
}
profitMax = Math.max(floatProfit, profitMax); // Refresh the maximum floating profit and loss
if (EnableAccountCheck && EnableStopLoss) { // If you initiate account detection and start a stop loss
if ((profitMax - floatProfit) >= StopLoss) { // If the maximum floating profit or loss minus the current floating profit or loss is greater than or equal to
// the maximum floating loss value, execute the code inside the curly braces
Log("Current floating profit a