Discussão do artigo "Criação de uma estratégia de retorno à média com base em aprendizado de máquina" - página 8

[Excluído]  
sibirqk #:

É claro que não estou convencido, mas usar o Savitsky_Golay não é muito diferente de usar o muve. O filtro SG é o ponto médio de uma regressão polinomial em uma determinada janela deslizante, com um grau de polinômio especificado. Para o grau 1, é uma correspondência perfeita com o muve do período correspondente.

Para identificar o retorno à média, faz mais sentido, na minha opinião, usar a filtragem de amplitude - renko, renji, ziguezagues. Acho que os intervalos são os melhores - a diferença entre Hg e Lw é uma constante. Bem, ou um tamanho constante ZZ, que é basicamente a mesma coisa.

Bem, o ZZ provou ser pior.
[Excluído]  

A decomposição de Fourier e de valor singular se mostram muito bem como filtros. Não me envolvi na seleção de parâmetros, primeiras variantes.


[Excluído]  

Um exemplo de adição de decaimento exponencial ao processo de filtragem, com base na primeira função de marcação do artigo. Os últimos exemplos recebem mais peso na marcação, para ajustar os dados mais recentes.

def get_labels_filter(dataset, rolling=200, quantiles=[.45, .55], polyorder=3, decay_factor=0.95) -> pd.DataFrame:
    """
    Generates labels for a financial dataset based on price deviation from a Savitzky-Golay filter,
    with exponential weighting applied to prioritize recent data.

    Args:
        dataset (pd.DataFrame): DataFrame containing financial data with a 'close' column.
        rolling (int, optional): Window size for the Savitzky-Golay filter. Defaults to 200.
        quantiles (list, optional): Quantiles to define the "reversion zone". Defaults to [.45, .55].
        polyorder (int, optional): Polynomial order for the Savitzky-Golay filter. Defaults to 3.
        decay_factor (float, optional): Exponential decay factor for weighting past data. 
                                        Lower values prioritize recent data more. Defaults to 0.95.

    Returns:
        pd.DataFrame: The original DataFrame with a new 'labels' column and filtered rows:
                       - 'labels' column: 
                            - 0: Buy
                            - 1: Sell
                       - Rows where 'labels' is 2 (no signal) are removed.
                       - Rows with missing values (NaN) are removed.
                       - The temporary 'lvl' column is removed. 
    """

    # Calcular preços suavizados usando o filtro Savitzky-Golay
    smoothed_prices = savgol_filter(dataset['close'].values, window_length=rolling, polyorder=polyorder)
    
    # Calcule a diferença entre os preços de fechamento reais e os preços suavizados
    diff = dataset['close'] - smoothed_prices
    
    # Aplicar ponderação exponencial aos valores "diff".
    weighted_diff = diff * np.exp(np.arange(len(diff)) * decay_factor / len(diff)) 
    dataset['lvl'] = weighted_diff # Adicione a diferença ponderada como 'lvl'

    # Remova todas as linhas com valores NaN 
    dataset = dataset.dropna()
    
    # Calcular os quantis da coluna "lvl" (desvio de preço)
    q = dataset['lvl'].quantile(quantiles).to_list() 

    # Extraia os preços de fechamento e os valores "lvl" calculados como matrizes NumPy
    close = dataset['close'].values
    lvl = dataset['lvl'].values
    
    # Calcule os rótulos de compra/venda usando a função "calculate_labels_filter". 
    labels = calculate_labels_filter(close, lvl, q) 

    # Corte o conjunto de dados para corresponder ao comprimento dos rótulos calculados
    dataset = dataset.iloc[:len(labels)].copy()
    
    # Adicione os rótulos calculados como uma nova coluna "rótulos" ao DataFrame
    dataset['labels'] = labels
    
    # Remova todas as linhas com valores NaN
    dataset = dataset.dropna()
    
    # Remova as linhas em que a coluna "labels" tenha um valor de 2,0 (sinais de venda)
    dataset = dataset.drop(dataset[dataset.labels == 2.0].index)
    
    # Retorna o DataFrame modificado com a coluna "lvl" removida
    return dataset.drop(columns=['lvl'])


  • O parâmetro decay_factor (padrão 0,95) é adicionado ao código para controlar o peso dado aos dados anteriores.
  • Para cada ponto de dados, calculamos o peso usando np.exp(np.exp(np.arange(len(diff))) * decay_factor / len(diff)) e o multiplicamos pelos valores de diferença. Isso dá mais peso às diferenças recentes e menos peso às mais antigas. Coluna 'lvl' ponderada: a coluna lvl agora armazena diferenças ponderadas exponencialmente, tornando o processo de marcação mais sensível aos movimentos recentes de preço.
  • Um valor menor de decay_factor (mais próximo de 0) tornará a ponderação mais agressiva, destacando mais as alterações recentes de preço. Isso significa que o algoritmo reagirá mais rapidamente a desvios recentes da tendência de preço suavizada.
  • Um valor maior de decay_factor (mais próximo de 1) levará a uma ponderação mais suave, dando mais peso aos dados anteriores. Isso pode ser útil para reduzir a influência do ruído de curto prazo e identificar tendências de longo prazo.
