import numpy as np
import MetaTrader5 as mt5
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import Dense
import time
from keras.utils import to_categorical
import threading
class ForexPredictor:
def __init__(
self,
symbol,
timeframe,
pattern_length,
balancerisk=0.03,
risklevel=1 / 3,
magic=1,
num_bars=1000,
epochs=20,
batch_size=32,
prediction_interval=0.001,
):
self.balancerisk = balancerisk
self.risklevel = risklevel
self.magic = magic
self.connected = False
self.symbol = symbol
self.timeframe = timeframe
self.pattern_length = pattern_length
self.model = None
self.scaler = MinMaxScaler()
self.connect_to_mt5()
self.last_bar_time = None # To track the last processed bar time
self.operate()
def connect_to_mt5(self):
resp = mt5.initialize(
login=REDACTED, password=REDACTED, server=REDACTED
)
if resp:
self.connected = True
return self.connected
def calculate_ema(self, prices, period, shift=0):
"""
Calculate the Exponential Moving Average (EMA) for a given period.
:param prices: List or array of closing prices.
:param period: EMA calculation period.
:param shift: Number of bars to shift the EMA forward.
:return: List of EMA values, shifted if required.
"""
if not prices or len(prices) < period:
raise ValueError("Not enough data points to calculate EMA.")
# Calculate the multiplier
multiplier = 2 / (period + 1)
# Initialize the EMA with the first price
ema_values = [prices[0]] # Seed value is the first price
print(ema_values)
# Compute EMA for the rest of the prices
for price in prices[1:]:
ema = (price * multiplier) + (ema_values[-1] * (1 - multiplier))
ema_values.append(ema)
# Apply shift if required
if shift > 0:
ema_values = [None] * shift + ema_values[:-shift] # Shift values forward
ema_values = ema_values[::-1]
return ema_values
def get_bars(self, pos=0, quantity=1):
"""
Retrieve multiple bars from the MT5 API and calculate 8EMA and 20EMA.
:param pos: Position to start retrieving bars from.
:param quantity: Number of bars to retrieve with EMA values.
:return: DataFrame containing the requested bars with EMA values.
"""
# Calculate how many extra bars are needed for EMA
max_ema_period = 20 # The longest EMA period used
extra_bars = max_ema_period - 1 # Extra bars needed for EMA calculation
total_bars = quantity + extra_bars
# Fetch bars from MT5
bars = mt5.copy_rates_from_pos(self.symbol, self.timeframe, pos, total_bars)
if bars is None or len(bars) < total_bars:
print("Not enough data to fetch the required bars.")
return None
# Convert to DataFrame
bars = pd.DataFrame(bars[::-1]) # Reverse the order
bars["time"] = pd.to_datetime(bars["time"], unit="s")
bars.set_index("time", inplace=True)
# Calculate 8EMA and 20EMA using the full dataset
close_prices = bars["close"].tolist()
bars["8ma"] = self.calculate_ema(prices=close_prices, period=8)
bars["20ma"] = self.calculate_ema(prices=close_prices, period=20)
# Return only the requested number of bars
return bars.iloc[:quantity]
def operate(self):
update = "None"
print(self.get_bars(0, 3))
return
targets = [
{
"symbol": "GBPUSD",
"timeframe": mt5.TIMEFRAME_M1,
"pattern_length": 25,
"balancerisk": 0.03,
"risklevel": 1 / 2,
"magic": 1,
"num_bars": 90000,
"epochs": 20,
"batch_size": 32,
"prediction_interval": 0.001,
}
]
# Usage:
if __name__ == "__main__":
for pair in targets:
threading.Thread(
target=ForexPredictor,
args=(
pair["symbol"],
pair["timeframe"],
pair["pattern_length"],
pair["balancerisk"],
pair["risklevel"],
pair["magic"],
pair["num_bars"],
pair["epochs"],
pair["batch_size"],
pair["prediction_interval"],
),
).start()
Обратите внимание на функцию Calculate_ema. и функция get_bars. Я просто получаю неточные/неправильные значения.
Мне нужны значения экспоненциальной скользящей средней для количества баров, запрошенного в функции get_bars. Я хочу получить доступ к 8MA и 20MA для запрошенного количества баров. Даже если это количество всего 1. Таким образом, функция запрашивает как минимум 20 баров, чтобы это можно было вычислить. Однако значения, которые я получаю для 8MA и 20MA, не совпадают со значениями моего индикатора Moving Average MT5 в экспоненциальном режиме (при закрытии).
Заранее спасибо.
Где я ошибаюсь... Вот мой код Python, который взаимодействует с API MetaTrader5. [code]import numpy as np import MetaTrader5 as mt5 import pandas as pd from sklearn.preprocessing import MinMaxScaler from keras.models import Sequential from keras.layers import Dense import time from keras.utils import to_categorical import threading
class ForexPredictor: def __init__( self, symbol, timeframe, pattern_length, balancerisk=0.03, risklevel=1 / 3, magic=1, num_bars=1000, epochs=20, batch_size=32, prediction_interval=0.001, ): self.balancerisk = balancerisk self.risklevel = risklevel self.magic = magic self.connected = False self.symbol = symbol self.timeframe = timeframe self.pattern_length = pattern_length self.model = None self.scaler = MinMaxScaler() self.connect_to_mt5() self.last_bar_time = None # To track the last processed bar time self.operate()
def calculate_ema(self, prices, period, shift=0): """ Calculate the Exponential Moving Average (EMA) for a given period.
:param prices: List or array of closing prices. :param period: EMA calculation period. :param shift: Number of bars to shift the EMA forward. :return: List of EMA values, shifted if required. """ if not prices or len(prices) < period: raise ValueError("Not enough data points to calculate EMA.")
# Initialize the EMA with the first price ema_values = [prices[0]] # Seed value is the first price print(ema_values) # Compute EMA for the rest of the prices for price in prices[1:]: ema = (price * multiplier) + (ema_values[-1] * (1 - multiplier)) ema_values.append(ema)
# Apply shift if required if shift > 0: ema_values = [None] * shift + ema_values[:-shift] # Shift values forward
ema_values = ema_values[::-1]
return ema_values
def get_bars(self, pos=0, quantity=1): """ Retrieve multiple bars from the MT5 API and calculate 8EMA and 20EMA. :param pos: Position to start retrieving bars from. :param quantity: Number of bars to retrieve with EMA values. :return: DataFrame containing the requested bars with EMA values. """ # Calculate how many extra bars are needed for EMA max_ema_period = 20 # The longest EMA period used extra_bars = max_ema_period - 1 # Extra bars needed for EMA calculation total_bars = quantity + extra_bars
# Fetch bars from MT5 bars = mt5.copy_rates_from_pos(self.symbol, self.timeframe, pos, total_bars) if bars is None or len(bars) < total_bars: print("Not enough data to fetch the required bars.") return None
# Convert to DataFrame bars = pd.DataFrame(bars[::-1]) # Reverse the order bars["time"] = pd.to_datetime(bars["time"], unit="s") bars.set_index("time", inplace=True)
# Calculate 8EMA and 20EMA using the full dataset close_prices = bars["close"].tolist() bars["8ma"] = self.calculate_ema(prices=close_prices, period=8) bars["20ma"] = self.calculate_ema(prices=close_prices, period=20)
# Return only the requested number of bars return bars.iloc[:quantity]
# Usage: if __name__ == "__main__": for pair in targets: threading.Thread( target=ForexPredictor, args=( pair["symbol"], pair["timeframe"], pair["pattern_length"], pair["balancerisk"], pair["risklevel"], pair["magic"], pair["num_bars"], pair["epochs"], pair["batch_size"], pair["prediction_interval"], ), ).start()
[/code] Обратите внимание на функцию Calculate_ema. и функция get_bars. Я просто получаю неточные/неправильные значения. Мне нужны значения экспоненциальной скользящей средней для количества баров, запрошенного в функции get_bars. Я хочу получить доступ к 8MA и 20MA для запрошенного количества баров. Даже если это количество всего 1. Таким образом, функция запрашивает как минимум 20 баров, чтобы это можно было вычислить. Однако значения, которые я получаю для 8MA и 20MA, не совпадают со значениями моего индикатора Moving Average MT5 в экспоненциальном режиме (при закрытии). Заранее спасибо.
У меня есть следующий список из 20 значений:
values =
Чтобы найти экспоненциальное скользящее среднее по диапазону из 9 значений, я могу сделать на Python следующее:
def calculate_ema(values, periods, smoothing=2):
ema = [sum(values ) /...
Я создаю текстовый файл, который будет использоваться в качестве входного файла FORTRAN. Программа FORTRAN указывает, что считываемые значения должны быть в таком формате, что