Estratégia EMV de volatilidade simples

Autora:Bem-estar, Criado: 2020-07-01 10:39:17, Atualizado: 2023-10-28 15:26:49

img

Resumo

Ao contrário de outros indicadores técnicos, Ease of Movement Value reflete mudanças de preço, volume e popularidade. É uma tecnologia que combina preços e mudanças de volume. Ele mede a mudança de preço do volume unitário, formando um indicador de volatilidade de preços. Quando o mercado ganha popularidade e a transação está ativa, ele solicita um sinal de compra; quando o volume de negociação é baixo e a energia do mercado está prestes a esgotar-se, ele solicita um sinal de venda.

O EMV de volatilidade simples é projetado de acordo com o princípio do gráfico de volume igual e gráfico comprimido. Seu conceito central é: o preço de mercado consumirá muita energia apenas quando a tendência vira ou está prestes a mudar, e o desempenho externo é que o volume de negociação se torna maior.

Fórmula de cálculo da EMV

Passo 1: Calcular mov_mid

Entre eles, TH representa o preço mais alto do dia, TL representa o preço mais baixo do dia, YH representa o preço mais alto do dia anterior e YL representa o preço mais baixo do dia anterior.

img

Passo 2: Calcular o rácio

Entre eles, o TVOL representa o volume de negociação do dia, o TH representa o preço mais alto do dia e o TL representa o preço mais baixo do dia.

img

Passo 3: Calcular o valor de emissão

img

Utilização de VEM

O autor da EMV acredita que o enorme aumento é acompanhado pelo rápido esgotamento da energia, e o aumento muitas vezes não dura muito tempo; pelo contrário, o volume moderado, que pode economizar uma certa quantidade de energia, muitas vezes faz com que o aumento dure mais tempo. Uma vez que uma tendência ascendente é formada, menos volume de negociação pode empurrar os preços para cima, e o valor da EMV aumentará. Uma vez que o mercado de tendência descendente é formado, muitas vezes é acompanhado por um declínio infinito ou pequeno, e o valor da EMV diminuirá.

O uso do EMV é bastante simples, basta olhar se o EMV atravessa o eixo zero. Quando o EMV está abaixo de 0, representa um mercado fraco; quando o EMV está acima de 0, representa um mercado forte. Quando o EMV muda de negativo para positivo, ele deve ser comprado; quando o EMV muda de positivo para negativo, ele deve ser vendido. Sua característica é que ele não só pode evitar o mercado de choque no mercado, mas também entrar no mercado a tempo quando o mercado de tendência começa. No entanto, porque o EMV reflete a mudança de volume quando os preços mudam, ele só tem um efeito nas tendências de médio a longo prazo. Para ciclos de negociação de curto prazo ou relativamente curtos, o efeito do EMV é muito pobre.

Realização da estratégia

Passo 1: Escrever um quadro estratégico

# Strategy main function
def onTick():
     pass

# Program entry
def main():
     while True: # Enter infinite loop mode
         onTick() # execution strategy main function
         Sleep(1000) # sleep for 1 second

FMZ.COMO primeiro passo é definir um sistema de formação de rotação.mainfunção e umonTickAmainfunção é a função de entrada da estratégia, e o programa executará a linha de código por linha a partir domainA funçãomainfunção, escrever umwhileciclo e executar repetidamente oonTickTodos os códigos essenciais da estratégia são escritos noonTick function.

Passo 2: Obter dados de posição

def get_position():
     position = 0 # The number of assigned positions is 0
     position_arr = _C(exchange.GetPosition) # Get array of positions
     if len(position_arr)> 0: # If the position array length is greater than 0
         for i in position_arr: # Traverse the array of positions
             if i['ContractType'] =='IH000': # If the position symbol is equal to the subscription symbol
                 if i['Type']% 2 == 0: # if it is long position
                     position = i['Amount'] # Assign a positive number of positions
                 else:
                     position = -i['Amount'] # Assign the number of positions to be negative
     return position # return position quantity

Porque nesta estratégia, apenas o número de posições em tempo real é usado, a fim de facilitar a manutenção,get_positionSe a posição atual for longa, ela retorna um número positivo, e se a posição atual for curta, ela retorna um número negativo.

Passo 3: Obter dados da linha K

exchange.SetContractType('IH000') # Subscribe to futures variety
bars_arr = exchange.GetRecords() # Get K-line array
if len(bars_arr) <10: # If the number of K lines is less than 10
     return

Antes de obter dados específicos da linha K, deve subscrever primeiro um contrato de negociação específico, utilizar oSetContractTypefunção deFMZ.COMSe você quiser saber outras informações sobre o contrato, você também pode usar uma variável para receber esses dados.GetRecordsfunção para obter dados de linha K, porque o devolvido é uma matriz, então usamos a variávelbars_arrpara aceitá-lo.

Etapa 4: Calcular o valor de emissão

bar1 = bars_arr[-2] # Get the previous K-line data
bar2 = bars_arr[-3] # get the previous K-line data
# Calculate the value of mov_mid
mov_mid = (bar1['High'] + bar1['Low']) / 2-(bar2['High'] + bar2['Low']) / 2
if bar1['High'] != bar1['Low']: # If the dividend is not 0
     # Calculate the value of ratio
     ratio = (bar1['Volume'] / 10000) / (bar1['High']-bar1['Low'])
else:
     ratio = 0
# If the value of ratio is greater than 0
if ratio> 0:
     emv = mov_mid / ratio