[Excluído]  

Para treinamento em intervalos mais curtos, por exemplo, de 2018 a 2024, poucas negociações podem ser obtidas se n_clusters = 10 nos hiperparâmetros. Reduzir o número de clusters, por exemplo, para 5-3, ajuda a obter mais negociações.

Dessa forma, você pode treinar em períodos de tempo mais curtos e procurar bons padrões neles variando diferentes parâmetros.

Você também pode reduzir os períodos de filtro (filtro Savitzky-Golei ou splines) dos amostradores de negociações.


 
Olá, Max! Estou escrevendo para dizer que estou ansioso pelos artigos de "Maxim Dmitrievsky". Estudo cada artigo que você publica, tenho acompanhado de perto seu trabalho nos últimos 2 anos. Sou do Brasil, estudo e aprendo algo novo e valioso.

Espero do fundo do meu coração que você, Maxim, continue compartilhando pesquisas de conhecimento e que a equipe da MetaQuotes o valorize como um autor respeitado e "compartilhe os lucros" para incentivá-lo a continuar o trabalho incrível. Espero que você seja o melhor, Maxim!

Por favor, @MetaQuotes e a equipe @MetaQuotes @alexx, dêem um aumento a esse cara! Ele merece <3

Saudações do Brasil
Maxim Dmitrievsky
Maxim Dmitrievsky
  • 2025.03.07
  • www.mql5.com
Профиль трейдера
[Excluído]  
Vinicius Barenho Pereira #:
Olá, Max! Estou escrevendo para dizer que estou ansioso pelos artigos de "Maxim Dmitrievsky". Estudo cada artigo que você publica, tenho acompanhado de perto seu trabalho nos últimos 2 anos. Sou do Brasil, estudo e aprendo algo novo e valioso.

Espero do fundo do meu coração que você, Maxim, continue compartilhando pesquisas de conhecimento e que a equipe da MetaQuotes o valorize como um autor respeitado e "compartilhe os lucros" para incentivá-lo a continuar o trabalho incrível. Espero que você seja o melhor, Maxim!

Por favor, @MetaQuotes e a equipe @MetaQuotes @alexx, dêem um aumento a esse cara! Ele merece <3

Saudações do Brasil

Obrigado, tentarei fazer algo interessante e talvez útil no futuro :)

 

Isso é ótimo: no final do artigo, será possível treinar diferentes modelos de aprendizado de máquina em Python e convertê-los em sistemas de negociação para o terminal de negociação MetaTrader 5.

Vou dar uma olhada nisso com mais detalhes - obrigado pelo artigo!

[Excluído]  
Roman Shiredchenko modelos de aprendizado de máquina em Python e convertê-los em sistemas de negociação para o terminal de negociação MetaTrader 5.

Vou dar uma olhada nisso com mais detalhes - obrigado pelo artigo!

De nada, às vezes eles até ganham dinheiro )
 

Olá, Maxim,

Encontrei um problema com a geração de valores na função get_features em Python e no MetaTrader 5.

O problema está na estatística "skew" em Python e "skewness" em MQL5. A partir dos testes que realizei, os valores gerados pelas duas linguagens são ligeiramente diferentes. Por exemplo:

-0.087111
Em MQL5, e
-0.092592
Em Python

Pode parecer pouco, mas, após a classificação dos meta_labels, isso leva a uma previsão atrasada, fazendo com que o EA geralmente entre com uma vela de atraso, o que torna a estratégia ineficaz. Recomendo não usar essa estatística na MQL5 ou tentar calculá-la manualmente para obter os mesmos valores.

Saudações do Brasil

[Excluído]  
KleversonGerhardt #:

Olá Maxim,

Encontrei um problema com a geração de valores na função get_features em Python e no MetaTrader 5.

O problema está na estatística "skew" em Python e "skewness" em MQL5. A partir dos testes que realizei, os valores gerados pelas duas linguagens são ligeiramente diferentes. Por exemplo:

-0.087111
Em MQL5, e
-0.092592
Em Python

Pode parecer pouco, mas, após a classificação dos meta_labels, isso leva a uma previsão atrasada, fazendo com que o EA geralmente entre com uma vela de atraso, o que torna a estratégia ineficaz. Recomendo não usar essa estatística na MQL5 ou tentar calculá-la manualmente para obter os mesmos valores.

Saudações do Brasil

Olá, obrigado! Vou verificar isso.