SuperTrend V.1 - Sistema de linha de tendência super

Autora:homilha, Criado: 2020-04-20 22:10:36, Atualizado: 2023-10-08 19:57:57

img

Primeiro, a origem da história

O meu bom amigo Vago observou este indicador durante muito tempo e recomendou-mo antes do Ano Novo para discutir se poderia ser convertido em quantidade. O problema é que o procrastinador se culpou e não conseguiu fazer isso até agora, mas o conhecimento dos algoritmos também aumentou rapidamente recentemente. A expectativa é que um dia escreva um tradutor de pinos. Tudo pode ser feito em Python. Para acabar com essa treta, vamos dar uma olhada na super-trend line da lenda.

II. Introdução ao sistema

CMC Markets nova geração de sistema de negociação inteligente SupertrendO sistema foi desenvolvido em parceria com o Google e o Google Maps.img

A nova geração de sistemas inteligentes de negociação na CMC Markets, com a opção de seleção de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis de níveis. Como mostrado no gráfico, pode-se ajustar a cor da cor e o detalhe grosseiro dos sinais de subida e de queda de acordo com as suas preferências. Então, o que é um indicador de supertrend? Antes de entender a fórmula do indicador de supertrend, é necessário entender o ATR, porque o supertrend usa o valor do ATR para calcular o valor do indicador.

Os principais algoritmos são descritos abaixo.img

Em termos gerais, a principal descrição é o canal HL2 (k linha média de preços) multiplicado por n vezes ATR. Mas o artigo é mais simples. Não há algoritmos detalhados. Então eu pensei na comunidade mais popular, Tradingview. Não é surpreendente.img

A partir do gráfico, parece ser uma tendência mais acertada. Mas infelizmente, é apenas um sinal de alerta do Alert.

Terceiro, aprender código fonte.

Se o código não for muito longo, vamos traduzir e tentar.imgO código completo do pine está aqui.

Quatro, tradução de código.

Aqui, no FMZ, criamos uma nova estratégia chamada SuperTrade.img

Então, vamos definir dois parâmetros, Factor, Pd.img

Para melhorar a operação do código simplificado e fácil de entender, é necessário usar o pacote de extensão de dados avançado do Python.Pandas

Durante o almoço, perguntei à professora se a FMZ apoiava a biblioteca. A professora de sonho é muito boa.

1.我们要导入pandas库time库 2.在main函数当中设置使用季度合约(主要跑okex) 3. Configure um ciclo doTicker para 15 minutos de detecção 1 vez.Elas executam o código em ciclos de 15 minutos. Depois, nós escrevemos as principais estratégias no doTicker.

import pandas as pd
import time

def main():
    exchange.SetContractType("quarter")
    preTime = 0
    Log(exchange.GetAccount())
    while True:
        records = exchange.GetRecords(PERIOD_M15)
        if records and records[-2].Time > preTime:
            preTime = records[-2].Time
            doTicker(records[:-1])
        Sleep(1000 *60)
        

Então nós vamos usar GetRecords para obter o OHCLV da linha k. 5. Vamos importar os dados recuperados para o panda M15 = pd.DataFrame (records) M15.columns = [time,open,high,low,close,volume,OpenInterest]A primeira letra de "open", "high", "low" e "close" são substituídas por letras minúsculas para facilitar a escrita do código.

def doTicker(records):
    M15 = pd.DataFrame(records)
    M15.columns = ['time','open','high','low','close','volume','OpenInterest']  

7. Adicionar uma coluna para o conjunto de dados.

#HL2
M15['hl2']=(M15['high']+M15['low'])/2

8.接着我们来计算ATRComo o cálculo do ATR é para importar um comprimento de variável, o seu valor é Pd

