A negociação de alta frequência é um campo desafiador e competitivo que depende da execução rápida de negócios e de insights sensíveis sobre a microestrutura do mercado. Uma estratégia notável é o Penny Jump, que se concentra em explorar os "elefantes" no mercado para obter lucros pequenos, mas frequentes.
No mercado de ações,
Por exemplo, suponha que a profundidade original de um mercado de ações fosse assim: 200 ∙ $1.01 x $1.03 ∙ 200. Então um "elefante" entra e coloca uma ordem de compra de 3000 ações a $1.01 cada. Neste ponto, a profundidade do mercado mudará para 3.200 ∙ $1.01 x $1.03 ∙ 200. Esta ação é como introduzir um "elefante", que se torna o foco de outros participantes no mercado.
Mercado competitivo Para os traders de alta frequência, seus lucros vêm principalmente da análise da microestrutura do mercado para especular sobre as intenções de outros traders.
O dilema do elefante Embora os elefantes possam querer operar em grande escala no mercado, suas ações também revelam suas intenções comerciais, tornando-os alvos de traders de alta frequência.
Engano no mercado Na realidade, os grandes investidores institucionais geralmente não colocam um grande número de ordens de compra ou venda no mercado descaradamente, pois tal comportamento pode levar outros participantes do mercado a tomar contramedidas ou até mesmo manipular o mercado.
A ideia central da estratégia Penny Jump é que uma vez que um
Não só isso, mas os traders de alta frequência também podem obter lucros após a compra, mesmo que o preço não suba, porque sabem que o grande jogador apoiou o preço de base; portanto, eles podem rapidamente vender suas ações para esse grande jogador e obter pequenos lucros de arbitragem.
Código fonte da estratégia:https://www.fmz.com/strategy/358
O código de estratégia fornecido acima é um exemplo, usado para implementar a estratégia Penny Jump. Abaixo está uma explicação detalhada do código, permitindo que os iniciantes entendam como funciona:
var Counter = {
i: 0,
w: 0,
f: 0
};
// Variables
var InitAccount = null;
function CancelAll() {
while (true) {
var orders = _C(exchange.GetOrders);
if (orders.length == 0) {
break;
}
for (var i = 0; i < orders.length; i++) {
exchange.CancelOrder(orders[i].Id);
}
Sleep(Interval);
}
}
function updateStatus(msg) {
LogStatus("Number of debugging sessions:", Counter.i, "succeeded:", Counter.w, "failed:", Counter.f, "\n"+msg+"#0000ff\n"+new Date());
}
function main() {
if (DisableLog) {
EnableLog(false);
}
CancelAll();
InitAccount = _C(exchange.GetAccount);
Log(InitAccount);
var i = 0;
var locks = 0;
while (true) {
Sleep(Interval);
var depth = _C(exchange.GetDepth);
if (depth.Asks.length === 0 || depth.Bids.length === 0) {
continue;
}
updateStatus("Searching within the elephant... Buy one: " + depth.Bids[0].Price + ", Sell one:" + depth.Asks[0].Price + ", Lock times: " + locks);
var askPrice = 0;
for (i = 0; i < depth.Asks.length; i++) {
if (depth.Asks[i].Amount >= Lot) {
askPrice = depth.Asks[i].Price;
break;
}
}
if (askPrice === 0) {
continue;
}
var elephant = null;
// skip Bids[0]
for (i = 1; i < depth.Bids.length; i++) {
if ((askPrice - depth.Bids[i].Price) > ElephantSpace) {
break;
}
if (depth.Bids[i].Amount >= ElephantAmount) {
elephant = depth.Bids[i];
break;
}
}
if (!elephant) {
locks = 0;
continue;
}
locks++;
if (locks < LockCount) {
continue;
}
locks = 0;
updateStatus("Debug the elephant... The elephant is in gear " + i + ", " + JSON.stringify(elephant));
exchange.Buy(elephant.Price + PennyTick, Lot, "Bids[" + i + "]", elephant);
var ts = new Date().getTime();
while (true) {
Sleep(CheckInterval);
var orders = _C(exchange.GetOrders);
if (orders.length == 0) {
break;
}
if ((new Date().getTime() - ts) > WaitInterval) {
for (var i = 0; i < orders.length; i++) {
exchange.CancelOrder(orders[i].Id);
}
}
}
var account = _C(exchange.GetAccount);
var opAmount = _N(account.Stocks - InitAccount.Stocks);
if (opAmount < 0.001) {
Counter.f++;
Counter.i++;
continue;
}
updateStatus("Successful payment: " + opAmount +", Start taking action...");
exchange.Sell(elephant.Price + (PennyTick * ProfitTick), opAmount);
var success = true;
while (true) {
var depth = _C(exchange.GetDepth);
if (depth.Bids.length > 0 && depth.Bids[0].Price <= (elephant.Price-(STTick*PennyTick))) {
success = false;
updateStatus("Didn't get it, start to stop loss, currently buying one: " + depth.Bids[0].Price);
CancelAll();
account = _C(exchange.GetAccount);
var opAmount = _N(account.Stocks - InitAccount.Stocks);
if (opAmount < 0.001) {
break;
}
exchange.Sell(depth.Bids[0].Price, opAmount);
}
var orders = _C(exchange.GetOrders);
if (orders.length === 0) {
break;
}
Sleep(CheckInterval);
}
if (success) {
Counter.w++;
} else {
Counter.f++;
}
Counter.i++;
var account = _C(exchange.GetAccount);
LogProfit(account.Balance - InitAccount.Balance, account);
}
}
Vou analisar o seu código de estratégia linha por linha para ajudá-lo a compreender a sua operação em detalhes.
var Counter = {
i: 0,
w: 0,
f: 0
};
Este código inicializa um objeto chamado Counter, que é usado para rastrear as informações estatísticas de negociação de uma estratégia.
Estes atributos serão registados e actualizados durante o processo de execução da estratégia.
var InitAccount = null;
Esta linha de código inicializa uma variável chamada InitAccount, que armazenará informações da conta quando a estratégia começar a ser executada.
function CancelAll() {
while (true) {
var orders = _C(exchange.GetOrders);
if (orders.length == 0) {
break;
}
for (var i = 0; i < orders.length; i++) {
exchange.CancelOrder(orders[i].Id);
}
Sleep(Interval);
}
}
Esta é uma função chamadaCancelAll()
O seu objectivo é cancelar todas as encomendas não cumpridas no mercado.
while (true)
Isto é um ciclo infinito, vai continuar a correr até não haver ordens incompletas.var orders = _C(exchange.GetOrders)
: Esta linha de código utiliza a função exchange.GetOrders para recuperar todas as ordens pendentes na conta corrente e armazená-las na variável ordens.if (orders.length == 0)
Se o comprimento da matriz de ordens for 0, isso significa que não há ordens inacabadas e o loop será interrompido (break).for (var i = 0; i < orders.length; i++)
: Este é um loop for que itera através de todas as ordens não concluídas.exchange.CancelOrder(orders[i].Id)
: Esta linha de código utiliza a função exchange.CancelOrder() para cancelar cada encomenda pelo seu ID.Sleep(Interval)
: Esta linha de código introduz um período de espera, com pausa por um determinado período de tempo (em milissegundos), para garantir que a operação de cancelamento de ordens não seja demasiado frequente.Esta linha de código introduz um período de espera, com pausa por um determinado período de tempo (em milissegundos), para garantir que a operação de cancelamento de ordens não seja demasiado frequente.
function updateStatus(msg) {
LogStatus("Number of debugging sessions:", Counter.i, "succeeded:", Counter.w, "failed:", Counter.f, "\n" + msg + "#0000ff\n" + new Date());
}
Esta é uma função chamadaupdateStatus(msg)
, que é usado para atualizar e registrar informações sobre o estado da transação. Aceita um parâmetro msg, que geralmente contém informações sobre o estado atual do mercado. As operações específicas da função incluem:
Utilizando oLogStatus()
Função para gravar as informações exibidas na barra de status durante a execução da estratégia.
Omsg
O parâmetro é anexado, que contém informações sobre a situação actual do mercado.
O carimbo de data e hora (new Date()
) é anexado para exibir informações sobre o tempo.
O objetivo desta função é registar e atualizar as informações sobre o estado das transacções para monitorização e análise durante a execução da estratégia.
function main() {
if (DisableLog) {
EnableLog(false);
}
CancelAll();
InitAccount = _C(exchange.GetAccount);
Log(InitAccount);
var i = 0;
var locks = 0;
while (true) {
Sleep(Interval);
var depth = _C(exchange.GetDepth);
if (depth.Asks.length === 0 || depth.Bids.length === 0) {
continue;
}
updateStatus("Searching within the elephant... Buy one: " + depth.Bids[0].Price + ", Sell one:" + depth.Asks[0].Price + ", Lock times: " + locks);
var askPrice = 0;
for (i = 0; i < depth.Asks.length; i++) {
if (depth.Asks[i].Amount >= Lot) {
askPrice = depth.Asks[i].Price;
break;
}
}
if (askPrice === 0) {
continue;
}
var elephant = null;
// skip Bids[0]
for (i = 1; i < depth.Bids.length; i++) {
if ((askPrice - depth.Bids[i].Price) > ElephantSpace) {
break;
}
if (depth.Bids[i].Amount >= ElephantAmount) {
elephant = depth.Bids[i];
break;
}
}
if (!elephant) {
locks = 0;
continue;
}
locks++;
if (locks < LockCount) {
continue;
}
locks = 0;
updateStatus("Debug the elephant... The elephant is in gear " + i + ", " + JSON.stringify(elephant));
exchange.Buy(elephant.Price + PennyTick, Lot, "Bids[" + i + "]", elephant);
var ts = new Date().getTime();
while (true) {
Sleep(CheckInterval);
var orders = _C(exchange.GetOrders);
if (orders.length == 0) {
break;
}
if ((new Date().getTime() - ts) > WaitInterval) {
for (var i = 0; i < orders.length; i++) {
exchange.CancelOrder(orders[i].Id);
}
}
}
var account = _C(exchange.GetAccount);
var opAmount = _N(account.Stocks - InitAccount.Stocks);
if (opAmount < 0.001) {
Counter.f++;
Counter.i++;
continue;
}
updateStatus("Successful payment: " + opAmount +", Start taking action...");
exchange.Sell(elephant.Price + (PennyTick * ProfitTick), opAmount);
var success = true;
while (true) {
var depth = _C(exchange.GetDepth);
if (depth.Bids.length > 0 && depth.Bids[0].Price <= (elephant.Price-(STTick*PennyTick))) {
success = false;
updateStatus("Didn't get it, start to stop loss, currently buying one: " + depth.Bids[0].Price);
CancelAll();
account = _C(exchange.GetAccount);
var opAmount = _N(account.Stocks - InitAccount.Stocks);
if (opAmount < 0.001) {
break;
}
exchange.Sell(depth.Bids[0].Price, opAmount);
}
var orders = _C(exchange.GetOrders);
if (orders.length === 0) {
break;
}
Sleep(CheckInterval);
}
if (success) {
Counter.w++;
} else {
Counter.f++;
}
Counter.i++;
var account = _C(exchange.GetAccount);
LogProfit(account.Balance - InitAccount.Balance, account);
}
}
Esta é a principal função de execuçãomain()
A estratégia de desenvolvimento sustentável é uma estratégia de desenvolvimento sustentável, que contém a lógica central da estratégia.
if (DisableLog)
: Esta linha de código verifica se a variável DisableLog é verdadeira e, se assim for, desativa a gravação de logs.
CancelAll()
: Chame a função CancelAll( explicada anteriormente para garantir que não haja pedidos inacabados.
InitAccount = _C(exchange.GetAccount)
: Esta linha de código recupera as informações da conta corrente e as armazena na variável InitAccount. Isto será usado para registar o estado da conta quando a estratégia começar a ser executada.
var i = 0;
evar locks = 0;
: Iniciar duas variáveis, i e bloqueios, que serão usados na lógica de estratégia subsequente.
while (true)
: Este é um ciclo infinito, usado principalmente para a execução contínua de estratégias.
Em seguida, vamos explicar a lógica estratégica principal dentro dowhile (true)
Loop linha por linha.
while (true) {
Sleep(Interval);
var depth = _C(exchange.GetDepth);
if (depth.Asks.length === 0 || depth.Bids.length === 0) {
continue;
}
updateStatus("Searching within the elephant... Buy one: " + depth.Bids[0].Price + ", Sell one:" + depth.Asks[0].Price + ", Lock times: " + locks);
Sleep(Interval)
: Esta linha de código permite que a estratégia durma por um período de tempo, a fim de controlar a frequência de execução da estratégia.
var depth = _C(exchange.GetDepth)
: Obter as informações atuais sobre a profundidade do mercado, incluindo os preços e quantidades das ordens de venda e de compra.
if (depth.Asks.length === 0 || depth.Bids.length === 0)
: Esta linha de código verifica as informações de profundidade do mercado, garantindo que existem ordens de venda e de compra.
updateStatus("Searching within the elephant... Buy one: " + depth.Bids[0].Price + ", Sell one:" + depth.Asks[0].Price + ", Lock times: " + locks)
: Esta linha de código chama a função updateStatus para atualizar as informações de estado da estratégia. Regista o estado atual do mercado, incluindo o preço de oferta mais alto, o preço de compra mais baixo e os tempos de bloqueio anteriores (bloques).
var askPrice = 0;
for (i = 0; i < depth.Asks.length; i++) {
if (depth.Asks[i].Amount >= Lot) {
askPrice = depth.Asks[i].Price;
break;
}
}
if (askPrice === 0) {
continue;
}
var elephant = null;
var askPrice = 0;
: Iniciar a variável askPrice, ele será usado para armazenar o preço das ordens de venda que atendem às condições.
for (i = 0; i < depth.Asks.length; i++)
: Este é um loop for utilizado para atravessar as informações de preço e quantidade das ordens de venda no mercado.
if (depth.Asks[i].Amount >= Lot)
: No loop, verifique se a quantidade de cada ordem de venda é maior ou igual ao lote especificado (contagem manual).
if (askPrice === 0)
Se não forem encontradas ordens de venda que satisfaçam as condições (o preço de venda continua a ser 0), a estratégia continuará a esperar e a ignorar operações subsequentes.
var elephant = null;
: Inicie a variável elefante, ela será usada para armazenar as informações da ordem de compra identificadas como
for (i = 1; i < depth.Bids.length; i++) {
if ((askPrice - depth.Bids[i].Price) > ElephantSpace) {
break;
}
if (depth.Bids[i].Amount >= ElephantAmount) {
elephant = depth.Bids[i];
break;
}
}
if (!elephant) {
locks = 0;
continue;
}
locks++;
if (locks < LockCount) {
continue;
}
locks = 0;
Continuar a percorrer as informações de preço e quantidade das ordens de compra de mercado, ignorando a primeira ordem de compra (Oferta[0]).
if ((askPrice - depth.Bids[i].Price) > ElephantSpace)
: Verifique se a diferença entre o preço atual de oferta e o askPrice é maior do que o ElephantSpace.
if (depth.Bids[i].Amount >= ElephantAmount)
: Verifique se a quantidade da ordem de compra atual é maior ou igual a ElephantAmount.
if (!elephant)
Se o
locks++
Se o
if (locks < LockCount)
: Verifique se o número de tempos de bloqueio cumpre o requisito (LockCount).
updateStatus("Debug the elephant... The elephant is in gear " + i + ", " + JSON.stringify(elephant));
exchange.Buy(elephant.Price + PennyTick, Lot, "Bids[" + i + "]", elephant);
var ts = new Date().getTime();
while (true) {
Sleep(CheckInterval);
var orders = _C(exchange.GetOrders);
if (orders.length == 0) {
break;
}
if ((new Date().getTime() - ts) > WaitInterval) {
for (var i = 0; i < orders.length; i++) {
exchange.CancelOrder(orders[i].Id);
}
}
}
updateStatus("Debug the elephant... The elephant is in gear " + i + ", " + JSON.stringify(elephant))
: Chamar a função updateStatus para registar o estado atual da estratégia, incluindo a posição da engrenagem do
exchange.Buy(elephant.Price + PennyTick, Lot, "Bids[" + i + "]", elephant)
: Use a função exchange.Buy para comprar o encontrado
var ts = new Date().getTime()
: Obter o carimbo horário da hora atual para o cálculo posterior dos intervalos de tempo.
while (true)
Introdução de um novo loop infinito, usado para esperar a execução de ordens de compra.
Sleep(CheckInterval)
: A estratégia dorme por um tempo para controlar a frequência de verificação do estado da ordem.
var orders = _C(exchange.GetOrders)
Obter todas as informações de encomenda da conta corrente.
if (orders.length == 0)
Verifique se há pedidos inacabados, se não, rompa o ciclo.
(new Date().getTime() - ts) > WaitInterval
: Calcule o intervalo de tempo entre a hora atual e quando o
for (var i = 0; i < orders.length; i++)
Revise todas as encomendas não concluídas.
exchange.CancelOrder(orders[i].Id)
: Utilize a função exchange.CancelOrder para cancelar cada encomenda inacabada.
var account = _C(exchange.GetAccount);
var opAmount = _N(account.Stocks - InitAccount.Stocks);
if (opAmount < 0.001) {
Counter.f++;
Counter.i++;
continue;
}
updateStatus("Successful payment: " + opAmount + ", Start taking action...");
exchange.Sell(elephant.Price + (PennyTick * ProfitTick), opAmount);
var success = true;
while (true) {
var depth = _C(exchange.GetDepth);
if (depth.Bids.length > 0 && depth.Bids[0].Price <= (elephant.Price - (STTick * PennyTick))) {
success = false;
updateStatus("Didn't get it, start to stop loss, currently buying one: " + depth.Bids[0].Price);
CancelAll();
account = _C(exchange.GetAccount);
var opAmount = _N(account.Stocks - InitAccount.Stocks);
if (opAmount < 0.001) {
break;
}
exchange.Sell(depth.Bids[0].Price, opAmount);
}
var orders = _C(exchange.GetOrders);
if (orders.length === 0) {
break;
}
Sleep(CheckInterval);
}
if (success) {
Counter.w++;
} else {
Counter.f++;
}
Counter.i++;
var account = _C(exchange.GetAccount);
LogProfit(account.Balance - InitAccount.Balance, account);
}
var account = _C(exchange.GetAccount)
Obter informações sobre a conta corrente.
var opAmount = _N(account.Stocks - InitAccount.Stocks)
: Calcule a mudança nos ativos da conta após a compra do
updateStatus("Successful payment: " + opAmount + ", Start taking action...")
: Registar as informações sobre a aquisição bem sucedida de
exchange.Sell(elephant.Price + (PennyTick * ProfitTick), opAmount)
: Use a função exchange.Sell para vender o
Introduza um novo loop infinito, usado para esperar pela execução de ordens de venda.
var depth = _C(exchange.GetDepth)
Obter informações aprofundadas sobre o mercado.
if (depth.Bids.length > 0 && depth.Bids[0].Price <= (elephant.Price - (STTick * PennyTick)))
: Verifique as informações de profundidade do mercado, se o preço de mercado já caiu para o nível de stop-loss, e execute a operação de stop-loss.
CancelAll()
: Chamar a função CancelAll( para cancelar todas as ordens não concluídas, a fim de evitar o risco de posição.
if (opAmount < 0.001)
: Verifique novamente a quantidade de compra, se for inferior a 0,001, indica que a compra falhou, saia do ciclo.
exchange.Sell(depth.Bids[0].Price, opAmount)
: Execute uma operação de stop-loss, venda os activos remanescentes ao preço mais baixo do mercado actual.
Por último, atualizar o número de transações bem sucedidas e falhadas com base em se a transação foi bem sucedida ou não e registar os lucros comerciais.
Esta é uma explicação linha por linha de toda a estratégia. A ideia central desta estratégia é encontrar
Em geral, esta estratégia é uma estratégia de negociação de alta frequência destinada a utilizar informações de profundidade de mercado para identificar grandes ordens de compra e realizar transações de compra e venda em um curto período de tempo.
Observe que a estratégia é baseada em mercados e plataformas de negociação específicos. Para diferentes mercados e exchanges, podem ser necessários ajustes e otimizações apropriados. Na aplicação prática, os investidores precisam testar e avaliar cuidadosamente o desempenho da estratégia para garantir que ela esteja alinhada com seus objetivos de investimento e tolerância ao risco.
À medida que você continua a executar a estratégia, ela executará repetidamente as seguintes operações:
Em primeiro lugar, a estratégia verificará a informação aprofundada do mercado para compreender a situação actual das ordens de venda e de compra.
Em seguida, a estratégia tentará encontrar ordens de venda que atendam aos critérios, especificamente ordens de venda com uma quantidade maior ou igual a Lot.
Em seguida, a estratégia continuará a procurar por
Se um número suficiente de
Toda a estratégia realiza continuamente as operações acima para capturar o maior número possível de "elefantes" e obter pequenos lucros. Esta é uma estratégia de negociação de alta frequência que requer respostas rápidas às mudanças do mercado, ao mesmo tempo em que considera a gestão de riscos e mecanismos de stop-loss para proteger o capital. Os investidores devem considerar cuidadosamente o uso desta estratégia, especialmente em mercados altamente voláteis.
A estratégia Penny Jump é um exemplo típico de negociação de alta frequência, demonstrando o jogo sutil e a competição entre os participantes do mercado. Esta estratégia é particularmente proeminente no mercado de criptomoedas devido às suas grandes flutuações, onde investidores institucionais e comerciantes de alta frequência estão todos buscando lucros rápidos. No entanto, isso também torna o mercado cheio de desafios, exigindo constante adaptação e ajuste de estratégias para manter vantagens competitivas.