Files
AlphaFlow-MT5-ML-DL-Trading…/notebooks/strategies/ml/live_trading/multi_bar_classification.ipynb
T

2622 lines
142 KiB
Plaintext
Raw Normal View History

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"One-Symbol Version"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Loaded pipeline from models/simple_models/JP225_best_model.pkl\n",
"Checking market status...\n",
"Market is open. Executing trades...\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-22 21:45:06, SYMBOL: JP225, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"Adjusted lot size to 1.0 (min=1.0, step=1.0, max=250.0)\n",
"Sending order request: {'action': 1, 'symbol': 'JP225', 'volume': 1.0, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order successful for JP225, comment=Request executed\n"
]
}
],
"source": [
"# LIVE TRADING CODE FOR MULTI-BAR CLASSIFICATION\n",
"\n",
"import sys\n",
"import os\n",
"import warnings\n",
"from pathlib import Path\n",
"\n",
"# ---------------------------------------------------------------------------\n",
"# 1) SET PROJECT ROOT AND UPDATE PATH/WORKING DIRECTORY\n",
"# ---------------------------------------------------------------------------\n",
"project_root = Path.cwd().parent.parent # Adjust if your notebook is in notebooks/time_series\n",
"sys.path.append(str(project_root))\n",
"os.chdir(str(project_root))\n",
"warnings.filterwarnings(\"ignore\")\n",
"\n",
"import warnings\n",
"warnings.filterwarnings(\"ignore\")\n",
"import MetaTrader5 as mt5\n",
"import pandas as pd\n",
"import numpy as np\n",
"import ta\n",
"from datetime import datetime, timedelta\n",
"import time\n",
"import logging\n",
"import joblib\n",
"\n",
"# Setup logging\n",
"logging.basicConfig(\n",
" filename='models/saved_models/trading_app1.log',\n",
" level=logging.INFO,\n",
" format='%(asctime)s %(levelname)s:%(message)s',\n",
" datefmt='%Y-%m-%d %H:%M:%S'\n",
")\n",
"\n",
"def log_and_print(message, is_error=False):\n",
" \"\"\"\n",
" Logs and prints a message.\n",
" If is_error=True, logs at the ERROR level; otherwise logs at INFO level.\n",
" \"\"\"\n",
" if is_error:\n",
" logging.error(message)\n",
" else:\n",
" logging.info(message)\n",
" print(message)\n",
"\n",
"# Update the login credentials and server information accordingly\n",
"#name = 66677507\n",
"#key = 'ST746$nG38'\n",
"#serv = 'ICMarketsSC-Demo'\n",
"\n",
"# Global variables\n",
"SYMBOL = \"JP225\"\n",
"LOT_SIZE = 0.1\n",
"TIMEFRAME = mt5.TIMEFRAME_H4 # 1 hour timeframe\n",
"N_BARS = 1000\n",
"MAGIC_NUMBER = 234003\n",
"SLEEP_TIME = 14400 # 4 hours in seconds\n",
"COMMENT_ML = \"RFFV-D\"\n",
"\n",
"# If you still need feature selection, you can keep this helper function:\n",
"def select_features_rf_reg(X, y, estimator, max_features=20):\n",
" \"\"\"\n",
" Example helper function for feature selection using RandomForest.\n",
" \"\"\"\n",
" from sklearn.feature_selection import SelectFromModel\n",
" selector = SelectFromModel(estimator=estimator, threshold=-np.inf, max_features=max_features).fit(X, y)\n",
" X_transformed = selector.transform(X)\n",
" selected_features_mask = selector.get_support()\n",
" return X_transformed, selected_features_mask\n",
"\n",
"class TradingApp:\n",
" def __init__(self, symbol, lot_size, magic_number):\n",
" self.symbol = symbol\n",
" self.lot_size = lot_size\n",
" self.magic_number = magic_number\n",
" self.pipeline = None # We'll store the loaded classification pipeline here\n",
" self.last_retrain_time = None\n",
"\n",
" def get_data(self, symbol, n, timeframe):\n",
" \"\"\"\n",
" Fetch 'n' bars of historical data for the given symbol and timeframe.\n",
" \"\"\"\n",
" rates = mt5.copy_rates_from_pos(symbol, timeframe, 0, n)\n",
" rates_frame = pd.DataFrame(rates)\n",
" rates_frame['time'] = pd.to_datetime(rates_frame['time'], unit='s')\n",
" rates_frame.set_index('time', inplace=True)\n",
" return rates_frame\n",
"\n",
" def add_all_ta_features(self, df):\n",
" \"\"\"\n",
" Add technical analysis features to the DataFrame using the 'ta' library.\n",
" \"\"\"\n",
" df = ta.add_all_ta_features(\n",
" df, open=\"open\", high=\"high\", low=\"low\", close=\"close\", volume=\"tick_volume\", fillna=True\n",
" )\n",
" return df\n",
"\n",
" def load_pipeline(self, pipeline_path):\n",
" \"\"\"\n",
" Loads a pre-trained classification pipeline (either a Pipeline or a dict).\n",
" \"\"\"\n",
" pipeline_loaded = joblib.load(pipeline_path)\n",
"\n",
" # If it's a dict, extract the model\n",
" if isinstance(pipeline_loaded, dict):\n",
" self.pipeline = pipeline_loaded[\"model\"]\n",
" else:\n",
" self.pipeline = pipeline_loaded\n",
"\n",
" logging.info(f\"Loaded pipeline from {pipeline_path}\")\n",
" log_and_print(f\"Loaded pipeline from {pipeline_path}\")\n",
"\n",
"\n",
" def ml_signal_generation(self, symbol, n_bars, timeframe):\n",
" \"\"\"\n",
" Generate buy/sell signals using the loaded classification pipeline.\n",
" The pipeline outputs SHIFTED labels in {0,1,2} => we SHIFT them back to {-1,0,+1}.\n",
" We'll interpret +1 => buy, -1 => sell, 0 => no trade.\n",
" \"\"\"\n",
" if self.pipeline is None:\n",
" logging.error(\"No pipeline loaded. Call load_pipeline(...) first.\")\n",
" return False, False, True, True\n",
"\n",
" # 1) Fetch new data\n",
" df = self.get_data(symbol, n_bars, timeframe)\n",
"\n",
" # 2) Add TA features\n",
" df = self.add_all_ta_features(df)\n",
" df.fillna(method='ffill', inplace=True)\n",
"\n",
" # 3) Prepare the features\n",
" X_new = df # The pipeline must handle columns in the correct order.\n",
"\n",
" # 4) Predict SHIFTED classes\n",
" preds_shifted = self.pipeline.predict(X_new)\n",
" # SHIFT them back: 0->-1, 1->0, 2->+1\n",
" preds = preds_shifted - 1\n",
"\n",
" # Get the latest predicted class\n",
" latest_pred = preds[-1]\n",
" # If latest_pred == +1 => buy signal\n",
" # If latest_pred == -1 => sell signal\n",
" # If 0 => do nothing\n",
" buy_signal = (latest_pred == 1)\n",
" sell_signal = (latest_pred == -1)\n",
"\n",
" return buy_signal, sell_signal, not buy_signal, not sell_signal\n",
"\n",
" def orders(self, symbol, lot, is_buy=True, id_position=None, sl=None, tp=None):\n",
" \"\"\"\n",
" Place an order (BUY or SELL) for the specified symbol and lot size.\n",
" \"\"\"\n",
" symbol_info = mt5.symbol_info(symbol)\n",
" if symbol_info is None:\n",
" log_and_print(f\"Symbol {symbol} not found, can't place order.\", is_error=True)\n",
" return \"Symbol not found\"\n",
"\n",
" # Make sure symbol is visible\n",
" if not symbol_info.visible:\n",
" if not mt5.symbol_select(symbol, True):\n",
" log_and_print(f\"Failed to select symbol {symbol}\", is_error=True)\n",
" return \"Symbol not visible or could not be selected.\"\n",
"\n",
" tick_info = mt5.symbol_info_tick(symbol)\n",
" if tick_info is None:\n",
" log_and_print(f\"Could not get tick info for {symbol}.\", is_error=True)\n",
" return \"Tick info unavailable\"\n",
"\n",
" # Check for valid bid/ask\n",
" if tick_info.bid <= 0 or tick_info.ask <= 0:\n",
" log_and_print(\n",
" f\"Zero or invalid bid/ask for {symbol}: bid={tick_info.bid}, ask={tick_info.ask}\",\n",
" is_error=True\n",
" )\n",
" return \"Invalid prices\"\n",
"\n",
" # LOT SIZE VALIDATION\n",
" lot = max(lot, symbol_info.volume_min)\n",
" step = symbol_info.volume_step\n",
" if step > 0:\n",
" remainder = lot % step\n",
" if remainder != 0:\n",
" lot = lot - remainder + step\n",
" if lot > symbol_info.volume_max:\n",
" lot = symbol_info.volume_max\n",
"\n",
" log_and_print(\n",
" f\"Adjusted lot size to {lot} (min={symbol_info.volume_min}, \"\n",
" f\"step={symbol_info.volume_step}, max={symbol_info.volume_max})\"\n",
" )\n",
"\n",
" # Force ORDER_FILLING_IOC\n",
" filling_mode = 1 # ORDER_FILLING_IOC\n",
"\n",
" order_type = mt5.ORDER_TYPE_BUY if is_buy else mt5.ORDER_TYPE_SELL\n",
" order_price = tick_info.ask if is_buy else tick_info.bid\n",
" deviation = 20\n",
"\n",
" request = {\n",
" \"action\": mt5.TRADE_ACTION_DEAL,\n",
" \"symbol\": symbol,\n",
" \"volume\": lot,\n",
" \"type\": order_type,\n",
" \"deviation\": deviation,\n",
" \"magic\": self.magic_number,\n",
" \"comment\": COMMENT_ML,\n",
" \"type_time\": mt5.ORDER_TIME_GTC,\n",
" \"type_filling\": filling_mode,\n",
" }\n",
"\n",
" if sl is not None:\n",
" request[\"sl\"] = sl\n",
" if tp is not None:\n",
" request[\"tp\"] = tp\n",
" if id_position is not None:\n",
" request[\"position\"] = id_position\n",
"\n",
" log_and_print(f\"Sending order request: {request}\")\n",
" result = mt5.order_send(request)\n",
"\n",
" order_type_str = \"BUY\" if is_buy else \"SELL\"\n",
" if result is None or result.retcode != mt5.TRADE_RETCODE_DONE:\n",
" error_message = f\"Order failed for {symbol}\"\n",
" if result:\n",
" error_message += f\", retcode={result.retcode}, comment={result.comment}\"\n",
" additional_info = (\n",
" f\"Date/Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\\n\"\n",
" f\"Order Type: {order_type_str}\\n\"\n",
" f\"Lot Size: {lot}\\n\"\n",
" f\"SL: {sl if sl else 'None'}\\n\"\n",
" f\"TP: {tp if tp else 'None'}\\n\"\n",
" f\"Comment: {COMMENT_ML}\\n\"\n",
" f\"Request: {request}\\n\"\n",
" f\"Result: {result}\"\n",
" )\n",
" # If you want notifications, you could log or handle them differently here.\n",
" log_and_print(f\"Order failed details: {additional_info}\", is_error=True)\n",
" else:\n",
" success_message = f\"Order successful for {symbol}, comment={result.comment}\"\n",
" additional_info = (\n",
" f\"Date/Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\\n\"\n",
" f\"Order Type: {order_type_str}\\n\"\n",
" f\"Lot Size: {lot}\\n\"\n",
" f\"SL: {sl if sl else 'None'}\\n\"\n",
" f\"TP: {tp if tp else 'None'}\\n\"\n",
" f\"Comment: {COMMENT_ML}\"\n",
" )\n",
" # If you want notifications, you could log or handle them differently here.\n",
" log_and_print(success_message)\n",
"\n",
" def get_positions_by_magic(self, symbol, magic_number):\n",
" \"\"\"\n",
" Retrieve positions for a specific symbol and magic number.\n",
" \"\"\"\n",
" all_positions = mt5.positions_get(symbol=symbol)\n",
" if not all_positions:\n",
" log_and_print(\"No positions found.\", is_error=False)\n",
" return []\n",
" return [pos for pos in all_positions if pos.magic == magic_number]\n",
"\n",
" def run_strategy(self, symbol, lot, buy_signal, sell_signal):\n",
" \"\"\"\n",
" Run the trading strategy logic based on buy/sell signals.\n",
" \"\"\"\n",
" log_and_print(\"------------------------------------------------------------------\")\n",
" log_and_print(\n",
" f\"Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}, \"\n",
" f\"SYMBOL: {symbol}, BUY SIGNAL: {buy_signal}, SELL SIGNAL: {sell_signal}\"\n",
" )\n",
"\n",
" positions = self.get_positions_by_magic(symbol, self.magic_number)\n",
" has_buy = any(pos.type == mt5.POSITION_TYPE_BUY for pos in positions)\n",
" has_sell = any(pos.type == mt5.POSITION_TYPE_SELL for pos in positions)\n",
"\n",
" if buy_signal and not has_buy:\n",
" if has_sell:\n",
" log_and_print(\"Existing sell positions found. Attempting to close...\")\n",
" if self.close_position(symbol, is_buy=True):\n",
" log_and_print(\"Sell positions closed. Placing new buy order.\")\n",
" self.orders(symbol, lot, is_buy=True)\n",
" else:\n",
" log_and_print(\"Failed to close sell positions.\")\n",
" else:\n",
" self.orders(symbol, lot, is_buy=True)\n",
" elif sell_signal and not has_sell:\n",
" if has_buy:\n",
" log_and_print(\"Existing buy positions found. Attempting to close...\")\n",
" if self.close_position(symbol, is_buy=False):\n",
" log_and_print(\"Buy positions closed. Placing new sell order.\")\n",
" self.orders(symbol, lot, is_buy=False)\n",
" else:\n",
" log_and_print(\"Failed to close buy positions.\")\n",
" else:\n",
" self.orders(symbol, lot, is_buy=False)\n",
" else:\n",
" log_and_print(\"Appropriate position already exists or no signal to act on.\")\n",
"\n",
" def close_position(self, symbol, is_buy):\n",
" \"\"\"\n",
" Closes positions of the opposite type (BUY/SELL) for this app's magic number.\n",
" \"\"\"\n",
" positions = mt5.positions_get(symbol=symbol)\n",
" if not positions:\n",
" log_and_print(f\"No positions to close for symbol: {symbol}\")\n",
" return False\n",
"\n",
" initial_balance = mt5.account_info().balance\n",
" closed_any = False\n",
"\n",
" for position in positions:\n",
" # Close positions of the opposite type with the same magic number\n",
" if position.magic == self.magic_number and (\n",
" (is_buy and position.type == mt5.POSITION_TYPE_SELL) or\n",
" (not is_buy and position.type == mt5.POSITION_TYPE_BUY)\n",
" ):\n",
" close_request = {\n",
" \"action\": mt5.TRADE_ACTION_DEAL,\n",
" \"symbol\": symbol,\n",
" \"volume\": position.volume,\n",
" \"type\": mt5.ORDER_TYPE_BUY if position.type == mt5.POSITION_TYPE_SELL else mt5.ORDER_TYPE_SELL,\n",
" \"position\": position.ticket,\n",
" \"deviation\": 20,\n",
" \"magic\": self.magic_number,\n",
" \"comment\": COMMENT_ML,\n",
" \"type_time\": mt5.ORDER_TIME_GTC,\n",
" \"type_filling\": mt5.ORDER_FILLING_RETURN,\n",
" }\n",
" result = mt5.order_send(close_request)\n",
" if result.retcode != mt5.TRADE_RETCODE_DONE:\n",
" error_message = f\"Failed to close position {position.ticket} for {symbol}: {result.retcode}\"\n",
" log_and_print(error_message, is_error=True)\n",
" # If you want notifications, you could log or handle them differently here.\n",
" else:\n",
" log_and_print(f\"Successfully closed position {position.ticket} for {symbol}\")\n",
" closed_any = True\n",
"\n",
" if closed_any:\n",
" final_balance = mt5.account_info().balance\n",
" profit = final_balance - initial_balance\n",
" success_message = f\"Closed positions successfully, Profit: {profit}\"\n",
" log_and_print(success_message)\n",
" return True\n",
"\n",
" return False\n",
"\n",
" def check_and_execute_trades(self):\n",
" \"\"\"\n",
" Convenience method to perform the entire flow:\n",
" generate signals, run strategy, and deselect symbol.\n",
" \"\"\"\n",
" mt5.symbol_select(self.symbol, True)\n",
" buy, sell, _, _ = self.ml_signal_generation(self.symbol, N_BARS, TIMEFRAME)\n",
" self.run_strategy(self.symbol, self.lot_size, buy, sell)\n",
" mt5.symbol_select(self.symbol, False)\n",
" log_and_print(\"Waiting for new signals...\")\n",
"\n",
"def is_market_open():\n",
" \"\"\"\n",
" Check if the current time is within the typical Forex trading session, adjusted for CET/CEST.\n",
" Market closes at Friday 10:00 PM CET and opens at Sunday 11:00 PM CET. \n",
" It is closed all day Saturday.\n",
" \"\"\"\n",
" current_time_utc = datetime.utcnow()\n",
" # Adjust for Central European Time (UTC+1) or Central European Summer Time (UTC+2)\n",
" current_time_cet = (\n",
" current_time_utc + timedelta(hours=2) \n",
" if time.localtime().tm_isdst \n",
" else current_time_utc + timedelta(hours=1)\n",
" )\n",
"\n",
" # Friday after 10 PM CET\n",
" if current_time_cet.weekday() == 4 and current_time_cet.hour >= 22:\n",
" return False\n",
" # Sunday before 11 PM CET\n",
" elif current_time_cet.weekday() == 6 and current_time_cet.hour < 23:\n",
" return False\n",
" # All day Saturday\n",
" elif current_time_cet.weekday() == 5:\n",
" return False\n",
" return True\n",
"\n",
"if __name__ == \"__main__\":\n",
" try:\n",
" if not mt5.initialize():\n",
" log_and_print(\"Failed to initialize MetaTrader 5\", is_error=True)\n",
" exit()\n",
"\n",
" app = TradingApp(symbol=SYMBOL, lot_size=LOT_SIZE, magic_number=MAGIC_NUMBER)\n",
"\n",
" # 1) Load the classification pipeline\n",
" pipeline_path = \"models/simple_models/JP225_best_model.pkl\"\n",
" app.load_pipeline(pipeline_path)\n",
"\n",
" while True:\n",
" log_and_print(\"Checking market status...\")\n",
" if is_market_open():\n",
" log_and_print(\"Market is open. Executing trades...\")\n",
"\n",
" # 2) Generate signals using the loaded pipeline\n",
" # This pipeline is classification-based => SHIFTED labels [0,1,2]\n",
" # ml_signal_generation() SHIFTs them back to [-1,0,+1] for signals\n",
" buy_signal, sell_signal, _, _ = app.ml_signal_generation(\n",
" symbol=app.symbol,\n",
" n_bars=N_BARS,\n",
" timeframe=TIMEFRAME\n",
" )\n",
"\n",
" # 3) Run strategy\n",
" app.run_strategy(app.symbol, app.lot_size, buy_signal, sell_signal)\n",
" else:\n",
" log_and_print(\"Market is closed. No actions performed.\")\n",
"\n",
" time.sleep(SLEEP_TIME)\n",
"\n",
" except KeyboardInterrupt:\n",
" log_and_print(\"Shutdown signal received.\")\n",
" # If you need a notification here, handle it (e.g., log, email, etc.).\n",
" except Exception as e:\n",
" error_message = f\"An error occurred: {e}\"\n",
" log_and_print(error_message, is_error=True)\n",
" # If you need a notification here, handle it (e.g., log, email, etc.).\n",
" finally:\n",
" mt5.shutdown()\n",
" log_and_print(\"MetaTrader 5 shutdown completed.\")\n",
" # If you need a notification here, handle it (e.g., log, email, etc.).\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Multi-Symbol Version"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Loaded pipeline from models/h1_models/EURUSD_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/USDJPY_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/AUDUSD_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/GBPUSD_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/USDCHF_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/EURGBP_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/MSFT.NAS_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/TSLA.NAS_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/NVDA.NAS_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/AMZN.NAS_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/GOOG.NAS_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/NFLX.NAS_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/AAPL.NAS_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/BABA.NYSE_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/JPM.NYSE_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/XOM.NYSE_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/BA.NYSE_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/DIS.NYSE_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/NKE.NYSE_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/US500_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/US2000_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/UK100_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/JP225_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/XAUUSD_H1_best_model.pkl\n",
"Loaded pipeline from models/h1_models/DE40_H1_best_model.pkl\n",
"Checking market status...\n",
"Market is open. Executing trades...\n",
"🟠 Skipping NKE.NYSE: US market not open yet.\n",
"🟠 Skipping NVDA.NAS: US market not open yet.\n",
"🔵 Checking Symbol: XAUUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 07:09:26, SYMBOL: XAUUSD, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 XAUUSD: Placing new SELL order.\n",
"Adjusted lot size to 0.01 (min=0.01, step=0.01, max=100.0)\n",
"Sending order request: {'action': 1, 'symbol': 'XAUUSD', 'volume': 0.01, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order successful for XAUUSD, comment=Request executed\n",
"🔵 Checking Symbol: US2000\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 07:09:27, SYMBOL: US2000, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 US2000: Flat signal. No position open.\n",
"🔵 Checking Symbol: USDJPY\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 07:09:27, SYMBOL: USDJPY, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: GBPUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 07:09:28, SYMBOL: GBPUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 GBPUSD: Flat signal. No position open.\n",
"🟠 Skipping NFLX.NAS: US market not open yet.\n",
"🟠 Skipping TSLA.NAS: US market not open yet.\n",
"🟠 Skipping AAPL.NAS: US market not open yet.\n",
"🟠 Skipping XOM.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: EURGBP\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 07:09:28, SYMBOL: EURGBP, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURGBP: Flat signal. No position open.\n",
"🔵 Checking Symbol: US500\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 07:09:29, SYMBOL: US500, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 US500: Placing new SELL order.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=250.0)\n",
"Sending order request: {'action': 1, 'symbol': 'US500', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order successful for US500, comment=Request executed\n",
"🔵 Checking Symbol: USDCHF\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 07:09:30, SYMBOL: USDCHF, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 USDCHF: Flat signal. No position open.\n",
"🔵 Checking Symbol: EURUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 07:09:30, SYMBOL: EURUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURUSD: Flat signal. No position open.\n",
"🟠 Skipping MSFT.NAS: US market not open yet.\n",
"🔵 Checking Symbol: AUDUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 07:09:31, SYMBOL: AUDUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 AUDUSD: Flat signal. No position open.\n",
"🟠 Skipping BA.NYSE: US market not open yet.\n",
"🟠 Skipping JPM.NYSE: US market not open yet.\n",
"🟠 Skipping DIS.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: DE40\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 07:09:31, SYMBOL: DE40, BUY SIGNAL: False, SELL SIGNAL: False\n",
"🟤 DE40: Flat signal. No position open.\n",
"🔵 Checking Symbol: JP225\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 07:09:32, SYMBOL: JP225, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 JP225: Placing new SELL order.\n",
"Adjusted lot size to 1.0 (min=1.0, step=1.0, max=250.0)\n",
"Sending order request: {'action': 1, 'symbol': 'JP225', 'volume': 1.0, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order successful for JP225, comment=Request executed\n",
"🟠 Skipping AMZN.NAS: US market not open yet.\n",
"🔵 Checking Symbol: UK100\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 07:09:33, SYMBOL: UK100, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 UK100: Placing new SELL order.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=250.0)\n",
"Sending order request: {'action': 1, 'symbol': 'UK100', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order successful for UK100, comment=Request executed\n",
"🟠 Skipping GOOG.NAS: US market not open yet.\n",
"🟠 Skipping BABA.NYSE: US market not open yet.\n",
"✅ Successful Orders: 4\n",
"❌ Failed Orders: 0\n",
"⏳ Retry Queue: []\n",
"Checking market status...\n",
"Market is open. Executing trades...\n",
"🟠 Skipping NKE.NYSE: US market not open yet.\n",
"🟠 Skipping NVDA.NAS: US market not open yet.\n",
"🔵 Checking Symbol: XAUUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 08:09:34, SYMBOL: XAUUSD, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔴 XAUUSD: Placing new SELL order.\n",
"Adjusted lot size to 0.01 (min=0.01, step=0.01, max=100.0)\n",
"Sending order request: {'action': 1, 'symbol': 'XAUUSD', 'volume': 0.01, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order successful for XAUUSD, comment=Request executed\n",
"🔵 Checking Symbol: US2000\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 08:09:35, SYMBOL: US2000, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 US2000: Flat signal. No position open.\n",
"🔵 Checking Symbol: USDJPY\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 08:09:36, SYMBOL: USDJPY, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: GBPUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 08:09:37, SYMBOL: GBPUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 GBPUSD: Flat signal. No position open.\n",
"🟠 Skipping NFLX.NAS: US market not open yet.\n",
"🟠 Skipping TSLA.NAS: US market not open yet.\n",
"🟠 Skipping AAPL.NAS: US market not open yet.\n",
"🟠 Skipping XOM.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: EURGBP\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 08:09:38, SYMBOL: EURGBP, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURGBP: Flat signal. No position open.\n",
"🔵 Checking Symbol: US500\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 08:09:39, SYMBOL: US500, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 US500: Placing new SELL order.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=250.0)\n",
"Sending order request: {'action': 1, 'symbol': 'US500', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order successful for US500, comment=Request executed\n",
"🔵 Checking Symbol: USDCHF\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 08:09:40, SYMBOL: USDCHF, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 USDCHF: Flat signal. No position open.\n",
"🔵 Checking Symbol: EURUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 08:09:41, SYMBOL: EURUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURUSD: Flat signal. No position open.\n",
"🟠 Skipping MSFT.NAS: US market not open yet.\n",
"🔵 Checking Symbol: AUDUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 08:09:42, SYMBOL: AUDUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 AUDUSD: Flat signal. No position open.\n",
"🟠 Skipping BA.NYSE: US market not open yet.\n",
"🟠 Skipping JPM.NYSE: US market not open yet.\n",
"🟠 Skipping DIS.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: DE40\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 08:09:42, SYMBOL: DE40, BUY SIGNAL: False, SELL SIGNAL: False\n",
"🟤 DE40: Flat signal. No position open.\n",
"🔵 Checking Symbol: JP225\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 08:09:43, SYMBOL: JP225, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🟠 Skipping AMZN.NAS: US market not open yet.\n",
"🔵 Checking Symbol: UK100\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 08:09:44, SYMBOL: UK100, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 UK100: Placing new SELL order.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=250.0)\n",
"Sending order request: {'action': 1, 'symbol': 'UK100', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order successful for UK100, comment=Request executed\n",
"🟠 Skipping GOOG.NAS: US market not open yet.\n",
"🟠 Skipping BABA.NYSE: US market not open yet.\n",
"✅ Successful Orders: 7\n",
"❌ Failed Orders: 0\n",
"⏳ Retry Queue: []\n",
"Checking market status...\n",
"Market is open. Executing trades...\n",
"🟠 Skipping NKE.NYSE: US market not open yet.\n",
"🟠 Skipping NVDA.NAS: US market not open yet.\n",
"🔵 Checking Symbol: XAUUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 09:09:45, SYMBOL: XAUUSD, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔴 XAUUSD: Placing new SELL order.\n",
"Adjusted lot size to 0.01 (min=0.01, step=0.01, max=100.0)\n",
"Sending order request: {'action': 1, 'symbol': 'XAUUSD', 'volume': 0.01, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order successful for XAUUSD, comment=Request executed\n",
"🔵 Checking Symbol: US2000\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 09:09:47, SYMBOL: US2000, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 US2000: Flat signal. No position open.\n",
"🔵 Checking Symbol: USDJPY\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 09:09:48, SYMBOL: USDJPY, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: GBPUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 09:09:49, SYMBOL: GBPUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 GBPUSD: Flat signal. No position open.\n",
"🟠 Skipping NFLX.NAS: US market not open yet.\n",
"🟠 Skipping TSLA.NAS: US market not open yet.\n",
"🟠 Skipping AAPL.NAS: US market not open yet.\n",
"🟠 Skipping XOM.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: EURGBP\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 09:09:50, SYMBOL: EURGBP, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURGBP: Flat signal. No position open.\n",
"🔵 Checking Symbol: US500\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 09:09:51, SYMBOL: US500, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: USDCHF\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 09:09:52, SYMBOL: USDCHF, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 USDCHF: Flat signal. No position open.\n",
"🔵 Checking Symbol: EURUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 09:09:53, SYMBOL: EURUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURUSD: Flat signal. No position open.\n",
"🟠 Skipping MSFT.NAS: US market not open yet.\n",
"🔵 Checking Symbol: AUDUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 09:09:54, SYMBOL: AUDUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 AUDUSD: Flat signal. No position open.\n",
"🟠 Skipping BA.NYSE: US market not open yet.\n",
"🟠 Skipping JPM.NYSE: US market not open yet.\n",
"🟠 Skipping DIS.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: DE40\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 09:09:55, SYMBOL: DE40, BUY SIGNAL: False, SELL SIGNAL: False\n",
"🟤 DE40: Flat signal. No position open.\n",
"🔵 Checking Symbol: JP225\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 09:09:56, SYMBOL: JP225, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🟠 Skipping AMZN.NAS: US market not open yet.\n",
"🔵 Checking Symbol: UK100\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 09:09:57, SYMBOL: UK100, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🟠 Skipping GOOG.NAS: US market not open yet.\n",
"🟠 Skipping BABA.NYSE: US market not open yet.\n",
"✅ Successful Orders: 8\n",
"❌ Failed Orders: 0\n",
"⏳ Retry Queue: []\n",
"Checking market status...\n",
"Market is open. Executing trades...\n",
"🟠 Skipping NKE.NYSE: US market not open yet.\n",
"🟠 Skipping NVDA.NAS: US market not open yet.\n",
"🔵 Checking Symbol: XAUUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 10:09:58, SYMBOL: XAUUSD, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: US2000\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 10:09:59, SYMBOL: US2000, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 US2000: Flat signal. No position open.\n",
"🔵 Checking Symbol: USDJPY\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 10:09:59, SYMBOL: USDJPY, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: GBPUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 10:10:00, SYMBOL: GBPUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 GBPUSD: Flat signal. No position open.\n",
"🟠 Skipping NFLX.NAS: US market not open yet.\n",
"🟠 Skipping TSLA.NAS: US market not open yet.\n",
"🟠 Skipping AAPL.NAS: US market not open yet.\n",
"🟠 Skipping XOM.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: EURGBP\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 10:10:00, SYMBOL: EURGBP, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURGBP: Flat signal. No position open.\n",
"🔵 Checking Symbol: US500\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 10:10:01, SYMBOL: US500, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: USDCHF\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 10:10:02, SYMBOL: USDCHF, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 USDCHF: Flat signal. No position open.\n",
"🔵 Checking Symbol: EURUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 10:10:02, SYMBOL: EURUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURUSD: Flat signal. No position open.\n",
"🟠 Skipping MSFT.NAS: US market not open yet.\n",
"🔵 Checking Symbol: AUDUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 10:10:03, SYMBOL: AUDUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 AUDUSD: Flat signal. No position open.\n",
"🟠 Skipping BA.NYSE: US market not open yet.\n",
"🟠 Skipping JPM.NYSE: US market not open yet.\n",
"🟠 Skipping DIS.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: DE40\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 10:10:03, SYMBOL: DE40, BUY SIGNAL: False, SELL SIGNAL: False\n",
"🟤 DE40: Flat signal. No position open.\n",
"🔵 Checking Symbol: JP225\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 10:10:04, SYMBOL: JP225, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🟠 Skipping AMZN.NAS: US market not open yet.\n",
"🔵 Checking Symbol: UK100\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 10:10:04, SYMBOL: UK100, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🟠 Skipping GOOG.NAS: US market not open yet.\n",
"🟠 Skipping BABA.NYSE: US market not open yet.\n",
"✅ Successful Orders: 8\n",
"❌ Failed Orders: 0\n",
"⏳ Retry Queue: []\n",
"Checking market status...\n",
"Market is open. Executing trades...\n",
"🟠 Skipping NKE.NYSE: US market not open yet.\n",
"🟠 Skipping NVDA.NAS: US market not open yet.\n",
"🔵 Checking Symbol: XAUUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 11:10:05, SYMBOL: XAUUSD, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: US2000\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 11:10:05, SYMBOL: US2000, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 US2000: Flat signal. No position open.\n",
"🔵 Checking Symbol: USDJPY\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 11:10:06, SYMBOL: USDJPY, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: GBPUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 11:10:06, SYMBOL: GBPUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 GBPUSD: Flat signal. No position open.\n",
"🟠 Skipping NFLX.NAS: US market not open yet.\n",
"🟠 Skipping TSLA.NAS: US market not open yet.\n",
"🟠 Skipping AAPL.NAS: US market not open yet.\n",
"🟠 Skipping XOM.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: EURGBP\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 11:10:07, SYMBOL: EURGBP, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURGBP: Flat signal. No position open.\n",
"🔵 Checking Symbol: US500\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 11:10:07, SYMBOL: US500, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: USDCHF\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 11:10:08, SYMBOL: USDCHF, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 USDCHF: Flat signal. No position open.\n",
"🔵 Checking Symbol: EURUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 11:10:08, SYMBOL: EURUSD, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 EURUSD: Placing new SELL order.\n",
"Adjusted lot size to 0.01 (min=0.01, step=0.01, max=200.0)\n",
"Sending order request: {'action': 1, 'symbol': 'EURUSD', 'volume': 0.01, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order successful for EURUSD, comment=Request executed\n",
"🟠 Skipping MSFT.NAS: US market not open yet.\n",
"🔵 Checking Symbol: AUDUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 11:10:09, SYMBOL: AUDUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 AUDUSD: Flat signal. No position open.\n",
"🟠 Skipping BA.NYSE: US market not open yet.\n",
"🟠 Skipping JPM.NYSE: US market not open yet.\n",
"🟠 Skipping DIS.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: DE40\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 11:10:09, SYMBOL: DE40, BUY SIGNAL: False, SELL SIGNAL: False\n",
"🟤 DE40: Flat signal. No position open.\n",
"🔵 Checking Symbol: JP225\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 11:10:10, SYMBOL: JP225, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🟠 Skipping AMZN.NAS: US market not open yet.\n",
"🔵 Checking Symbol: UK100\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 11:10:10, SYMBOL: UK100, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🟠 Skipping GOOG.NAS: US market not open yet.\n",
"🟠 Skipping BABA.NYSE: US market not open yet.\n",
"✅ Successful Orders: 9\n",
"❌ Failed Orders: 0\n",
"⏳ Retry Queue: []\n",
"Checking market status...\n",
"Market is open. Executing trades...\n",
"🟠 Skipping NKE.NYSE: US market not open yet.\n",
"🟠 Skipping NVDA.NAS: US market not open yet.\n",
"🔵 Checking Symbol: XAUUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 12:10:11, SYMBOL: XAUUSD, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: US2000\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 12:10:12, SYMBOL: US2000, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 US2000: Flat signal. No position open.\n",
"🔵 Checking Symbol: USDJPY\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 12:10:12, SYMBOL: USDJPY, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: GBPUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 12:10:13, SYMBOL: GBPUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 GBPUSD: Flat signal. No position open.\n",
"🟠 Skipping NFLX.NAS: US market not open yet.\n",
"🟠 Skipping TSLA.NAS: US market not open yet.\n",
"🟠 Skipping AAPL.NAS: US market not open yet.\n",
"🟠 Skipping XOM.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: EURGBP\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 12:10:14, SYMBOL: EURGBP, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURGBP: Flat signal. No position open.\n",
"🔵 Checking Symbol: US500\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 12:10:14, SYMBOL: US500, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: USDCHF\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 12:10:15, SYMBOL: USDCHF, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 USDCHF: Flat signal. No position open.\n",
"🔵 Checking Symbol: EURUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 12:10:15, SYMBOL: EURUSD, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🟠 Skipping MSFT.NAS: US market not open yet.\n",
"🔵 Checking Symbol: AUDUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 12:10:16, SYMBOL: AUDUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 AUDUSD: Flat signal. No position open.\n",
"🟠 Skipping BA.NYSE: US market not open yet.\n",
"🟠 Skipping JPM.NYSE: US market not open yet.\n",
"🟠 Skipping DIS.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: DE40\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 12:10:17, SYMBOL: DE40, BUY SIGNAL: False, SELL SIGNAL: False\n",
"🟤 DE40: Flat signal. No position open.\n",
"🔵 Checking Symbol: JP225\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 12:10:17, SYMBOL: JP225, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🟠 Skipping AMZN.NAS: US market not open yet.\n",
"🔵 Checking Symbol: UK100\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 12:10:18, SYMBOL: UK100, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🟠 Skipping GOOG.NAS: US market not open yet.\n",
"🟠 Skipping BABA.NYSE: US market not open yet.\n",
"✅ Successful Orders: 9\n",
"❌ Failed Orders: 0\n",
"⏳ Retry Queue: []\n",
"Checking market status...\n",
"Market is open. Executing trades...\n",
"🟠 Skipping NKE.NYSE: US market not open yet.\n",
"🟠 Skipping NVDA.NAS: US market not open yet.\n",
"🔵 Checking Symbol: XAUUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 13:10:19, SYMBOL: XAUUSD, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 XAUUSD: Placing new SELL order.\n",
"Adjusted lot size to 0.01 (min=0.01, step=0.01, max=100.0)\n",
"Sending order request: {'action': 1, 'symbol': 'XAUUSD', 'volume': 0.01, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order successful for XAUUSD, comment=Request executed\n",
"🔵 Checking Symbol: US2000\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 13:10:20, SYMBOL: US2000, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 US2000: Flat signal. No position open.\n",
"🔵 Checking Symbol: USDJPY\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 13:10:20, SYMBOL: USDJPY, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: GBPUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 13:10:21, SYMBOL: GBPUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 GBPUSD: Flat signal. No position open.\n",
"🟠 Skipping NFLX.NAS: US market not open yet.\n",
"🟠 Skipping TSLA.NAS: US market not open yet.\n",
"🟠 Skipping AAPL.NAS: US market not open yet.\n",
"🟠 Skipping XOM.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: EURGBP\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 13:10:21, SYMBOL: EURGBP, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURGBP: Flat signal. No position open.\n",
"🔵 Checking Symbol: US500\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 13:10:22, SYMBOL: US500, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: USDCHF\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 13:10:22, SYMBOL: USDCHF, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 USDCHF: Flat signal. No position open.\n",
"🔵 Checking Symbol: EURUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 13:10:23, SYMBOL: EURUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"⚪ EURUSD: Flat signal. CLOSE_ON_FLAT is True, attempting to close open position.\n",
"⚠️ Filling mode error for EURUSD position 1117275715, retrying with ORDER_FILLING_IOC...\n",
"✅ Retry succeeded in closing EURUSD position 1117275715\n",
"✅ Closed positions successfully, Profit: -0.7900000000000205\n",
"✅ EURUSD: Flat signal - Position closed.\n",
"🟠 Skipping MSFT.NAS: US market not open yet.\n",
"🔵 Checking Symbol: AUDUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 13:10:24, SYMBOL: AUDUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 AUDUSD: Flat signal. No position open.\n",
"🟠 Skipping BA.NYSE: US market not open yet.\n",
"🟠 Skipping JPM.NYSE: US market not open yet.\n",
"🟠 Skipping DIS.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: DE40\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 13:10:24, SYMBOL: DE40, BUY SIGNAL: False, SELL SIGNAL: False\n",
"🟤 DE40: Flat signal. No position open.\n",
"🔵 Checking Symbol: JP225\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 13:10:25, SYMBOL: JP225, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🟠 Skipping AMZN.NAS: US market not open yet.\n",
"🔵 Checking Symbol: UK100\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 13:10:25, SYMBOL: UK100, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 UK100: Placing new SELL order.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=250.0)\n",
"Sending order request: {'action': 1, 'symbol': 'UK100', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order successful for UK100, comment=Request executed\n",
"🟠 Skipping GOOG.NAS: US market not open yet.\n",
"🟠 Skipping BABA.NYSE: US market not open yet.\n",
"✅ Successful Orders: 11\n",
"❌ Failed Orders: 0\n",
"⏳ Retry Queue: []\n",
"Checking market status...\n",
"Market is open. Executing trades...\n",
"🟠 Skipping NKE.NYSE: US market not open yet.\n",
"🟠 Skipping NVDA.NAS: US market not open yet.\n",
"🔵 Checking Symbol: XAUUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 14:10:26, SYMBOL: XAUUSD, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 XAUUSD: Placing new SELL order.\n",
"Adjusted lot size to 0.01 (min=0.01, step=0.01, max=100.0)\n",
"Sending order request: {'action': 1, 'symbol': 'XAUUSD', 'volume': 0.01, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order successful for XAUUSD, comment=Request executed\n",
"🔵 Checking Symbol: US2000\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 14:10:28, SYMBOL: US2000, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 US2000: Flat signal. No position open.\n",
"🔵 Checking Symbol: USDJPY\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 14:10:28, SYMBOL: USDJPY, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: GBPUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 14:10:29, SYMBOL: GBPUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 GBPUSD: Flat signal. No position open.\n",
"🟠 Skipping NFLX.NAS: US market not open yet.\n",
"🟠 Skipping TSLA.NAS: US market not open yet.\n",
"🟠 Skipping AAPL.NAS: US market not open yet.\n",
"🟠 Skipping XOM.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: EURGBP\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 14:10:30, SYMBOL: EURGBP, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURGBP: Flat signal. No position open.\n",
"🔵 Checking Symbol: US500\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 14:10:31, SYMBOL: US500, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: USDCHF\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 14:10:32, SYMBOL: USDCHF, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 USDCHF: Flat signal. No position open.\n",
"🔵 Checking Symbol: EURUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 14:10:33, SYMBOL: EURUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURUSD: Flat signal. No position open.\n",
"🟠 Skipping MSFT.NAS: US market not open yet.\n",
"🔵 Checking Symbol: AUDUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 14:10:34, SYMBOL: AUDUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 AUDUSD: Flat signal. No position open.\n",
"🟠 Skipping BA.NYSE: US market not open yet.\n",
"🟠 Skipping JPM.NYSE: US market not open yet.\n",
"🟠 Skipping DIS.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: DE40\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 14:10:35, SYMBOL: DE40, BUY SIGNAL: False, SELL SIGNAL: False\n",
"🟤 DE40: Flat signal. No position open.\n",
"🔵 Checking Symbol: JP225\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 14:10:36, SYMBOL: JP225, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 JP225: Placing new SELL order.\n",
"Adjusted lot size to 1.0 (min=1.0, step=1.0, max=250.0)\n",
"Sending order request: {'action': 1, 'symbol': 'JP225', 'volume': 1.0, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order successful for JP225, comment=Request executed\n",
"🟠 Skipping AMZN.NAS: US market not open yet.\n",
"🔵 Checking Symbol: UK100\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 14:10:37, SYMBOL: UK100, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🟠 Skipping GOOG.NAS: US market not open yet.\n",
"🟠 Skipping BABA.NYSE: US market not open yet.\n",
"✅ Successful Orders: 13\n",
"❌ Failed Orders: 0\n",
"⏳ Retry Queue: []\n",
"Checking market status...\n",
"Market is open. Executing trades...\n",
"🟠 Skipping NKE.NYSE: US market not open yet.\n",
"🟠 Skipping NVDA.NAS: US market not open yet.\n",
"🔵 Checking Symbol: XAUUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 15:10:38, SYMBOL: XAUUSD, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔴 XAUUSD: Placing new SELL order.\n",
"Adjusted lot size to 0.01 (min=0.01, step=0.01, max=100.0)\n",
"Sending order request: {'action': 1, 'symbol': 'XAUUSD', 'volume': 0.01, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order successful for XAUUSD, comment=Request executed\n",
"🔵 Checking Symbol: US2000\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 15:10:39, SYMBOL: US2000, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 US2000: Flat signal. No position open.\n",
"🔵 Checking Symbol: USDJPY\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 15:10:40, SYMBOL: USDJPY, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: GBPUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 15:10:41, SYMBOL: GBPUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 GBPUSD: Flat signal. No position open.\n",
"🟠 Skipping NFLX.NAS: US market not open yet.\n",
"🟠 Skipping TSLA.NAS: US market not open yet.\n",
"🟠 Skipping AAPL.NAS: US market not open yet.\n",
"🟠 Skipping XOM.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: EURGBP\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 15:10:42, SYMBOL: EURGBP, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURGBP: Flat signal. No position open.\n",
"🔵 Checking Symbol: US500\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 15:10:43, SYMBOL: US500, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: USDCHF\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 15:10:43, SYMBOL: USDCHF, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 USDCHF: Flat signal. No position open.\n",
"🔵 Checking Symbol: EURUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 15:10:44, SYMBOL: EURUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURUSD: Flat signal. No position open.\n",
"🟠 Skipping MSFT.NAS: US market not open yet.\n",
"🔵 Checking Symbol: AUDUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 15:10:45, SYMBOL: AUDUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 AUDUSD: Flat signal. No position open.\n",
"🟠 Skipping BA.NYSE: US market not open yet.\n",
"🟠 Skipping JPM.NYSE: US market not open yet.\n",
"🟠 Skipping DIS.NYSE: US market not open yet.\n",
"🔵 Checking Symbol: DE40\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 15:10:46, SYMBOL: DE40, BUY SIGNAL: False, SELL SIGNAL: False\n",
"🟤 DE40: Flat signal. No position open.\n",
"🔵 Checking Symbol: JP225\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 15:10:47, SYMBOL: JP225, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🟠 Skipping AMZN.NAS: US market not open yet.\n",
"🔵 Checking Symbol: UK100\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 15:10:47, SYMBOL: UK100, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🟠 Skipping GOOG.NAS: US market not open yet.\n",
"🟠 Skipping BABA.NYSE: US market not open yet.\n",
"✅ Successful Orders: 14\n",
"❌ Failed Orders: 0\n",
"⏳ Retry Queue: []\n",
"Checking market status...\n",
"Market is open. Executing trades...\n",
"🔵 Checking Symbol: NKE.NYSE\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:10:49, SYMBOL: NKE.NYSE, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: NVDA.NAS\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:10:50, SYMBOL: NVDA.NAS, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: XAUUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:10:51, SYMBOL: XAUUSD, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 XAUUSD: Placing new SELL order.\n",
"Adjusted lot size to 0.01 (min=0.01, step=0.01, max=100.0)\n",
"Sending order request: {'action': 1, 'symbol': 'XAUUSD', 'volume': 0.01, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order failed details: Date/Time: 2025-05-01 16:10:51\n",
"Order Type: SELL\n",
"Lot Size: 0.01\n",
"SL: None\n",
"TP: None\n",
"Comment: RFFV-D\n",
"Request: {'action': 1, 'symbol': 'XAUUSD', 'volume': 0.01, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Result: OrderSendResult(retcode=10031, deal=0, order=0, volume=0.0, price=0.0, bid=0.0, ask=0.0, comment='Request rejected due to absence of network connection', request_id=0, retcode_external=0, request=TradeRequest(action=1, magic=234003, order=0, symbol='XAUUSD', volume=0.01, price=0.0, stoplimit=0.0, sl=0.0, tp=0.0, deviation=20, type=1, type_filling=1, type_time=0, expiration=0, comment='RFFV-D', position=0, position_by=0))\n",
"🔵 Checking Symbol: US2000\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:10:52, SYMBOL: US2000, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 US2000: Flat signal. No position open.\n",
"🔵 Checking Symbol: USDJPY\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:10:53, SYMBOL: USDJPY, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 USDJPY: Placing new SELL order.\n",
"Adjusted lot size to 0.01 (min=0.01, step=0.01, max=200.0)\n",
"Sending order request: {'action': 1, 'symbol': 'USDJPY', 'volume': 0.01, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order failed details: Date/Time: 2025-05-01 16:10:53\n",
"Order Type: SELL\n",
"Lot Size: 0.01\n",
"SL: None\n",
"TP: None\n",
"Comment: RFFV-D\n",
"Request: {'action': 1, 'symbol': 'USDJPY', 'volume': 0.01, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Result: OrderSendResult(retcode=10031, deal=0, order=0, volume=0.0, price=0.0, bid=0.0, ask=0.0, comment='Request rejected due to absence of network connection', request_id=0, retcode_external=0, request=TradeRequest(action=1, magic=234003, order=0, symbol='USDJPY', volume=0.01, price=0.0, stoplimit=0.0, sl=0.0, tp=0.0, deviation=20, type=1, type_filling=1, type_time=0, expiration=0, comment='RFFV-D', position=0, position_by=0))\n",
"🔵 Checking Symbol: GBPUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:10:54, SYMBOL: GBPUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 GBPUSD: Flat signal. No position open.\n",
"🔵 Checking Symbol: NFLX.NAS\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:10:55, SYMBOL: NFLX.NAS, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: TSLA.NAS\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:10:56, SYMBOL: TSLA.NAS, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: AAPL.NAS\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:10:57, SYMBOL: AAPL.NAS, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 AAPL.NAS: Placing new SELL order.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=1000.0)\n",
"Sending order request: {'action': 1, 'symbol': 'AAPL.NAS', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order failed details: Date/Time: 2025-05-01 16:10:57\n",
"Order Type: SELL\n",
"Lot Size: 0.1\n",
"SL: None\n",
"TP: None\n",
"Comment: RFFV-D\n",
"Request: {'action': 1, 'symbol': 'AAPL.NAS', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Result: OrderSendResult(retcode=10044, deal=0, order=0, volume=0.0, price=0.0, bid=0.0, ask=0.0, comment='Only position closing is allowed', request_id=0, retcode_external=0, request=TradeRequest(action=1, magic=234003, order=0, symbol='AAPL.NAS', volume=0.1, price=0.0, stoplimit=0.0, sl=0.0, tp=0.0, deviation=20, type=1, type_filling=1, type_time=0, expiration=0, comment='RFFV-D', position=0, position_by=0))\n",
"Symbol AAPL.NAS added to retry queue for later attempt.\n",
"🔵 Checking Symbol: XOM.NYSE\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:10:59, SYMBOL: XOM.NYSE, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 XOM.NYSE: Placing new SELL order.\n",
"Zero or invalid bid/ask for XOM.NYSE: bid=0.0, ask=0.0\n",
"🔵 Checking Symbol: EURGBP\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:10:59, SYMBOL: EURGBP, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURGBP: Flat signal. No position open.\n",
"🔵 Checking Symbol: US500\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:11:00, SYMBOL: US500, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: USDCHF\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:11:01, SYMBOL: USDCHF, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 USDCHF: Flat signal. No position open.\n",
"🔵 Checking Symbol: EURUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:11:02, SYMBOL: EURUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 EURUSD: Flat signal. No position open.\n",
"🔵 Checking Symbol: MSFT.NAS\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:11:04, SYMBOL: MSFT.NAS, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 MSFT.NAS: Placing new SELL order.\n",
"Zero or invalid bid/ask for MSFT.NAS: bid=0.0, ask=0.0\n",
"🔵 Checking Symbol: AUDUSD\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:11:04, SYMBOL: AUDUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"🟤 AUDUSD: Flat signal. No position open.\n",
"🔵 Checking Symbol: BA.NYSE\n",
"⚠️ Error processing BA.NYSE: 'time'\n",
"🔵 Checking Symbol: JPM.NYSE\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:11:07, SYMBOL: JPM.NYSE, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: DIS.NYSE\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:11:08, SYMBOL: DIS.NYSE, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 DIS.NYSE: Placing new SELL order.\n",
"Zero or invalid bid/ask for DIS.NYSE: bid=0.0, ask=0.0\n",
"🔵 Checking Symbol: DE40\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:11:09, SYMBOL: DE40, BUY SIGNAL: False, SELL SIGNAL: False\n",
"🟤 DE40: Flat signal. No position open.\n",
"🔵 Checking Symbol: JP225\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:11:10, SYMBOL: JP225, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: AMZN.NAS\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:11:11, SYMBOL: AMZN.NAS, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"🔴 AMZN.NAS: Placing new SELL order.\n",
"Zero or invalid bid/ask for AMZN.NAS: bid=0.0, ask=0.0\n",
"🔵 Checking Symbol: UK100\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:11:12, SYMBOL: UK100, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: GOOG.NAS\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:11:13, SYMBOL: GOOG.NAS, BUY SIGNAL: False, SELL SIGNAL: True\n",
"🔵 Checking Symbol: BABA.NYSE\n",
"------------------------------------------------------------------\n",
"🟡 Date: 2025-05-01 16:11:14, SYMBOL: BABA.NYSE, BUY SIGNAL: False, SELL SIGNAL: True\n",
"✅ Successful Orders: 14\n",
"❌ Failed Orders: 7\n",
"⏳ Retry Queue: ['AAPL.NAS']\n"
]
}
],
"source": [
"# LIVE TRADING CODE FOR MULTI-BAR CLASSIFICATION\n",
"\n",
"import sys\n",
"import os\n",
"import warnings\n",
"from pathlib import Path\n",
"\n",
"# ---------------------------------------------------------------------------\n",
"# 1) SET PROJECT ROOT AND UPDATE PATH/WORKING DIRECTORY\n",
"# ---------------------------------------------------------------------------\n",
"project_root = Path.cwd().parent.parent # Adjust if your notebook is in notebooks/time_series\n",
"sys.path.append(str(project_root))\n",
"os.chdir(str(project_root))\n",
"warnings.filterwarnings(\"ignore\")\n",
"\n",
"import warnings\n",
"warnings.filterwarnings(\"ignore\")\n",
"import MetaTrader5 as mt5\n",
"import pandas as pd\n",
"import numpy as np\n",
"import ta\n",
"from datetime import datetime, timedelta\n",
"import time\n",
"import logging\n",
"import joblib\n",
"\n",
"# Setup logging\n",
"logging.basicConfig(\n",
" filename='models/saved_models/trading_app1.log',\n",
" level=logging.INFO,\n",
" format='%(asctime)s %(levelname)s:%(message)s',\n",
" datefmt='%Y-%m-%d %H:%M:%S'\n",
")\n",
"\n",
"def log_and_print(message, is_error=False):\n",
" \"\"\"\n",
" Logs and prints a message.\n",
" If is_error=True, logs at the ERROR level; otherwise logs at INFO level.\n",
" \"\"\"\n",
" if is_error:\n",
" logging.error(message)\n",
" else:\n",
" logging.info(message)\n",
" print(message)\n",
"\n",
"# Update the login credentials and server information accordingly\n",
"#name = 66677507\n",
"#key = 'ST746$nG38'\n",
"#serv = 'ICMarketsSC-Demo'\n",
"\n",
"# Global variables\n",
"symbols = [\n",
" \"EURUSD\", \"USDJPY\", \"AUDUSD\", \"GBPUSD\", \"USDCHF\", \"EURGBP\",\n",
" \"MSFT.NAS\", \"TSLA.NAS\", \"NVDA.NAS\", \"AMZN.NAS\", \"GOOG.NAS\", \"NFLX.NAS\", \"AAPL.NAS\",\n",
" \"BABA.NYSE\", \"JPM.NYSE\", \"XOM.NYSE\", \"BA.NYSE\", \"DIS.NYSE\", \"NKE.NYSE\",\"JP225\"\n",
"]\n",
"\n",
"lot_sizes = {\n",
" \n",
" \"US500\": 0.1,\n",
" \"JP225\": 1.00,\n",
"\n",
"}\n",
"\n",
"# Add Forex and Stocks with 0.01 lot size\n",
"for symbol in symbols:\n",
" if symbol not in lot_sizes:\n",
" lot_sizes[symbol] = 0.01\n",
"\n",
"model_paths = {\n",
" symbol: f\"models/h1_models/{symbol}_H1_best_model.pkl\" for symbol in symbols\n",
"}\n",
"\n",
"\n",
"TIMEFRAME = mt5.TIMEFRAME_H1\n",
"N_BARS = 1000\n",
"MAGIC_NUMBER = 234003\n",
"SLEEP_TIME = 3600 # 1 hour\n",
"COMMENT_ML = \"RFFV-D\"\n",
"\n",
"success_count = 0\n",
"fail_count = 0\n",
"retry_queue = []\n",
"# Global setting for whether to close open positions on flat (neutral) signal\n",
"CLOSE_ON_FLAT = True\n",
"\n",
"\n",
"# If you still need feature selection, you can keep this helper function:\n",
"def select_features_rf_reg(X, y, estimator, max_features=20):\n",
" \"\"\"\n",
" Example helper function for feature selection using RandomForest.\n",
" \"\"\"\n",
" from sklearn.feature_selection import SelectFromModel\n",
" selector = SelectFromModel(estimator=estimator, threshold=-np.inf, max_features=max_features).fit(X, y)\n",
" X_transformed = selector.transform(X)\n",
" selected_features_mask = selector.get_support()\n",
" return X_transformed, selected_features_mask\n",
"\n",
"def is_us_stock(symbol):\n",
" return symbol.endswith(\".NAS\") or symbol.endswith(\".NYSE\")\n",
"\n",
"def is_us_market_open():\n",
" \"\"\"\n",
" Check if US stock market is open based on Switzerland time (CET/CEST).\n",
" \"\"\"\n",
" now = datetime.now()\n",
"\n",
" if now.weekday() >= 5: # Saturday or Sunday\n",
" return False\n",
"\n",
" market_open = now.replace(hour=15, minute=30, second=0, microsecond=0)\n",
" market_close = now.replace(hour=22, minute=0, second=0, microsecond=0)\n",
"\n",
" return market_open <= now <= market_close\n",
"\n",
"\n",
"\n",
"\n",
"class TradingApp:\n",
" def __init__(self, symbol, lot_size, magic_number):\n",
" self.symbol = symbol\n",
" self.lot_size = lot_size\n",
" self.magic_number = magic_number\n",
" self.pipeline = None # We'll store the loaded classification pipeline here\n",
" self.last_retrain_time = None\n",
"\n",
" def get_data(self, symbol, n, timeframe):\n",
" \"\"\"\n",
" Fetch 'n' bars of historical data for the given symbol and timeframe.\n",
" \"\"\"\n",
" rates = mt5.copy_rates_from_pos(symbol, timeframe, 0, n)\n",
" rates_frame = pd.DataFrame(rates)\n",
" rates_frame['time'] = pd.to_datetime(rates_frame['time'], unit='s')\n",
" rates_frame.set_index('time', inplace=True)\n",
" return rates_frame\n",
"\n",
" def add_all_ta_features(self, df):\n",
" \"\"\"\n",
" Add technical analysis features to the DataFrame using the 'ta' library.\n",
" \"\"\"\n",
" df = ta.add_all_ta_features(\n",
" df, open=\"open\", high=\"high\", low=\"low\", close=\"close\", volume=\"tick_volume\", fillna=True\n",
" )\n",
" return df\n",
"\n",
" def load_pipeline(self, pipeline_path):\n",
" \"\"\"\n",
" Loads a pre-trained classification pipeline (either a Pipeline or a dict).\n",
" \"\"\"\n",
" pipeline_loaded = joblib.load(pipeline_path)\n",
"\n",
" # If it's a dict, extract the model\n",
" if isinstance(pipeline_loaded, dict):\n",
" self.pipeline = pipeline_loaded[\"model\"]\n",
" else:\n",
" self.pipeline = pipeline_loaded\n",
"\n",
" logging.info(f\"Loaded pipeline from {pipeline_path}\")\n",
" log_and_print(f\"Loaded pipeline from {pipeline_path}\")\n",
"\n",
"\n",
" def ml_signal_generation(self, symbol, n_bars, timeframe):\n",
" \"\"\"\n",
" Generate buy/sell signals using the loaded classification pipeline.\n",
" The pipeline outputs SHIFTED labels in {0,1,2} => we SHIFT them back to {-1,0,+1}.\n",
" We'll interpret +1 => buy, -1 => sell, 0 => no trade.\n",
" \"\"\"\n",
" if self.pipeline is None:\n",
" logging.error(\"No pipeline loaded. Call load_pipeline(...) first.\")\n",
" return False, False, True, True\n",
"\n",
" # 1) Fetch new data\n",
" df = self.get_data(symbol, n_bars, timeframe)\n",
"\n",
" # 2) Add TA features\n",
" df = self.add_all_ta_features(df)\n",
" df.fillna(method='ffill', inplace=True)\n",
"\n",
" # 3) Prepare the features\n",
" X_new = df # The pipeline must handle columns in the correct order.\n",
"\n",
" # 4) Predict SHIFTED classes\n",
" preds_shifted = self.pipeline.predict(X_new)\n",
" # SHIFT them back: 0->-1, 1->0, 2->+1\n",
" preds = preds_shifted - 1\n",
"\n",
" # Get the latest predicted class\n",
" latest_pred = preds[-1]\n",
" # If latest_pred == +1 => buy signal\n",
" # If latest_pred == -1 => sell signal\n",
" # If 0 => do nothing\n",
" buy_signal = (latest_pred == 1)\n",
" sell_signal = (latest_pred == -1)\n",
"\n",
" return buy_signal, sell_signal, not buy_signal, not sell_signal\n",
"\n",
" def orders(self, symbol, lot, is_buy=True, id_position=None, sl=None, tp=None):\n",
" \"\"\"\n",
" Place an order (BUY or SELL) for the specified symbol and lot size.\n",
" \"\"\"\n",
" global success_count, fail_count, retry_queue\n",
"\n",
" symbol_info = mt5.symbol_info(symbol)\n",
" if symbol_info is None:\n",
" log_and_print(f\"Symbol {symbol} not found, can't place order.\", is_error=True)\n",
" fail_count += 1\n",
" return \"Symbol not found\"\n",
"\n",
" # Make sure symbol is visible\n",
" if not symbol_info.visible:\n",
" if not mt5.symbol_select(symbol, True):\n",
" log_and_print(f\"Failed to select symbol {symbol}\", is_error=True)\n",
" fail_count += 1\n",
" return \"Symbol not visible or could not be selected.\"\n",
"\n",
" tick_info = mt5.symbol_info_tick(symbol)\n",
" if tick_info is None:\n",
" log_and_print(f\"Could not get tick info for {symbol}.\", is_error=True)\n",
" fail_count += 1\n",
" return \"Tick info unavailable\"\n",
"\n",
" # Check for valid bid/ask\n",
" if tick_info.bid <= 0 or tick_info.ask <= 0:\n",
" log_and_print(\n",
" f\"Zero or invalid bid/ask for {symbol}: bid={tick_info.bid}, ask={tick_info.ask}\",\n",
" is_error=True\n",
" )\n",
" fail_count += 1\n",
" return \"Invalid prices\"\n",
"\n",
" # LOT SIZE VALIDATION\n",
" lot = max(lot, symbol_info.volume_min)\n",
" step = symbol_info.volume_step\n",
" if step > 0:\n",
" remainder = lot % step\n",
" if remainder != 0:\n",
" lot = lot - remainder + step\n",
" if lot > symbol_info.volume_max:\n",
" lot = symbol_info.volume_max\n",
"\n",
" log_and_print(\n",
" f\"Adjusted lot size to {lot} (min={symbol_info.volume_min}, \"\n",
" f\"step={symbol_info.volume_step}, max={symbol_info.volume_max})\"\n",
" )\n",
"\n",
" # Force ORDER_FILLING_IOC\n",
" filling_mode = 1 # ORDER_FILLING_IOC\n",
"\n",
" order_type = mt5.ORDER_TYPE_BUY if is_buy else mt5.ORDER_TYPE_SELL\n",
" order_price = tick_info.ask if is_buy else tick_info.bid\n",
" deviation = 20\n",
"\n",
" request = {\n",
" \"action\": mt5.TRADE_ACTION_DEAL,\n",
" \"symbol\": symbol,\n",
" \"volume\": lot,\n",
" \"type\": order_type,\n",
" \"deviation\": deviation,\n",
" \"magic\": self.magic_number,\n",
" \"comment\": COMMENT_ML,\n",
" \"type_time\": mt5.ORDER_TIME_GTC,\n",
" \"type_filling\": filling_mode,\n",
" }\n",
"\n",
" if sl is not None:\n",
" request[\"sl\"] = sl\n",
" if tp is not None:\n",
" request[\"tp\"] = tp\n",
" if id_position is not None:\n",
" request[\"position\"] = id_position\n",
"\n",
" log_and_print(f\"Sending order request: {request}\")\n",
" result = mt5.order_send(request)\n",
"\n",
" order_type_str = \"BUY\" if is_buy else \"SELL\"\n",
"\n",
" if result is None or result.retcode != mt5.TRADE_RETCODE_DONE:\n",
" fail_count += 1\n",
" error_message = f\"Order failed for {symbol}\"\n",
" if result:\n",
" error_message += f\", retcode={result.retcode}, comment={result.comment}\"\n",
" additional_info = (\n",
" f\"Date/Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\\n\"\n",
" f\"Order Type: {order_type_str}\\n\"\n",
" f\"Lot Size: {lot}\\n\"\n",
" f\"SL: {sl if sl else 'None'}\\n\"\n",
" f\"TP: {tp if tp else 'None'}\\n\"\n",
" f\"Comment: {COMMENT_ML}\\n\"\n",
" f\"Request: {request}\\n\"\n",
" f\"Result: {result}\"\n",
" )\n",
" log_and_print(f\"Order failed details: {additional_info}\", is_error=True)\n",
"\n",
" # If market closed or only closing allowed => add to retry queue\n",
" if result is not None and result.retcode in [10018, 10044]:\n",
" retry_queue.append((symbol, datetime.now() + timedelta(minutes=15)))\n",
" log_and_print(f\"Symbol {symbol} added to retry queue for later attempt.\", is_error=False)\n",
"\n",
" else:\n",
" success_count += 1\n",
" success_message = f\"Order successful for {symbol}, comment={result.comment}\"\n",
" additional_info = (\n",
" f\"Date/Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\\n\"\n",
" f\"Order Type: {order_type_str}\\n\"\n",
" f\"Lot Size: {lot}\\n\"\n",
" f\"SL: {sl if sl else 'None'}\\n\"\n",
" f\"TP: {tp if tp else 'None'}\\n\"\n",
" f\"Comment: {COMMENT_ML}\"\n",
" )\n",
" log_and_print(success_message)\n",
"\n",
"\n",
" def get_positions_by_magic(self, symbol, magic_number):\n",
" \"\"\"\n",
" Retrieve positions for a specific symbol and magic number.\n",
" \"\"\"\n",
" all_positions = mt5.positions_get(symbol=symbol)\n",
" if not all_positions:\n",
" log_and_print(\"No positions found.\", is_error=False)\n",
" return []\n",
" return [pos for pos in all_positions if pos.magic == magic_number]\n",
"\n",
" def run_strategy(self, symbol, lot, buy_signal, sell_signal):\n",
" \"\"\"\n",
" Run the trading strategy logic based on buy/sell signals, including flat signals.\n",
" \"\"\"\n",
" log_and_print(\"------------------------------------------------------------------\")\n",
" log_and_print(\n",
" f\"🟡 Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}, \"\n",
" f\"SYMBOL: {symbol}, BUY SIGNAL: {buy_signal}, SELL SIGNAL: {sell_signal}\"\n",
" )\n",
"\n",
" positions = self.get_positions_by_magic(symbol, self.magic_number)\n",
" has_buy = any(pos.type == mt5.POSITION_TYPE_BUY for pos in positions)\n",
" has_sell = any(pos.type == mt5.POSITION_TYPE_SELL for pos in positions)\n",
"\n",
" if buy_signal and not has_buy:\n",
" if has_sell:\n",
" log_and_print(f\"🔄 {symbol}: Existing SELL position found. Attempting to close it...\")\n",
" if self.close_position(symbol, is_buy=True):\n",
" log_and_print(f\"✅ {symbol}: Closed SELL. Placing new BUY order.\")\n",
" self.orders(symbol, lot, is_buy=True)\n",
" else:\n",
" log_and_print(f\"❌ {symbol}: Failed to close SELL position.\")\n",
" else:\n",
" log_and_print(f\"🟢 {symbol}: Placing new BUY order.\")\n",
" self.orders(symbol, lot, is_buy=True)\n",
"\n",
" elif sell_signal and not has_sell:\n",
" if has_buy:\n",
" log_and_print(f\"🔄 {symbol}: Existing BUY position found. Attempting to close it...\")\n",
" if self.close_position(symbol, is_buy=False):\n",
" log_and_print(f\"✅ {symbol}: Closed BUY. Placing new SELL order.\")\n",
" self.orders(symbol, lot, is_buy=False)\n",
" else:\n",
" log_and_print(f\"❌ {symbol}: Failed to close BUY position.\")\n",
" else:\n",
" log_and_print(f\"🔴 {symbol}: Placing new SELL order.\")\n",
" self.orders(symbol, lot, is_buy=False)\n",
"\n",
" elif not buy_signal and not sell_signal:\n",
" if has_buy or has_sell:\n",
" if CLOSE_ON_FLAT:\n",
" log_and_print(f\"⚪ {symbol}: Flat signal. CLOSE_ON_FLAT is True, attempting to close open position.\")\n",
" success = self.close_position(symbol, is_buy=has_sell)\n",
" if success:\n",
" log_and_print(f\"✅ {symbol}: Flat signal - Position closed.\")\n",
" else:\n",
" log_and_print(f\"❌ {symbol}: Flat signal - Failed to close position.\")\n",
" else:\n",
" log_and_print(f\"⚪ {symbol}: Flat signal but CLOSE_ON_FLAT is False. Holding current position.\")\n",
" else:\n",
" log_and_print(f\"🟤 {symbol}: Flat signal. No position open.\")\n",
"\n",
"\n",
"\n",
" def close_position(self, symbol, is_buy):\n",
" \"\"\"\n",
" Closes positions of the opposite type (BUY/SELL) for this app's magic number.\n",
" \"\"\"\n",
" positions = mt5.positions_get(symbol=symbol)\n",
" if not positions:\n",
" log_and_print(f\"No positions to close for symbol: {symbol}\")\n",
" return False\n",
"\n",
" initial_balance = mt5.account_info().balance\n",
" closed_any = False\n",
"\n",
" for position in positions:\n",
" if position.magic == self.magic_number and (\n",
" (is_buy and position.type == mt5.POSITION_TYPE_SELL) or\n",
" (not is_buy and position.type == mt5.POSITION_TYPE_BUY)\n",
" ):\n",
" # First try ORDER_FILLING_RETURN\n",
" close_request = {\n",
" \"action\": mt5.TRADE_ACTION_DEAL,\n",
" \"symbol\": symbol,\n",
" \"volume\": position.volume,\n",
" \"type\": mt5.ORDER_TYPE_BUY if position.type == mt5.POSITION_TYPE_SELL else mt5.ORDER_TYPE_SELL,\n",
" \"position\": position.ticket,\n",
" \"deviation\": 20,\n",
" \"magic\": self.magic_number,\n",
" \"comment\": COMMENT_ML,\n",
" \"type_time\": mt5.ORDER_TIME_GTC,\n",
" \"type_filling\": mt5.ORDER_FILLING_RETURN, # Try RETURN first\n",
" }\n",
" result = mt5.order_send(close_request)\n",
"\n",
" if result is None or result.retcode != mt5.TRADE_RETCODE_DONE:\n",
" # Retry WITH ORDER_FILLING_IOC instead of removing filling type\n",
" log_and_print(f\"⚠️ Filling mode error for {symbol} position {position.ticket}, retrying with ORDER_FILLING_IOC...\")\n",
" \n",
" close_request[\"type_filling\"] = mt5.ORDER_FILLING_IOC # Force IOC\n",
" result_retry = mt5.order_send(close_request)\n",
"\n",
" if result_retry is None or result_retry.retcode != mt5.TRADE_RETCODE_DONE:\n",
" log_and_print(f\"❌ Retry failed to close {symbol} — retcode: {result_retry.retcode}, comment: {result_retry.comment}\", is_error=True)\n",
" else:\n",
" log_and_print(f\"✅ Retry succeeded in closing {symbol} position {position.ticket}\")\n",
" closed_any = True\n",
" else:\n",
" log_and_print(f\"✅ Successfully closed position {position.ticket} for {symbol}\")\n",
" closed_any = True\n",
"\n",
" if closed_any:\n",
" final_balance = mt5.account_info().balance\n",
" profit = final_balance - initial_balance\n",
" log_and_print(f\"✅ Closed positions successfully, Profit: {profit}\")\n",
" return True\n",
" else:\n",
" return False\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" def check_and_execute_trades(self):\n",
" \"\"\"\n",
" Convenience method to perform the entire flow:\n",
" generate signals, run strategy, and deselect symbol.\n",
" \"\"\"\n",
" mt5.symbol_select(self.symbol, True)\n",
" buy, sell, _, _ = self.ml_signal_generation(self.symbol, N_BARS, TIMEFRAME)\n",
" self.run_strategy(self.symbol, self.lot_size, buy, sell)\n",
" mt5.symbol_select(self.symbol, False)\n",
" log_and_print(\"Waiting for new signals...\")\n",
"\n",
"def is_market_open():\n",
" \"\"\"\n",
" Check if the current time is within the typical Forex trading session, adjusted for CET/CEST.\n",
" Market closes at Friday 10:00 PM CET and opens at Sunday 11:00 PM CET. \n",
" It is closed all day Saturday.\n",
" \"\"\"\n",
" current_time_utc = datetime.utcnow()\n",
" # Adjust for Central European Time (UTC+1) or Central European Summer Time (UTC+2)\n",
" current_time_cet = (\n",
" current_time_utc + timedelta(hours=2) \n",
" if time.localtime().tm_isdst \n",
" else current_time_utc + timedelta(hours=1)\n",
" )\n",
"\n",
" # Friday after 10 PM CET\n",
" if current_time_cet.weekday() == 4 and current_time_cet.hour >= 22:\n",
" return False\n",
" # Sunday before 11 PM CET\n",
" elif current_time_cet.weekday() == 6 and current_time_cet.hour < 23:\n",
" return False\n",
" # All day Saturday\n",
" elif current_time_cet.weekday() == 5:\n",
" return False\n",
" return True\n",
"\n",
"\n",
"if __name__ == \"__main__\":\n",
" try:\n",
" if not mt5.initialize():\n",
" log_and_print(\"Failed to initialize MetaTrader 5\", is_error=True)\n",
" exit()\n",
"\n",
" # 1) Create a TradingApp per symbol\n",
" apps = {}\n",
" for symbol in symbols:\n",
" app = TradingApp(symbol=symbol, lot_size=lot_sizes[symbol], magic_number=MAGIC_NUMBER)\n",
" app.load_pipeline(model_paths[symbol])\n",
" apps[symbol] = app\n",
"\n",
" # 2) Initialize tracking variables\n",
" success_count = 0\n",
" fail_count = 0\n",
" retry_queue = []\n",
"\n",
" while True:\n",
" log_and_print(\"Checking market status...\")\n",
" if is_market_open():\n",
" log_and_print(\"Market is open. Executing trades...\")\n",
"\n",
" # Handle retry queue\n",
" now = datetime.now()\n",
" retry_symbols_ready = [item for item in retry_queue if item[1] <= now]\n",
" retry_queue = [item for item in retry_queue if item[1] > now]\n",
"\n",
" symbols_to_process = set(apps.keys())\n",
"\n",
" # Add retry symbols first\n",
" symbols_ready_to_retry = [item[0] for item in retry_symbols_ready]\n",
" if symbols_ready_to_retry:\n",
" log_and_print(f\"🔁 Retrying symbols: {symbols_ready_to_retry}\")\n",
" symbols_to_process = set(symbols_ready_to_retry) | symbols_to_process\n",
"\n",
" for symbol in symbols_to_process:\n",
" app = apps[symbol]\n",
"\n",
" try:\n",
" # Skip US stock symbols if US market is closed\n",
" if is_us_stock(symbol) and not is_us_market_open():\n",
" log_and_print(f\"🟠 Skipping {symbol}: US market not open yet.\")\n",
" continue\n",
"\n",
" log_and_print(f\"🔵 Checking Symbol: {symbol}\")\n",
" buy_signal, sell_signal, _, _ = app.ml_signal_generation(\n",
" symbol=app.symbol,\n",
" n_bars=N_BARS,\n",
" timeframe=TIMEFRAME\n",
" )\n",
" app.run_strategy(app.symbol, app.lot_size, buy_signal, sell_signal)\n",
"\n",
" except Exception as e:\n",
" log_and_print(f\"⚠️ Error processing {symbol}: {e}\", is_error=True)\n",
"\n",
" # After the trading round, log results\n",
" log_and_print(f\"✅ Successful Orders: {success_count}\")\n",
" log_and_print(f\"❌ Failed Orders: {fail_count}\")\n",
" log_and_print(f\"⏳ Retry Queue: {[item[0] for item in retry_queue]}\")\n",
"\n",
" else:\n",
" log_and_print(\"Market is closed. Waiting...\")\n",
"\n",
" time.sleep(SLEEP_TIME)\n",
"\n",
" except KeyboardInterrupt:\n",
" log_and_print(\"Shutdown signal received.\")\n",
"\n",
" except Exception as e:\n",
" error_message = f\"An error occurred: {e}\"\n",
" log_and_print(error_message, is_error=True)\n",
"\n",
" finally:\n",
" mt5.shutdown()\n",
" log_and_print(\"MetaTrader 5 shutdown completed.\")\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Loaded pipeline from models/simple_models/EURUSD_best_model.pkl\n",
"Loaded pipeline from models/simple_models/USDJPY_best_model.pkl\n",
"Loaded pipeline from models/simple_models/AUDUSD_best_model.pkl\n",
"Loaded pipeline from models/simple_models/GBPUSD_best_model.pkl\n",
"Loaded pipeline from models/simple_models/USDCHF_best_model.pkl\n",
"Loaded pipeline from models/simple_models/EURGBP_best_model.pkl\n",
"Loaded pipeline from models/simple_models/MSFT.NAS_best_model.pkl\n",
"Loaded pipeline from models/simple_models/TSLA.NAS_best_model.pkl\n",
"Loaded pipeline from models/simple_models/NVDA.NAS_best_model.pkl\n",
"Loaded pipeline from models/simple_models/AMZN.NAS_best_model.pkl\n",
"Loaded pipeline from models/simple_models/GOOG.NAS_best_model.pkl\n",
"Loaded pipeline from models/simple_models/NFLX.NAS_best_model.pkl\n",
"Loaded pipeline from models/simple_models/AAPL.NAS_best_model.pkl\n",
"Loaded pipeline from models/simple_models/BABA.NYSE_best_model.pkl\n",
"Loaded pipeline from models/simple_models/JPM.NYSE_best_model.pkl\n",
"Loaded pipeline from models/simple_models/XOM.NYSE_best_model.pkl\n",
"Loaded pipeline from models/simple_models/BA.NYSE_best_model.pkl\n",
"Loaded pipeline from models/simple_models/DIS.NYSE_best_model.pkl\n",
"Loaded pipeline from models/simple_models/NKE.NYSE_best_model.pkl\n",
"Loaded pipeline from models/simple_models/JP225_best_model.pkl\n",
"Loaded pipeline from models/simple_models/US500_best_model.pkl\n",
"Loaded pipeline from models/simple_models/UK100_best_model.pkl\n",
"Checking market status...\n",
"Market is open. Executing trades...\n",
"🔵 Checking Symbol: EURUSD\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:01:46, SYMBOL: EURUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"Appropriate position already exists or no signal to act on.\n",
"🔵 Checking Symbol: USDJPY\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:01:47, SYMBOL: USDJPY, BUY SIGNAL: False, SELL SIGNAL: True\n",
"Appropriate position already exists or no signal to act on.\n",
"🔵 Checking Symbol: AUDUSD\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:01:48, SYMBOL: AUDUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"Appropriate position already exists or no signal to act on.\n",
"🔵 Checking Symbol: GBPUSD\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:01:51, SYMBOL: GBPUSD, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"Appropriate position already exists or no signal to act on.\n",
"🔵 Checking Symbol: USDCHF\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:01:55, SYMBOL: USDCHF, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"Appropriate position already exists or no signal to act on.\n",
"🔵 Checking Symbol: EURGBP\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:01:58, SYMBOL: EURGBP, BUY SIGNAL: False, SELL SIGNAL: True\n",
"Appropriate position already exists or no signal to act on.\n",
"🔵 Checking Symbol: MSFT.NAS\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:01:59, SYMBOL: MSFT.NAS, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=1000.0)\n",
"Sending order request: {'action': 1, 'symbol': 'MSFT.NAS', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order failed details: Date/Time: 2025-04-28 15:01:59\n",
"Order Type: SELL\n",
"Lot Size: 0.1\n",
"SL: None\n",
"TP: None\n",
"Comment: RFFV-D\n",
"Request: {'action': 1, 'symbol': 'MSFT.NAS', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Result: OrderSendResult(retcode=10044, deal=0, order=0, volume=0.0, price=0.0, bid=0.0, ask=0.0, comment='Only position closing is allowed', request_id=0, retcode_external=0, request=TradeRequest(action=1, magic=234003, order=0, symbol='MSFT.NAS', volume=0.1, price=0.0, stoplimit=0.0, sl=0.0, tp=0.0, deviation=20, type=1, type_filling=1, type_time=0, expiration=0, comment='RFFV-D', position=0, position_by=0))\n",
"🔵 Checking Symbol: TSLA.NAS\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" File \"c:\\Users\\moham\\miniconda3\\envs\\ml\\Lib\\site-packages\\joblib\\externals\\loky\\backend\\context.py\", line 257, in _count_physical_cores\n",
" cpu_info = subprocess.run(\n",
" ^^^^^^^^^^^^^^^\n",
" File \"c:\\Users\\moham\\miniconda3\\envs\\ml\\Lib\\subprocess.py\", line 548, in run\n",
" with Popen(*popenargs, **kwargs) as process:\n",
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n",
" File \"c:\\Users\\moham\\miniconda3\\envs\\ml\\Lib\\subprocess.py\", line 1026, in __init__\n",
" self._execute_child(args, executable, preexec_fn, close_fds,\n",
" File \"c:\\Users\\moham\\miniconda3\\envs\\ml\\Lib\\subprocess.py\", line 1538, in _execute_child\n",
" hp, ht, pid, tid = _winapi.CreateProcess(executable, args,\n",
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:02:01, SYMBOL: TSLA.NAS, BUY SIGNAL: True, SELL SIGNAL: False\n",
"No positions found.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=1000.0)\n",
"Sending order request: {'action': 1, 'symbol': 'TSLA.NAS', 'volume': 0.1, 'type': 0, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order failed details: Date/Time: 2025-04-28 15:02:01\n",
"Order Type: BUY\n",
"Lot Size: 0.1\n",
"SL: None\n",
"TP: None\n",
"Comment: RFFV-D\n",
"Request: {'action': 1, 'symbol': 'TSLA.NAS', 'volume': 0.1, 'type': 0, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Result: OrderSendResult(retcode=10018, deal=0, order=0, volume=0.0, price=0.0, bid=0.0, ask=0.0, comment='Market closed', request_id=753743240, retcode_external=0, request=TradeRequest(action=1, magic=234003, order=0, symbol='TSLA.NAS', volume=0.1, price=0.0, stoplimit=0.0, sl=0.0, tp=0.0, deviation=20, type=0, type_filling=1, type_time=0, expiration=0, comment='RFFV-D', position=0, position_by=0))\n",
"🔵 Checking Symbol: NVDA.NAS\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:02:02, SYMBOL: NVDA.NAS, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=1000.0)\n",
"Sending order request: {'action': 1, 'symbol': 'NVDA.NAS', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order failed details: Date/Time: 2025-04-28 15:02:02\n",
"Order Type: SELL\n",
"Lot Size: 0.1\n",
"SL: None\n",
"TP: None\n",
"Comment: RFFV-D\n",
"Request: {'action': 1, 'symbol': 'NVDA.NAS', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Result: OrderSendResult(retcode=10018, deal=0, order=0, volume=0.0, price=0.0, bid=0.0, ask=0.0, comment='Market closed', request_id=753743241, retcode_external=0, request=TradeRequest(action=1, magic=234003, order=0, symbol='NVDA.NAS', volume=0.1, price=0.0, stoplimit=0.0, sl=0.0, tp=0.0, deviation=20, type=1, type_filling=1, type_time=0, expiration=0, comment='RFFV-D', position=0, position_by=0))\n",
"🔵 Checking Symbol: AMZN.NAS\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:02:03, SYMBOL: AMZN.NAS, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=1000.0)\n",
"Sending order request: {'action': 1, 'symbol': 'AMZN.NAS', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order failed details: Date/Time: 2025-04-28 15:02:03\n",
"Order Type: SELL\n",
"Lot Size: 0.1\n",
"SL: None\n",
"TP: None\n",
"Comment: RFFV-D\n",
"Request: {'action': 1, 'symbol': 'AMZN.NAS', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Result: OrderSendResult(retcode=10044, deal=0, order=0, volume=0.0, price=0.0, bid=0.0, ask=0.0, comment='Only position closing is allowed', request_id=0, retcode_external=0, request=TradeRequest(action=1, magic=234003, order=0, symbol='AMZN.NAS', volume=0.1, price=0.0, stoplimit=0.0, sl=0.0, tp=0.0, deviation=20, type=1, type_filling=1, type_time=0, expiration=0, comment='RFFV-D', position=0, position_by=0))\n",
"🔵 Checking Symbol: GOOG.NAS\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:02:04, SYMBOL: GOOG.NAS, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=1000.0)\n",
"Sending order request: {'action': 1, 'symbol': 'GOOG.NAS', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order failed details: Date/Time: 2025-04-28 15:02:04\n",
"Order Type: SELL\n",
"Lot Size: 0.1\n",
"SL: None\n",
"TP: None\n",
"Comment: RFFV-D\n",
"Request: {'action': 1, 'symbol': 'GOOG.NAS', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Result: OrderSendResult(retcode=10018, deal=0, order=0, volume=0.0, price=0.0, bid=0.0, ask=0.0, comment='Market closed', request_id=753743242, retcode_external=0, request=TradeRequest(action=1, magic=234003, order=0, symbol='GOOG.NAS', volume=0.1, price=0.0, stoplimit=0.0, sl=0.0, tp=0.0, deviation=20, type=1, type_filling=1, type_time=0, expiration=0, comment='RFFV-D', position=0, position_by=0))\n",
"🔵 Checking Symbol: NFLX.NAS\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:02:05, SYMBOL: NFLX.NAS, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=1000.0)\n",
"Sending order request: {'action': 1, 'symbol': 'NFLX.NAS', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order failed details: Date/Time: 2025-04-28 15:02:05\n",
"Order Type: SELL\n",
"Lot Size: 0.1\n",
"SL: None\n",
"TP: None\n",
"Comment: RFFV-D\n",
"Request: {'action': 1, 'symbol': 'NFLX.NAS', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Result: OrderSendResult(retcode=10018, deal=0, order=0, volume=0.0, price=0.0, bid=0.0, ask=0.0, comment='Market closed', request_id=753743243, retcode_external=0, request=TradeRequest(action=1, magic=234003, order=0, symbol='NFLX.NAS', volume=0.1, price=0.0, stoplimit=0.0, sl=0.0, tp=0.0, deviation=20, type=1, type_filling=1, type_time=0, expiration=0, comment='RFFV-D', position=0, position_by=0))\n",
"🔵 Checking Symbol: AAPL.NAS\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:02:06, SYMBOL: AAPL.NAS, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=1000.0)\n",
"Sending order request: {'action': 1, 'symbol': 'AAPL.NAS', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order failed details: Date/Time: 2025-04-28 15:02:06\n",
"Order Type: SELL\n",
"Lot Size: 0.1\n",
"SL: None\n",
"TP: None\n",
"Comment: RFFV-D\n",
"Request: {'action': 1, 'symbol': 'AAPL.NAS', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Result: OrderSendResult(retcode=10044, deal=0, order=0, volume=0.0, price=0.0, bid=0.0, ask=0.0, comment='Only position closing is allowed', request_id=0, retcode_external=0, request=TradeRequest(action=1, magic=234003, order=0, symbol='AAPL.NAS', volume=0.1, price=0.0, stoplimit=0.0, sl=0.0, tp=0.0, deviation=20, type=1, type_filling=1, type_time=0, expiration=0, comment='RFFV-D', position=0, position_by=0))\n",
"🔵 Checking Symbol: BABA.NYSE\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:02:07, SYMBOL: BABA.NYSE, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=1000.0)\n",
"Sending order request: {'action': 1, 'symbol': 'BABA.NYSE', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order failed details: Date/Time: 2025-04-28 15:02:07\n",
"Order Type: SELL\n",
"Lot Size: 0.1\n",
"SL: None\n",
"TP: None\n",
"Comment: RFFV-D\n",
"Request: {'action': 1, 'symbol': 'BABA.NYSE', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Result: OrderSendResult(retcode=10018, deal=0, order=0, volume=0.0, price=0.0, bid=0.0, ask=0.0, comment='Market closed', request_id=753743244, retcode_external=0, request=TradeRequest(action=1, magic=234003, order=0, symbol='BABA.NYSE', volume=0.1, price=0.0, stoplimit=0.0, sl=0.0, tp=0.0, deviation=20, type=1, type_filling=1, type_time=0, expiration=0, comment='RFFV-D', position=0, position_by=0))\n",
"🔵 Checking Symbol: JPM.NYSE\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:02:09, SYMBOL: JPM.NYSE, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=1000.0)\n",
"Sending order request: {'action': 1, 'symbol': 'JPM.NYSE', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order failed details: Date/Time: 2025-04-28 15:02:09\n",
"Order Type: SELL\n",
"Lot Size: 0.1\n",
"SL: None\n",
"TP: None\n",
"Comment: RFFV-D\n",
"Request: {'action': 1, 'symbol': 'JPM.NYSE', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Result: OrderSendResult(retcode=10018, deal=0, order=0, volume=0.0, price=0.0, bid=0.0, ask=0.0, comment='Market closed', request_id=753743245, retcode_external=0, request=TradeRequest(action=1, magic=234003, order=0, symbol='JPM.NYSE', volume=0.1, price=0.0, stoplimit=0.0, sl=0.0, tp=0.0, deviation=20, type=1, type_filling=1, type_time=0, expiration=0, comment='RFFV-D', position=0, position_by=0))\n",
"🔵 Checking Symbol: XOM.NYSE\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:02:11, SYMBOL: XOM.NYSE, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"Appropriate position already exists or no signal to act on.\n",
"🔵 Checking Symbol: BA.NYSE\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:02:14, SYMBOL: BA.NYSE, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=1000.0)\n",
"Sending order request: {'action': 1, 'symbol': 'BA.NYSE', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order failed details: Date/Time: 2025-04-28 15:02:14\n",
"Order Type: SELL\n",
"Lot Size: 0.1\n",
"SL: None\n",
"TP: None\n",
"Comment: RFFV-D\n",
"Request: {'action': 1, 'symbol': 'BA.NYSE', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Result: OrderSendResult(retcode=10044, deal=0, order=0, volume=0.0, price=0.0, bid=0.0, ask=0.0, comment='Only position closing is allowed', request_id=0, retcode_external=0, request=TradeRequest(action=1, magic=234003, order=0, symbol='BA.NYSE', volume=0.1, price=0.0, stoplimit=0.0, sl=0.0, tp=0.0, deviation=20, type=1, type_filling=1, type_time=0, expiration=0, comment='RFFV-D', position=0, position_by=0))\n",
"🔵 Checking Symbol: DIS.NYSE\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:02:16, SYMBOL: DIS.NYSE, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=1000.0)\n",
"Sending order request: {'action': 1, 'symbol': 'DIS.NYSE', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order failed details: Date/Time: 2025-04-28 15:02:16\n",
"Order Type: SELL\n",
"Lot Size: 0.1\n",
"SL: None\n",
"TP: None\n",
"Comment: RFFV-D\n",
"Request: {'action': 1, 'symbol': 'DIS.NYSE', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Result: OrderSendResult(retcode=10044, deal=0, order=0, volume=0.0, price=0.0, bid=0.0, ask=0.0, comment='Only position closing is allowed', request_id=0, retcode_external=0, request=TradeRequest(action=1, magic=234003, order=0, symbol='DIS.NYSE', volume=0.1, price=0.0, stoplimit=0.0, sl=0.0, tp=0.0, deviation=20, type=1, type_filling=1, type_time=0, expiration=0, comment='RFFV-D', position=0, position_by=0))\n",
"🔵 Checking Symbol: NKE.NYSE\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:02:17, SYMBOL: NKE.NYSE, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"Adjusted lot size to 0.1 (min=0.1, step=0.1, max=1000.0)\n",
"Sending order request: {'action': 1, 'symbol': 'NKE.NYSE', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order failed details: Date/Time: 2025-04-28 15:02:17\n",
"Order Type: SELL\n",
"Lot Size: 0.1\n",
"SL: None\n",
"TP: None\n",
"Comment: RFFV-D\n",
"Request: {'action': 1, 'symbol': 'NKE.NYSE', 'volume': 0.1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Result: OrderSendResult(retcode=10018, deal=0, order=0, volume=0.0, price=0.0, bid=0.0, ask=0.0, comment='Market closed', request_id=753743246, retcode_external=0, request=TradeRequest(action=1, magic=234003, order=0, symbol='NKE.NYSE', volume=0.1, price=0.0, stoplimit=0.0, sl=0.0, tp=0.0, deviation=20, type=1, type_filling=1, type_time=0, expiration=0, comment='RFFV-D', position=0, position_by=0))\n",
"🔵 Checking Symbol: JP225\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:02:18, SYMBOL: JP225, BUY SIGNAL: False, SELL SIGNAL: True\n",
"No positions found.\n",
"Adjusted lot size to 1 (min=1.0, step=1.0, max=250.0)\n",
"Sending order request: {'action': 1, 'symbol': 'JP225', 'volume': 1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Order failed details: Date/Time: 2025-04-28 15:02:18\n",
"Order Type: SELL\n",
"Lot Size: 1\n",
"SL: None\n",
"TP: None\n",
"Comment: RFFV-D\n",
"Request: {'action': 1, 'symbol': 'JP225', 'volume': 1, 'type': 1, 'deviation': 20, 'magic': 234003, 'comment': 'RFFV-D', 'type_time': 0, 'type_filling': 1}\n",
"Result: None\n",
"🔵 Checking Symbol: US500\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:02:19, SYMBOL: US500, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"Appropriate position already exists or no signal to act on.\n",
"🔵 Checking Symbol: UK100\n",
"------------------------------------------------------------------\n",
"Date: 2025-04-28 15:02:20, SYMBOL: UK100, BUY SIGNAL: False, SELL SIGNAL: False\n",
"No positions found.\n",
"Appropriate position already exists or no signal to act on.\n"
]
}
],
"source": [
"# LIVE TRADING CODE FOR MULTI-BAR CLASSIFICATION\n",
"\n",
"import sys\n",
"import os\n",
"import warnings\n",
"from pathlib import Path\n",
"\n",
"# ---------------------------------------------------------------------------\n",
"# 1) SET PROJECT ROOT AND UPDATE PATH/WORKING DIRECTORY\n",
"# ---------------------------------------------------------------------------\n",
"project_root = Path.cwd().parent.parent # Adjust if your notebook is in notebooks/time_series\n",
"sys.path.append(str(project_root))\n",
"os.chdir(str(project_root))\n",
"warnings.filterwarnings(\"ignore\")\n",
"\n",
"import warnings\n",
"warnings.filterwarnings(\"ignore\")\n",
"import MetaTrader5 as mt5\n",
"import pandas as pd\n",
"import numpy as np\n",
"import ta\n",
"from datetime import datetime, timedelta\n",
"import time\n",
"import logging\n",
"import joblib\n",
"\n",
"# Setup logging\n",
"logging.basicConfig(\n",
" filename='models/saved_models/trading_app1.log',\n",
" level=logging.INFO,\n",
" format='%(asctime)s %(levelname)s:%(message)s',\n",
" datefmt='%Y-%m-%d %H:%M:%S'\n",
")\n",
"\n",
"def log_and_print(message, is_error=False):\n",
" \"\"\"\n",
" Logs and prints a message.\n",
" If is_error=True, logs at the ERROR level; otherwise logs at INFO level.\n",
" \"\"\"\n",
" if is_error:\n",
" logging.error(message)\n",
" else:\n",
" logging.info(message)\n",
" print(message)\n",
"\n",
"# Update the login credentials and server information accordingly\n",
"#name = 66677507\n",
"#key = 'ST746$nG38'\n",
"#serv = 'ICMarketsSC-Demo'\n",
"\n",
"# Global variables\n",
"symbols = [\n",
" \"EURUSD\", \"USDJPY\", \"AUDUSD\", \"GBPUSD\", \"USDCHF\", \"EURGBP\",\n",
" \"MSFT.NAS\", \"TSLA.NAS\", \"NVDA.NAS\", \"AMZN.NAS\", \"GOOG.NAS\", \"NFLX.NAS\", \"AAPL.NAS\",\n",
" \"BABA.NYSE\", \"JPM.NYSE\", \"XOM.NYSE\", \"BA.NYSE\", \"DIS.NYSE\", \"NKE.NYSE\",\n",
" \"JP225\", \"US500\", \"UK100\"\n",
"]\n",
"\n",
"lot_sizes = {\n",
" \"JP225\": 1,\n",
" \"US500\": 0.1,\n",
" \"UK100\": 0.1\n",
"}\n",
"\n",
"# Add Forex and Stocks with 0.01 lot size\n",
"for symbol in symbols:\n",
" if symbol not in lot_sizes:\n",
" lot_sizes[symbol] = 0.01\n",
"\n",
"model_paths = {\n",
" symbol: f\"models/simple_models/{symbol}_best_model.pkl\" for symbol in symbols\n",
"}\n",
"\n",
"\n",
"TIMEFRAME = mt5.TIMEFRAME_H4\n",
"N_BARS = 1000\n",
"MAGIC_NUMBER = 234003\n",
"SLEEP_TIME = 14400 # 4 hours\n",
"COMMENT_ML = \"RFFV-D\"\n",
"\n",
"# If you still need feature selection, you can keep this helper function:\n",
"def select_features_rf_reg(X, y, estimator, max_features=20):\n",
" \"\"\"\n",
" Example helper function for feature selection using RandomForest.\n",
" \"\"\"\n",
" from sklearn.feature_selection import SelectFromModel\n",
" selector = SelectFromModel(estimator=estimator, threshold=-np.inf, max_features=max_features).fit(X, y)\n",
" X_transformed = selector.transform(X)\n",
" selected_features_mask = selector.get_support()\n",
" return X_transformed, selected_features_mask\n",
"\n",
"class TradingApp:\n",
" def __init__(self, symbol, lot_size, magic_number):\n",
" self.symbol = symbol\n",
" self.lot_size = lot_size\n",
" self.magic_number = magic_number\n",
" self.pipeline = None # We'll store the loaded classification pipeline here\n",
" self.last_retrain_time = None\n",
"\n",
" def get_data(self, symbol, n, timeframe):\n",
" \"\"\"\n",
" Fetch 'n' bars of historical data for the given symbol and timeframe.\n",
" \"\"\"\n",
" rates = mt5.copy_rates_from_pos(symbol, timeframe, 0, n)\n",
" rates_frame = pd.DataFrame(rates)\n",
" rates_frame['time'] = pd.to_datetime(rates_frame['time'], unit='s')\n",
" rates_frame.set_index('time', inplace=True)\n",
" return rates_frame\n",
"\n",
" def add_all_ta_features(self, df):\n",
" \"\"\"\n",
" Add technical analysis features to the DataFrame using the 'ta' library.\n",
" \"\"\"\n",
" df = ta.add_all_ta_features(\n",
" df, open=\"open\", high=\"high\", low=\"low\", close=\"close\", volume=\"tick_volume\", fillna=True\n",
" )\n",
" return df\n",
"\n",
" def load_pipeline(self, pipeline_path):\n",
" \"\"\"\n",
" Loads a pre-trained classification pipeline (either a Pipeline or a dict).\n",
" \"\"\"\n",
" pipeline_loaded = joblib.load(pipeline_path)\n",
"\n",
" # If it's a dict, extract the model\n",
" if isinstance(pipeline_loaded, dict):\n",
" self.pipeline = pipeline_loaded[\"model\"]\n",
" else:\n",
" self.pipeline = pipeline_loaded\n",
"\n",
" logging.info(f\"Loaded pipeline from {pipeline_path}\")\n",
" log_and_print(f\"Loaded pipeline from {pipeline_path}\")\n",
"\n",
"\n",
" def ml_signal_generation(self, symbol, n_bars, timeframe):\n",
" \"\"\"\n",
" Generate buy/sell signals using the loaded classification pipeline.\n",
" The pipeline outputs SHIFTED labels in {0,1,2} => we SHIFT them back to {-1,0,+1}.\n",
" We'll interpret +1 => buy, -1 => sell, 0 => no trade.\n",
" \"\"\"\n",
" if self.pipeline is None:\n",
" logging.error(\"No pipeline loaded. Call load_pipeline(...) first.\")\n",
" return False, False, True, True\n",
"\n",
" # 1) Fetch new data\n",
" df = self.get_data(symbol, n_bars, timeframe)\n",
"\n",
" # 2) Add TA features\n",
" df = self.add_all_ta_features(df)\n",
" df.fillna(method='ffill', inplace=True)\n",
"\n",
" # 3) Prepare the features\n",
" X_new = df # The pipeline must handle columns in the correct order.\n",
"\n",
" # 4) Predict SHIFTED classes\n",
" preds_shifted = self.pipeline.predict(X_new)\n",
" # SHIFT them back: 0->-1, 1->0, 2->+1\n",
" preds = preds_shifted - 1\n",
"\n",
" # Get the latest predicted class\n",
" latest_pred = preds[-1]\n",
" # If latest_pred == +1 => buy signal\n",
" # If latest_pred == -1 => sell signal\n",
" # If 0 => do nothing\n",
" buy_signal = (latest_pred == 1)\n",
" sell_signal = (latest_pred == -1)\n",
"\n",
" return buy_signal, sell_signal, not buy_signal, not sell_signal\n",
"\n",
" def orders(self, symbol, lot, is_buy=True, id_position=None, sl=None, tp=None):\n",
" \"\"\"\n",
" Place an order (BUY or SELL) for the specified symbol and lot size.\n",
" \"\"\"\n",
" symbol_info = mt5.symbol_info(symbol)\n",
" if symbol_info is None:\n",
" log_and_print(f\"Symbol {symbol} not found, can't place order.\", is_error=True)\n",
" return \"Symbol not found\"\n",
"\n",
" # Make sure symbol is visible\n",
" if not symbol_info.visible:\n",
" if not mt5.symbol_select(symbol, True):\n",
" log_and_print(f\"Failed to select symbol {symbol}\", is_error=True)\n",
" return \"Symbol not visible or could not be selected.\"\n",
"\n",
" tick_info = mt5.symbol_info_tick(symbol)\n",
" if tick_info is None:\n",
" log_and_print(f\"Could not get tick info for {symbol}.\", is_error=True)\n",
" return \"Tick info unavailable\"\n",
"\n",
" # Check for valid bid/ask\n",
" if tick_info.bid <= 0 or tick_info.ask <= 0:\n",
" log_and_print(\n",
" f\"Zero or invalid bid/ask for {symbol}: bid={tick_info.bid}, ask={tick_info.ask}\",\n",
" is_error=True\n",
" )\n",
" return \"Invalid prices\"\n",
"\n",
" # LOT SIZE VALIDATION\n",
" lot = max(lot, symbol_info.volume_min)\n",
" step = symbol_info.volume_step\n",
" if step > 0:\n",
" remainder = lot % step\n",
" if remainder != 0:\n",
" lot = lot - remainder + step\n",
" if lot > symbol_info.volume_max:\n",
" lot = symbol_info.volume_max\n",
"\n",
" log_and_print(\n",
" f\"Adjusted lot size to {lot} (min={symbol_info.volume_min}, \"\n",
" f\"step={symbol_info.volume_step}, max={symbol_info.volume_max})\"\n",
" )\n",
"\n",
" # Force ORDER_FILLING_IOC\n",
" filling_mode = 1 # ORDER_FILLING_IOC\n",
"\n",
" order_type = mt5.ORDER_TYPE_BUY if is_buy else mt5.ORDER_TYPE_SELL\n",
" order_price = tick_info.ask if is_buy else tick_info.bid\n",
" deviation = 20\n",
"\n",
" request = {\n",
" \"action\": mt5.TRADE_ACTION_DEAL,\n",
" \"symbol\": symbol,\n",
" \"volume\": lot,\n",
" \"type\": order_type,\n",
" \"deviation\": deviation,\n",
" \"magic\": self.magic_number,\n",
" \"comment\": COMMENT_ML,\n",
" \"type_time\": mt5.ORDER_TIME_GTC,\n",
" \"type_filling\": filling_mode,\n",
" }\n",
"\n",
" if sl is not None:\n",
" request[\"sl\"] = sl\n",
" if tp is not None:\n",
" request[\"tp\"] = tp\n",
" if id_position is not None:\n",
" request[\"position\"] = id_position\n",
"\n",
" log_and_print(f\"Sending order request: {request}\")\n",
" result = mt5.order_send(request)\n",
"\n",
" order_type_str = \"BUY\" if is_buy else \"SELL\"\n",
" if result is None or result.retcode != mt5.TRADE_RETCODE_DONE:\n",
" error_message = f\"Order failed for {symbol}\"\n",
" if result:\n",
" error_message += f\", retcode={result.retcode}, comment={result.comment}\"\n",
" additional_info = (\n",
" f\"Date/Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\\n\"\n",
" f\"Order Type: {order_type_str}\\n\"\n",
" f\"Lot Size: {lot}\\n\"\n",
" f\"SL: {sl if sl else 'None'}\\n\"\n",
" f\"TP: {tp if tp else 'None'}\\n\"\n",
" f\"Comment: {COMMENT_ML}\\n\"\n",
" f\"Request: {request}\\n\"\n",
" f\"Result: {result}\"\n",
" )\n",
" # If you want notifications, you could log or handle them differently here.\n",
" log_and_print(f\"Order failed details: {additional_info}\", is_error=True)\n",
" else:\n",
" success_message = f\"Order successful for {symbol}, comment={result.comment}\"\n",
" additional_info = (\n",
" f\"Date/Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\\n\"\n",
" f\"Order Type: {order_type_str}\\n\"\n",
" f\"Lot Size: {lot}\\n\"\n",
" f\"SL: {sl if sl else 'None'}\\n\"\n",
" f\"TP: {tp if tp else 'None'}\\n\"\n",
" f\"Comment: {COMMENT_ML}\"\n",
" )\n",
" # If you want notifications, you could log or handle them differently here.\n",
" log_and_print(success_message)\n",
"\n",
" def get_positions_by_magic(self, symbol, magic_number):\n",
" \"\"\"\n",
" Retrieve positions for a specific symbol and magic number.\n",
" \"\"\"\n",
" all_positions = mt5.positions_get(symbol=symbol)\n",
" if not all_positions:\n",
" log_and_print(\"No positions found.\", is_error=False)\n",
" return []\n",
" return [pos for pos in all_positions if pos.magic == magic_number]\n",
"\n",
" def run_strategy(self, symbol, lot, buy_signal, sell_signal):\n",
" \"\"\"\n",
" Run the trading strategy logic based on buy/sell signals.\n",
" \"\"\"\n",
" log_and_print(\"------------------------------------------------------------------\")\n",
" log_and_print(\n",
" f\"Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}, \"\n",
" f\"SYMBOL: {symbol}, BUY SIGNAL: {buy_signal}, SELL SIGNAL: {sell_signal}\"\n",
" )\n",
"\n",
" positions = self.get_positions_by_magic(symbol, self.magic_number)\n",
" has_buy = any(pos.type == mt5.POSITION_TYPE_BUY for pos in positions)\n",
" has_sell = any(pos.type == mt5.POSITION_TYPE_SELL for pos in positions)\n",
"\n",
" if buy_signal and not has_buy:\n",
" if has_sell:\n",
" log_and_print(\"Existing sell positions found. Attempting to close...\")\n",
" if self.close_position(symbol, is_buy=True):\n",
" log_and_print(\"Sell positions closed. Placing new buy order.\")\n",
" self.orders(symbol, lot, is_buy=True)\n",
" else:\n",
" log_and_print(\"Failed to close sell positions.\")\n",
" else:\n",
" self.orders(symbol, lot, is_buy=True)\n",
" elif sell_signal and not has_sell:\n",
" if has_buy:\n",
" log_and_print(\"Existing buy positions found. Attempting to close...\")\n",
" if self.close_position(symbol, is_buy=False):\n",
" log_and_print(\"Buy positions closed. Placing new sell order.\")\n",
" self.orders(symbol, lot, is_buy=False)\n",
" else:\n",
" log_and_print(\"Failed to close buy positions.\")\n",
" else:\n",
" self.orders(symbol, lot, is_buy=False)\n",
" else:\n",
" log_and_print(\"Appropriate position already exists or no signal to act on.\")\n",
"\n",
" def close_position(self, symbol, is_buy):\n",
" \"\"\"\n",
" Closes positions of the opposite type (BUY/SELL) for this app's magic number.\n",
" \"\"\"\n",
" positions = mt5.positions_get(symbol=symbol)\n",
" if not positions:\n",
" log_and_print(f\"No positions to close for symbol: {symbol}\")\n",
" return False\n",
"\n",
" initial_balance = mt5.account_info().balance\n",
" closed_any = False\n",
"\n",
" for position in positions:\n",
" # Close positions of the opposite type with the same magic number\n",
" if position.magic == self.magic_number and (\n",
" (is_buy and position.type == mt5.POSITION_TYPE_SELL) or\n",
" (not is_buy and position.type == mt5.POSITION_TYPE_BUY)\n",
" ):\n",
" close_request = {\n",
" \"action\": mt5.TRADE_ACTION_DEAL,\n",
" \"symbol\": symbol,\n",
" \"volume\": position.volume,\n",
" \"type\": mt5.ORDER_TYPE_BUY if position.type == mt5.POSITION_TYPE_SELL else mt5.ORDER_TYPE_SELL,\n",
" \"position\": position.ticket,\n",
" \"deviation\": 20,\n",
" \"magic\": self.magic_number,\n",
" \"comment\": COMMENT_ML,\n",
" \"type_time\": mt5.ORDER_TIME_GTC,\n",
" \"type_filling\": mt5.ORDER_FILLING_RETURN,\n",
" }\n",
" result = mt5.order_send(close_request)\n",
" if result.retcode != mt5.TRADE_RETCODE_DONE:\n",
" error_message = f\"Failed to close position {position.ticket} for {symbol}: {result.retcode}\"\n",
" log_and_print(error_message, is_error=True)\n",
" # If you want notifications, you could log or handle them differently here.\n",
" else:\n",
" log_and_print(f\"Successfully closed position {position.ticket} for {symbol}\")\n",
" closed_any = True\n",
"\n",
" if closed_any:\n",
" final_balance = mt5.account_info().balance\n",
" profit = final_balance - initial_balance\n",
" success_message = f\"Closed positions successfully, Profit: {profit}\"\n",
" log_and_print(success_message)\n",
" return True\n",
"\n",
" return False\n",
"\n",
" def check_and_execute_trades(self):\n",
" \"\"\"\n",
" Convenience method to perform the entire flow:\n",
" generate signals, run strategy, and deselect symbol.\n",
" \"\"\"\n",
" mt5.symbol_select(self.symbol, True)\n",
" buy, sell, _, _ = self.ml_signal_generation(self.symbol, N_BARS, TIMEFRAME)\n",
" self.run_strategy(self.symbol, self.lot_size, buy, sell)\n",
" mt5.symbol_select(self.symbol, False)\n",
" log_and_print(\"Waiting for new signals...\")\n",
"\n",
"def is_market_open():\n",
" \"\"\"\n",
" Check if the current time is within the typical Forex trading session, adjusted for CET/CEST.\n",
" Market closes at Friday 10:00 PM CET and opens at Sunday 11:00 PM CET. \n",
" It is closed all day Saturday.\n",
" \"\"\"\n",
" current_time_utc = datetime.utcnow()\n",
" # Adjust for Central European Time (UTC+1) or Central European Summer Time (UTC+2)\n",
" current_time_cet = (\n",
" current_time_utc + timedelta(hours=2) \n",
" if time.localtime().tm_isdst \n",
" else current_time_utc + timedelta(hours=1)\n",
" )\n",
"\n",
" # Friday after 10 PM CET\n",
" if current_time_cet.weekday() == 4 and current_time_cet.hour >= 22:\n",
" return False\n",
" # Sunday before 11 PM CET\n",
" elif current_time_cet.weekday() == 6 and current_time_cet.hour < 23:\n",
" return False\n",
" # All day Saturday\n",
" elif current_time_cet.weekday() == 5:\n",
" return False\n",
" return True\n",
"\n",
"\n",
"if __name__ == \"__main__\":\n",
" try:\n",
" if not mt5.initialize():\n",
" log_and_print(\"Failed to initialize MetaTrader 5\", is_error=True)\n",
" exit()\n",
"\n",
" # 1) Create a TradingApp per symbol\n",
" apps = {}\n",
" for symbol in symbols:\n",
" app = TradingApp(symbol=symbol, lot_size=lot_sizes[symbol], magic_number=MAGIC_NUMBER)\n",
" app.load_pipeline(model_paths[symbol])\n",
" apps[symbol] = app\n",
"\n",
" while True:\n",
" log_and_print(\"Checking market status...\")\n",
" if is_market_open():\n",
" log_and_print(\"Market is open. Executing trades...\")\n",
"\n",
" for symbol, app in apps.items():\n",
" try:\n",
" log_and_print(f\"🔵 Checking Symbol: {symbol}\")\n",
" buy_signal, sell_signal, _, _ = app.ml_signal_generation(\n",
" symbol=app.symbol,\n",
" n_bars=N_BARS,\n",
" timeframe=TIMEFRAME\n",
" )\n",
" app.run_strategy(app.symbol, app.lot_size, buy_signal, sell_signal)\n",
" except Exception as e:\n",
" log_and_print(f\"⚠️ Error processing {symbol}: {e}\", is_error=True)\n",
"\n",
"\n",
" time.sleep(SLEEP_TIME)\n",
"\n",
" except KeyboardInterrupt:\n",
" log_and_print(\"Shutdown signal received.\")\n",
"\n",
" except Exception as e:\n",
" error_message = f\"An error occurred: {e}\"\n",
" log_and_print(error_message, is_error=True)\n",
"\n",
" finally:\n",
" mt5.shutdown()\n",
" log_and_print(\"MetaTrader 5 shutdown completed.\")\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "ml",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.11"
}
},
"nbformat": 4,
"nbformat_minor": 2
}