Em seguida, passamos ao manual da língua Ma, e os passos do algoritmo para obter o valor médio da amplitude real de oscilação do ATR são: TR: MAX (MAX (HIGH-LOW), ABS (REF (CLOSE, 1) -HIGH), ABS (REF (CLOSE, 1) -LOW); ATR: RMA (TR, N)

O valor TR é o maior dos três valores abaixo. 1, o intervalo entre o preço mais alto e o preço mais baixo do dia de negociação atual 2, o intervalo entre o preço de fechamento do dia anterior e o preço mais alto do dia anterior REF ((CLOSE, 1) - HIGH) 3, o intervalo entre o preço de fechamento do dia anterior e o preço mais baixo do dia anterior REF ((CLOSE, 1) - LOW) Então TR: MAX (MAX (HIGH-LOW), ABS (REF (CLOSE, 1) -HIGH), ABS (REF (CLOSE, 1) -LOW));

Computação em Python

M15['prev_close']=M15['close'].shift(1)

Para obter dados da linha anterior, é preciso definir um prev_close, ou seja, mover 1 para a direita da grelha para criar um novo parâmetro.

ranges= [M15['high'] - M15['low'],M15['high']-M15['prev_close'],M15['low']-M15['prev_close']]

Em seguida, defina uma variável intermediária que regista a matriz de três valores de comparação de TR.

M15['tr'] = pd.DataFrame(ranges).T.abs().max(axis=1)

Nós definimos uma nova coluna denominada TR no conjunto de dados, tomando o valor de TR como o maior dos valores absolutos da variável intermediária, usando as funções abs (()) e max (()).

    alpha = (1.0 / length) if length > 0 else 0.5
    M15['atr']=M15['tr'].ewm(alpha=alpha, min_periods=length).mean()

Finalmente, vamos calcular o valor do ATR, ATR: RMA ((TR,N), que, de acordo com o algoritmo do RMA, é um algoritmo EMA de variação de valor fixo. N é a variável que importamos, onde o parâmetro padrão do ATR é 14; aqui nós importamos o decimal de alfa = length.

===

Em seguida, você pode calcular a eima usando o algoritmo ewm.O processo completo de cálculo do ATR é o seguinte:

    #ATR(PD)
    length=Pd
    M15['prev_close']=M15['close'].shift(1)
    ranges= [M15['high'] - M15['low'],M15['high']-M15['prev_close'],M15['low']-M15['prev_close']]
    M15['tr'] = pd.DataFrame(ranges).T.abs().max(axis=1)
    alpha = (1.0 / length) if length > 0 else 0.5
    M15['atr']=M15['tr'].ewm(alpha=alpha, min_periods=length).mean()

9 Computação inicial Up e Dn

    M15['Up']=M15['hl2']-(Factor*M15['atr'])
    M15['Dn']=M15['hl2']+(Factor*M15['atr'])

Up=hl2 - ((Factor * atr) Dn = hl2 + ((Factor * atr)) O que você está fazendo aqui é muito simples.

Abaixo estão os trechos de código do núcleo das 15-21 linhas da TV.

TrendUp=close[1]>TrendUp[1]? max(Up,TrendUp[1]) : Up
TrendDown=close[1]<TrendDown[1]? min(Dn,TrendDown[1]) : Dn

Trend = close > TrendDown[1] ? 1: close< TrendUp[1]? -1: nz(Trend[1],1)
Tsl = Trend==1? TrendUp: TrendDown

linecolor = Trend == 1 ? green : red

O principal objetivo deste texto é expressar que a maioria dos blogueiros não tem conhecimento da realidade do país. Se estiver no estágio de crescimento, o (baixo) TrendUp = max (Up, TrendUp[1]) Se estiver em fase de queda, (línea superior) TrendDown=min (Dn, TrendDown[1])Ou seja, em uma tendência, o valor do ATR tem usado uma técnica semelhante à estratégia do robô Brin. O outro lado do corredor está sempre a ser estreito.

Aqui, o TrendUp e o TrendDown precisam de uma auto-repetência para cada cálculo. O que eu quero dizer é que, para cada passo, você deve fazer o cálculo do passo anterior. Por isso, é preciso fazer um circuito no conjunto de dados.

Aqui, o primeiro passo é criar novos campos para o conjunto de dados: TrendUp, TrendDown, Trend, linecolor e dar-lhes um valor inicial. Em seguida, a sintaxe fillna ((0) preenche 0 com dados com valores vazios nos resultados calculados anteriormente.

    M15['TrendUp']=0.0
    M15['TrendDown']=0.0
    M15['Trend']=1
    M15['Tsl']=0.0
    M15['linecolor']='Homily'
    M15 = M15.fillna(0)

Ativar um loop for A terceira operação do Python no ciclo

    for x in range(len(M15)):

Computação TrendUpTrendUp = MAX ((Up, TrendUp[-1]) if close [-1]>TrendUp[-1] else Up Isso significa que se o último close> o último TrendUp, o maior valor entre o último TrendUp e o último TrendUp, não é o valor do Up, e é passado para o TrendUp atual.

        M15['TrendUp'].values[x] = max(M15['Up'].values[x],M15['TrendUp'].values[x-1]) if (M15['close'].values[x-1]>M15['TrendUp'].values[x-1]) else M15['Up'].values[x]

Paralelo, calcular o TrendDown.TrendDown=min ((Dn, TrendDown[-1]) if close[-1]

        M15['TrendDown'].values[x] = min(M15['Dn'].values[x],M15['TrendDown'].values[x-1]) if (M15['close'].values[x-1]<M15['TrendDown'].values[x-1]) else M15['Dn'].values[x]

Abaixo está a bandeira para calcular a direção do controle, e eu simplifiquei o pseudo código.Tendência= 1 se (fechar > Tendência Baixa[-1]) caso contrário (x) x = -1 se (fechado< Tendência de subida[-1]) caso contrário Tendência[-1]

O que significa é que se o preço de fechamento > um TrendDown anterior, tomar 1 (ver mais) não é válido para tomar x. Se o preço de fechamento < um TrendUp anterior, pegue -1 ((vazio) não se estabelece pegue uma Tendência (significa invariável) Traduzido para a linguagem de imagem é que a transmissão de flags de conversão de tração é mais, a transmissão de flags de conversão de tração de tração é menos, o resto do tempo não muda.

        M15['Tsl'].values[x] = M15['TrendUp'].values[x] if  (M15['Trend'].values[x]==1) else M15['TrendDown'].values[x]

Computação de Tsl e LinecolorTsl = rendUp if (Trend==1) else TrendDown Tsl é usado para indicar o valor de SuperTrend em uma imagem. Isto significa que o gráfico é marcado para baixo quando se vê mais e para cima quando se vê menos. linecolor= green if (Trend==1) else red linecolor significa linha verde se você vê mais, linha em branco se você vê pouco (principalmente para mostrar o Tradingview)

        M15['Tsl'].values[x] = M15['TrendUp'].values[x] if  (M15['Trend'].values[x]==1) else M15['TrendDown'].values[x]
        M15['linecolor'].values[x]= 'green' if ( M15['Trend'].values[x]==1) else  'red'

As linhas 23-30 de código seguem-se principalmente para plots, mas não há detalhes.

Finalmente, há duas linhas de código para o controle de sinal de compra e venda.Em Tradingview, o que ele quer dizer é que ele reverteu o Flag e depois deu um sinal. Converte a declaração condicional para Python. Se a última bandeira de tendência passou de -1 para 1 significa que a resistência está acima. Se a última bandeira de tendência passar de 1 para -1 significa que o suporte está aberto.

    if(M15['Trend'].values[-1] == 1 and M15['Trend'].values[-2] == -1):
        Log('SuperTrend V.1 Alert Long',"Create Order Buy)
    if(M15['Trend'].values[-1] == -1 and M15['Trend'].values[-2] == 1):
        Log('SuperTrend V.1 Alert Long',"Create Order Sell)

O código completo para este parágrafo é o seguinte:

    M15['TrendUp']=0.0
    M15['TrendDown']=0.0
    M15['Trend']=1
    M15['Tsl']=0.0
    M15['linecolor']='Homily'
    M15 = M15.fillna(0)
    
    for x in range(len(M15)):
        M15['TrendUp'].values[x] = max(M15['Up'].values[x],M15['TrendUp'].values[x-1]) if (M15['close'].values[x-1]>M15['TrendUp'].values[x-1]) else M15['Up'].values[x]
        M15['TrendDown'].values[x] = min(M15['Dn'].values[x],M15['TrendDown'].values[x-1]) if (M15['close'].values[x-1]<M15['TrendDown'].values[x-1]) else M15['Dn'].values[x]
        M15['Trend'].values[x] = 1 if (M15['close'].values[x] > M15['TrendDown'].values[x-1]) else ( -1 if (M15['close'].values[x]< M15['TrendUp'].values[x-1])else M15['Trend'].values[x-1] )
        M15['Tsl'].values[x] = M15['TrendUp'].values[x] if  (M15['Trend'].values[x]==1) else M15['TrendDown'].values[x]
        M15['linecolor'].values[x]= 'green' if ( M15['Trend'].values[x]==1) else  'red'
        
    if(M15['Trend'].values[-1] == 1 and M15['Trend'].values[-2] == -1):
        Log('SuperTrend V.1 Alert Long',"Create Order Buy)
        Log('Tsl=',Tsl)
    if(M15['Trend'].values[-1] == -1 and M15['Trend'].values[-2] == 1):
        Log('SuperTrend V.1 Alert Long',"Create Order Sell)
        Log('Tsl=',Tsl)

img img

Cinco, todo o código.

Eu ajustei a estrutura de código geral. O projeto também inclui a inclusão de uma lista de pedidos de emprego para a estratégia. Abaixo está o código completo.

'''backtest
start: 2019-05-01 00:00:00
end: 2020-04-21 00:00:00
period: 15m
exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}]
'''

import pandas as pd
import time

def main():
    exchange.SetContractType("quarter")
    preTime = 0
    Log(exchange.GetAccount())
    while True:
        records = exchange.GetRecords(PERIOD_M15)
        if records and records[-2].Time > preTime:
            preTime = records[-2].Time
            doTicker(records[:-1])
        Sleep(1000 *60)

       
def doTicker(records):
    #Log('onTick',exchange.GetTicker())
    M15 = pd.DataFrame(records)

    #Factor=3
    #Pd=7
    
    M15.columns = ['time','open','high','low','close','volume','OpenInterest']  
    
    #HL2
    M15['hl2']=(M15['high']+M15['low'])/2

    #ATR(PD)
    length=Pd
    M15['prev_close']=M15['close'].shift(1)
    ranges= [M15['high'] - M15['low'],M15['high']-M15['prev_close'],M15['low']-M15['prev_close']]
    M15['tr'] = pd.DataFrame(ranges).T.abs().max(axis=1)
    alpha = (1.0 / length) if length > 0 else 0.5
    M15['atr']=M15['tr'].ewm(alpha=alpha, min_periods=length).mean()


    M15['Up']=M15['hl2']-(Factor*M15['atr'])
    M15['Dn']=M15['hl2']+(Factor*M15['atr'])
    
    M15['TrendUp']=0.0
    M15['TrendDown']=0.0
    M15['Trend']=1
    M15['Tsl']=0.0
    M15['linecolor']='Homily'
    M15 = M15.fillna(0)

    for x in range(len(M15)):
        M15['TrendUp'].values[x] = max(M15['Up'].values[x],M15['TrendUp'].values[x-1]) if (M15['close'].values[x-1]>M15['TrendUp'].values[x-1]) else M15['Up'].values[x]
        M15['TrendDown'].values[x] = min(M15['Dn'].values[x],M15['TrendDown'].values[x-1]) if (M15['close'].values[x-1]<M15['TrendDown'].values[x-1]) else M15['Dn'].values[x]
        M15['Trend'].values[x] = 1 if (M15['close'].values[x] > M15['TrendDown'].values[x-1]) else ( -1 if (M15['close'].values[x]< M15['TrendUp'].values[x-1])else M15['Trend'].values[x-1] )
        M15['Tsl'].values[x] = M15['TrendUp'].values[x] if  (M15['Trend'].values[x]==1) else M15['TrendDown'].values[x]
        M15['linecolor'].values[x]= 'Long' if ( M15['Trend'].values[x]==1) else  'Short'
 

    linecolor=M15['linecolor'].values[-2]
    close=M15['close'].values[-2]
    Tsl=M15['Tsl'].values[-2] 


    if(M15['Trend'].values[-1] == 1 and M15['Trend'].values[-2] == -1):

        Log('SuperTrend V.1 Alert Long','Create Order Buy')
        Log('Tsl=',Tsl)
        position = exchange.GetPosition()
        if len(position) > 0:
            Amount=position[0]["Amount"]
            exchange.SetDirection("closesell")
            exchange.Buy(_C(exchange.GetTicker).Sell*1.01, Amount);
        
        exchange.SetDirection("buy")
        exchange.Buy(_C(exchange.GetTicker).Sell*1.01, vol);

    if(M15['Trend'].values[-1] == -1 and M15['Trend'].values[-2] == 1):
        Log('SuperTrend V.1 Alert Long','Create Order Sell')
        Log('Tsl=',Tsl)
        position = exchange.GetPosition()
        if len(position) > 0:
            Amount=position[0]["Amount"]
            exchange.SetDirection("closebuy")
            exchange.Sell(_C(exchange.GetTicker).Buy*0.99,Amount);
        exchange.SetDirection("sell")
        exchange.Sell(_C(exchange.GetTicker).Buy*0.99, vol*2);

Ligação de estratégia pública https://www.fmz.com/strategy/200625

6. Reavaliação e resumo

A pesquisa foi realizada em uma base de dados de cerca de um ano. Usando o contrato trimestral okx em ciclos de 15 minutos. O parâmetro definido é Factor é igual a 3. Pd é igual a 45. Vol = 100 (por cada pedido) A taxa de crescimento anual é de cerca de 33%. A retirada não foi grande em geral. A queda do 312 causou um grande impacto no sistema, mas não foi suficiente. O resultado seria muito melhor se não houvesse o 312.

img

Seis, escrito no final.

SuperTrend é um sistema de negociação muito bom.

O principal princípio do sistema SuperTrend é a adoção de estratégias de ruptura do canal ATR (semelhante ao canal de Kent) Mas o que mudou foi principalmente o uso da estratégia de estreitamento do ladrão Brin, ou seja, o princípio inverso de Dongjian. O canal de acesso é cada vez mais estreito. Para atingir a operação de rotação de ruptura do canal.

Eu fiz o up dn TrendUp TrendDn em TradingView. A partir daí, a estratégia é melhor compreendida.A primeira coisa.img

Além disso, há uma versão do js no github. Eu não sei muito sobre o js, mas parece que há um problema com a seção. O endereço éhttps://github.com/Dodo33/gekko-supertrend-strategy/blob/master/Supertrend.js

Por fim, fui procurar o original. Foi publicado em 29.05.2013. Autor: Rajandran R. Código C++ publicado no fórum Mt4https://www.mql5.com/en/code/viewcode/10851/128437/Non_Repainting_SuperTrend.mq4Eu entendi o que significa C++ e tive a oportunidade de reescrever mais um.

O que eu quero dizer é que, se você quiser, você pode usar a sua experiência. Não é fácil.


Relacionados

Mais.

ZDG4484YYDS!

Glydz2010Se você usar essa estratégia diretamente no OK Exchange, você não vai entender como conectar a troca.

BamsmenAqui, se a onda de 312 não for suficiente, o parâmetro deve ter muito espaço para ajustes, porque o supertrend é principalmente para pegar a lista de tendências.

Zhang não se importaAfinal de contas, o que eu quero dizer com isso é que, se você não tem um sistema de controle de tempo, você não tem um sistema de controle de tempo, mas você tem um sistema de controle de tempo, então você não tem um sistema de controle de tempo.

É gordo.Sim, resolvi, obrigado pela ajuda.

É gordo.Não pode ser usado, mostra isto:Traceback (most recent call last): File "", line 1473, in Run File "", line 8, in ImportError: No module named pandas

Xunfeng91A tradução de Pine, esperando

tempoA cultura não tem nada a ver com o que se diz: "Bob!"

Frank131419O que você está tentando fazer é escrever um tradutor de pinos. Tudo em Python.

Kmeans (médio)Se o código do mecanismo de repetição é aberto, eu quero implementar a repetição e depois usar o svm para encontrar os melhores parâmetros.

DsaidasiO sistema parece ter sido uma estratégia de futuros para os dez maiores rendimentos.

Nuvens levesOlá, por favor, PD é o valor de comprimento de ATR?

Sonhos pequenosAbençoado

OvelhasA expectativa é a expectativa, Pine realmente não entende muito, e há poucas dicas.

homilhaIsso significa que o seu sistema pode precisar de Pip para instalar Pandas

Ant_SkyComo é que isto foi resolvido?

homilhaAh-ha-ha, obrigado chefe.

Sonhos pequenosPor um momento, aberta.

homem solitárioPeça a versão JS!

homilhaNão, não.

Nuvens levesMuito bem, obrigado! O mq4 também foi retirado, obrigado.

homilhaSim, é verdade.

homilhaGlorificado seja!

Sonhos pequenosAcontece que eu também escrevi uma versão em JS.

homilhaObrigada, professora Dream Dream.