else:
     emv = 0

Aqui, não usamos o preço mais recente para calcular o valor do EMV, mas usamos a linha K atual relativamente atrasada para emitir o sinal e colocar uma linha K para emitir uma ordem. O propósito disso é tornar o backtest mais próximo da negociação real. Sabemos que, embora o software de negociação quantitativa esteja agora muito avançado, ainda é difícil simular completamente o ambiente de tique de preço real, especialmente quando confrontado com o backtesting de dados longos de nível de barra, então esse método de compromisso é usado.

Etapa 5: Envio das ordens

current_price = bars_arr[-1]['Close'] # latest price
position = get_position() # Get the latest position
if position> 0: # If you are holding long positions
    if emv <0: # If the current price is less than teeth
        exchange.SetDirection("closebuy") # Set the trading direction and type
        exchange.Sell(round(current_price-0.2, 2), 1) # close long position
if position <0: # If you are holding short positions
    if emv> 0: # If the current price is greater than the teeth
        exchange.SetDirection("closesell") # Set the trading direction and type
        exchange.Buy(round(current_price + 0.2, 2), 1) # close short position
if position == 0: # If there is no holding position
    if emv> 0: # If the current price is greater than the upper lip
        exchange.SetDirection("buy") # Set the trading direction and type
        exchange.Buy(round(current_price + 0.2, 2), 1) # open long position
    if emv <0: # if the current price is smaller than the chin
        exchange.SetDirection("sell") # Set the trading direction and type
        exchange.Sell(round(current_price-0.2, 2), 1) # open short position

Antes de colocar a ordem, precisamos determinar dois dados, um é o preço da ordem e o outro é o status da posição atual. O preço de colocar uma ordem é muito simples, basta usar o preço de fechamento atual para adicionar ou subtrair o preço mínimo de mudança da variedade.get_positionFinalmente, a posição é aberta e fechada de acordo com a relação posicional entre o EMV e o eixo zero.

Backtest da estratégia

Configuração de teste de retorno

img

Registo dos testes de regresso

img img

Curva do capital

img

Estratégia completa

# Backtest configuration
'''backtest
start: 2019-01-01 00:00:00
end: 2020-01-01 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
'''


def get_position():
     position = 0 # The number of assigned positions is 0
     position_arr = _C(exchange.GetPosition) # Get array of positions
     if len(position_arr)> 0: # If the position array length is greater than 0
         for i in position_arr: # Traverse the array of positions
             if i['ContractType'] =='IH000': # If the position symbol is equal to the subscription symbol
                 if i['Type']% 2 == 0: # if it is long position
                     position = i['Amount'] # Assign a positive number of positions
                 else:
                     position = -i['Amount'] # Assign the number of positions to be negative
     return position # return position quantity


# Strategy main function
def onTick():
     # retrieve data
     exchange.SetContractType('IH000') # Subscribe to futures
     bars_arr = exchange.GetRecords() # Get K-line array
     if len(bars_arr) <10: # If the number of K lines is less than 10
         return

     # Calculate emv
     bar1 = bars_arr[-2] # Get the previous K-line data
     bar2 = bars_arr[-3] # get the previous K-line data
     # Calculate the value of mov_mid
     mov_mid = (bar1['High'] + bar1['Low']) / 2-(bar2['High'] + bar2['Low']) / 2
     if bar1['High'] != bar1['Low']: # If the dividend is not 0
          # Calculate the value of ratio
          ratio = (bar1['Volume'] / 10000) / (bar1['High']-bar1['Low'])
     else:
          ratio = 0
     # If the value of ratio is greater than 0
     if ratio> 0:
          emv = mov_mid / ratio
     else:
          emv = 0

     # Placing orders
     current_price = bars_arr[-1]['Close'] # latest price
     position = get_position() # Get the latest position
     if position> 0: # If you are holding long positions
          if emv <0: # If the current price is less than teeth
               exchange.SetDirection("closebuy") # Set the trading direction and type
               exchange.Sell(round(current_price-0.2, 2), 1) # close long position
     if position <0: # If you are holding short positions
          if emv> 0: # If the current price is greater than the teeth
               exchange.SetDirection("closesell") # Set the trading direction and type
               exchange.Buy(round(current_price + 0.2, 2), 1) # close short position
     if position == 0: # If there is no holding position
          if emv> 0: # If the current price is greater than the upper lip
               exchange.SetDirection("buy") # Set the trading direction and type
               exchange.Buy(round(current_price + 0.2, 2), 1) # open long position
     if emv <0: # if the current price is smaller than the chin
               exchange.SetDirection("sell") # Set the trading direction and type
               exchange.Sell(round(current_price-0.2, 2), 1) # open short position

# Program entry
def main():
     while True: # Enter infinite loop mode
         onTick() # execution strategy main function
         Sleep(1000) # sleep for 1 second

A estratégia completa foi publicada na praça de estratégia daFMZ.COMsite, e pode ser usado clicando em Copiar.https://www.fmz.com/strategy/213636

Resumindo

Através deste curso de estudo, podemos ver que a EMV é contrária aos traders comuns, mas não é irracional. Como a EMV introduz dados de volume, é mais eficaz do que outros indicadores técnicos que usam cálculos de preço para descobrir o que está por trás do preço. Cada estratégia tem características diferentes. Somente entendendo completamente as vantagens e desvantagens de diferentes estratégias e removendo a escória e extraindo sua essência podemos ir mais longe do sucesso.


Relacionados

Mais.