Ao contrário de outros indicadores técnicos,
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.
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.
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.
Passo 3: Calcular o valor de emissão
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
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.main
função e umonTick
Amain
função é a função de entrada da estratégia, e o programa executará a linha de código por linha a partir domain
A funçãomain
função, escrever umwhile
ciclo e executar repetidamente oonTick
Todos 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_position
Se 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 oSetContractType
função deFMZ.COMSe você quiser saber outras informações sobre o contrato, você também pode usar uma variável para receber esses dados.GetRecords
função para obter dados de linha K, porque o devolvido é uma matriz, então usamos a variávelbars_arr
para 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_position
Finalmente, a posição é aberta e fechada de acordo com a relação posicional entre o EMV e o eixo zero.
Configuração de teste de retorno
Registo dos testes de regresso
Curva do capital
# 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
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.