Update mt5-xau-lstm-ppo-stoch-adx-bot.py

This commit is contained in:
Vittus Mikiassen
2026-06-19 13:31:50 +02:00
committed by GitHub
parent dd5943e6b3
commit 619ca34869
+163 -29
View File
@@ -61,7 +61,7 @@ def load_last_mb_xauusd(file_path="C:\\Users\\Vittus Mikiassen\\Desktop\\XAU_5m_
df[col] = pd.to_numeric(df[col], errors='coerce')
df['Date'] = pd.to_datetime(df['Date'])
df.set_index('Date', inplace=True)
df = df[['Open', 'High', 'Low', 'Close']].copy()
df = df[['Open', 'High', 'Low', 'Close', 'Volume']].copy()
# df = df.resample('15min').agg({
# 'Open': 'first',
@@ -285,6 +285,97 @@ def AsiaLowDist(df):
return asia_low - df["Close"]
def VWAP(df, atr_period=14, atr_multiplier=1.0):
# print(type(df.index))
# print(df.index.dtype)
# print(df.index[:5])
# --------------------------------------------------
# Select volume column
# --------------------------------------------------
if "Volume" in df.columns:
volume = df["Volume"]
elif "tick_volume" in df.columns:
volume = df["tick_volume"]
elif "real_volume" in df.columns:
volume = df["real_volume"]
else:
raise ValueError("No volume column found.")
# --------------------------------------------------
# ATR (internal only)
# --------------------------------------------------
prev_close = df["Close"].shift(1)
tr = pd.concat([
df["High"] - df["Low"],
(df["High"] - prev_close).abs(),
(df["Low"] - prev_close).abs()
], axis=1).max(axis=1)
atr = tr.rolling(atr_period).mean()
# --------------------------------------------------
# VWAP
# --------------------------------------------------
typical_price = (
df["High"] +
df["Low"] +
df["Close"]
) / 3
session = df.index.normalize()
cum_tpv = (typical_price * volume).groupby(session).cumsum()
cum_volume = volume.groupby(session).cumsum()
vwap = round(cum_tpv / cum_volume, 2)
upper = round(vwap + atr * atr_multiplier, 2)
lower = round(vwap - atr * atr_multiplier, 2)
# --------------------------------------------------
# Derived features
# --------------------------------------------------
dist = df["Close"] - vwap
above = (df["Close"] > vwap).astype(int)
below = (df["Close"] < vwap).astype(int)
above_upper = (df["Close"] > upper).astype(int)
below_lower = (df["Close"] < lower).astype(int)
slope = vwap.diff()
return (
vwap,
upper,
lower,
dist,
above,
below,
above_upper,
below_lower,
slope
)
def VolumeMA(df, period=14):
# -----------------------------------------
# Select volume column
# -----------------------------------------
if "Volume" in df.columns:
volume = df["Volume"]
elif "tick_volume" in df.columns:
volume = df["tick_volume"]
elif "real_volume" in df.columns:
volume = df["real_volume"]
else:
raise ValueError("No volume column found.")
return round(volume.rolling(period).mean(), 2)
def BuyScore(df):
return (
@@ -297,7 +388,11 @@ def BuyScore(df):
df["bullish_mb"] * 1 +
df["bullish_fvg"] * 1 +
df["eql"] * 1 +
df["bullish_rb"] * 1 -
df["bullish_rb"] * 1 +
df["above_vwap"] * 1 +
df["vwap_above_upper"] * 1 -
df["below_vwap"] * 1 -
df["vwap_below_lower"] * 1 -
df["bearish_rb"] * 1 -
df["bearish_ob"] * 2 -
df["bearish_fvg"] * 1 -
@@ -317,6 +412,10 @@ def SellScore(df):
df["bearish_mb"] * 1 +
df["bearish_fvg"] * 1 +
df["eqh"] * 1 +
df["below_vwap"] * 1 +
df["vwap_below_lower"] * 1 -
df["above_vwap"] * 1 -
df["vwap_above_upper"] * 1 -
df["bearish_rb"] * 1 -
df["bullish_rb"] * 1 -
df["bullish_ob"] * 2 -
@@ -350,14 +449,22 @@ def add_indicators(df):
df["bullish_rb"], df["bearish_rb"] = RejectionBlocks(df)
df["vwap"], df["vwap_upper"], df["vwap_lower"], df["vwap_dist"], df["above_vwap"], df["below_vwap"], df["vwap_above_upper"], df["vwap_below_lower"], df["vwap_slope"] = VWAP(df)
df["sell_score"] = SellScore(df)
df["buy_score"] = BuyScore(df)
df["volume_ma"] = VolumeMA(df)
# df["asia_high_dist"] = AsiaHighDist(df)
# df["asia_low_dist"] = AsiaLowDist(df)
df = df[["Open", "High", "Low", "Close", "k", "k_smooth", "adx", "+di", "-di", "EMA7", "EMA21", "EMA_DIFF",
df = df[["Open", "High", "Low", "Close",
"k", "k_smooth", "adx", "+di", "-di", "EMA7", "EMA21", "EMA_DIFF",
"indecision", "bullish_ob", "bearish_ob", "bullish_fvg", "bearish_fvg", "eqh", "eql", "bearish_mb", "bullish_mb", "bullish_rb", "bearish_rb",
"vwap", "vwap_upper", "vwap_lower", "vwap_dist", "above_vwap", "below_vwap", "vwap_above_upper", "vwap_below_lower", "vwap_slope",
"volume_ma",
# "asia_high_dist", "asia_low_dist",
"sell_score", "buy_score"]].copy()
# df = df[["Open", "High", "Low", "Close", "EMA_crossover", "macd_zone", "macd_line", "macd_signal", "macd_line_diff", "macd_signal_diff", "macd_line_slope", "macd_signal_line_slope" , "macd_osma", "macd_crossover", "bb_sma", "bb_upper", "bb_lower", "RSI_zone", "ADX_zone", "+DI_val", "-DI_val", "ATR", "order_block_type"]].copy()
@@ -956,10 +1063,19 @@ def train_bot(symbol="XAUUSD"):
"bullish_mb",
"bullish_rb",
"bearish_rb",
"vwap",
"vwap_upper",
"vwap_lower",
"above_vwap",
"below_vwap",
"vwap_above_upper",
"vwap_below_lower",
"vwap_slope",
"volume_ma",
# "asia_high_dist",
# "asia_low_dist",
"sell_score",
"buy_score"
# "asia_high_dist",
# "asia_low_dist"
]
agent = LSTMPPOAgent(
@@ -1011,10 +1127,10 @@ def train_bot(symbol="XAUUSD"):
trade_returns = []
# STANDARD_SL_PIPS = 100
RR_RATIO = 0.375
RR_RATIO = 0.5
# SPREAD_AND_COMMISSION = 1.2
# SL_PIPS = 50
SL_PIPS = 40
# TP1_PIPS = 50
# TP2_PIPS = 100
@@ -1040,7 +1156,6 @@ def train_bot(symbol="XAUUSD"):
high = current["High"]
low = current["Low"]
# SL_PIPS = round(current_price * 0.00125 * 10, 0)
SL_PIPS = 40
TP1_PIPS = round(SL_PIPS * RR_RATIO, 0)
# TP2_PIPS = round(SL_PIPS * 2, 0)
# TP3_PIPS = round(SL_PIPS * 3, 0)
@@ -1083,7 +1198,8 @@ def train_bot(symbol="XAUUSD"):
# ==============================================================
# if action == 1 and not in_position and df["+di"].iloc[i] > df["-di"].iloc[i] and df["EMA_DIFF"].iloc[i] > 0 and df["k"].iloc[i] < 80:
if action == 1 and not in_position:
# if action == 1 and not in_position and df["EMA7"].iloc[i] > df["EMA21"].iloc[i] and df["k"].iloc[i] < 80:
if action == 1:
in_position = True
position_type = "long"
@@ -1124,7 +1240,9 @@ def train_bot(symbol="XAUUSD"):
# ==============================================================
# elif action == 2 and not in_position and df["-di"].iloc[i] > df["+di"].iloc[i] and df["EMA_DIFF"].iloc[i] < 0 and df["k"].iloc[i] > 20:
elif action == 2 and not in_position:
# elif action == 2 and not in_position and df["buy_score"].iloc[i] < df["sell_score"].iloc[i]:
# elif action == 2 and not in_position and df["EMA7"].iloc[i] < df["EMA21"].iloc[i] and df["k"].iloc[i] > 20:
elif action == 2:
in_position = True
position_type = "short"
@@ -1497,7 +1615,7 @@ def train_bot(symbol="XAUUSD"):
agent.savecheckpoint(symbol)
# knn._fit()
knn._fit()
# knn.save()
@@ -1513,7 +1631,7 @@ def open_long(symbol, lot_size):
sl = entry - 4
tp1 = entry + 1.5
tp1 = entry + 2
# tp2 = entry + 10
# tp3 = entry + 15
# tp4 = entry + 20
@@ -1549,7 +1667,7 @@ def open_short(symbol, lot_size):
sl = entry + 4
tp1 = entry - 1.5
tp1 = entry - 2
# tp2 = entry - 10
# tp3 = entry - 15
# tp4 = entry - 20
@@ -1706,10 +1824,19 @@ def test_bot(symbol="XAUUSD"):
"bullish_mb",
"bullish_rb",
"bearish_rb",
"vwap",
"vwap_upper",
"vwap_lower",
"above_vwap",
"below_vwap",
"vwap_above_upper",
"vwap_below_lower",
"vwap_slope",
"volume_ma",
# "asia_high_dist",
# "asia_low_dist",
"sell_score",
"buy_score"
# "asia_high_dist",
# "asia_low_dist"
]
# last_m15 = None
@@ -1846,23 +1973,26 @@ def test_bot(symbol="XAUUSD"):
'time': 'Date'
}, inplace=True)
new_row["Date"] = pd.to_datetime(new_row["Date"], unit="s")
new_row.set_index("Date", inplace=True)
if new_row.index[-1] != df.index[-1]:
df = pd.concat(
[df, new_row],
ignore_index=True
)
# df = pd.concat(
# [df, new_row]
# # ignore_index=True
# )
df.set_index("Date", inplace=True)
# df.set_index("Date", inplace=True)
df = (
df.tail(200)
# .reset_index(drop=True)
)
# df = (
# df.tail(200)
# # .reset_index(drop=True)
# )
raw_df = pd.concat(
[raw_df, new_row],
ignore_index=True
[raw_df, new_row]
# ignore_index=True
)
# raw_df = raw_df.tail(200).reset_index(drop=True)
@@ -1870,6 +2000,8 @@ def test_bot(symbol="XAUUSD"):
# print("Before indicators:", len(df))
# df = add_indicators(raw_df.copy())
# print(type(raw_df.index))
# print(raw_df.index[:5])
df = add_indicators(raw_df.copy())
# print("After indicators:", len(df))
# print(df.tail())
@@ -1924,7 +2056,7 @@ def test_bot(symbol="XAUUSD"):
if df["adx"].iloc[-1] < 20:
action = 0
# print(f"action: {action}")
print(f"action: {action}")
# ==================================================
# OPEN NEW TRADE
@@ -1942,6 +2074,7 @@ def test_bot(symbol="XAUUSD"):
# )
# if action == 1 and df["adx"].iloc[-1] > 20 and df["+di"].iloc[-1] > df["-di"].iloc[-1] and df["EMA_DIFF"].iloc[-1] > 0 and df["k"].iloc[-1] < 80:
# if action == 1 and df["buy_score"].iloc[-1] > df["sell_score"].iloc[-1]:
if action == 1:
# print(
# f"[{symbol}] PPO BUY"
@@ -1953,6 +2086,7 @@ def test_bot(symbol="XAUUSD"):
)
# elif action == 2 and df["adx"].iloc[-1] > 20 and df["-di"].iloc[-1] > df["+di"].iloc[-1] and df["EMA_DIFF"].iloc[-1] < 0 and df["k"].iloc[-1] > 20:
# elif action == 2 and df["buy_score"].iloc[-1] < df["sell_score"].iloc[-1]:
elif action == 2:
# print(
# f"[{symbol}] PPO SELL"
@@ -2151,8 +2285,8 @@ def update_xauusd_data():
def main():
# update_xauusd_data()
# train_bot("XAUUSD")
train_bot("XAUUSD")
test_bot(symbol="XAUUSD-VIP")
# test_bot(symbol="XAUUSD-VIP")
main()