| import pandas as pd |
| import numpy as np |
| from sklearn.preprocessing import MinMaxScaler |
| from tensorflow.keras.models import Sequential |
| from tensorflow.keras.layers import LSTM, Dense, Dropout |
| |
|
|
| def preprocess_data_for_deep_mql(df: pd.DataFrame, look_back: int = 60, features_cols=['Close', 'Volume'], target_col='Close'): |
| """ |
| Prepares data for a deep learning model (e.g., LSTM) for MQL-like tasks. |
| - Scales features. |
| - Creates sequences for time series forecasting. |
| """ |
| df_copy = df.copy() |
| |
| |
| df_copy['returns'] = df_copy['Close'].pct_change() |
| df_copy['ma10'] = df_copy['Close'].rolling(window=10).mean() |
| df_copy['ma30'] = df_copy['Close'].rolling(window=30).mean() |
| df_copy = df_copy.dropna() |
|
|
| all_cols = list(set(features_cols + [target_col] + ['returns', 'ma10', 'ma30'])) |
| data_to_scale = df_copy[all_cols].values |
| |
| scaler = MinMaxScaler(feature_range=(0, 1)) |
| scaled_data = scaler.fit_transform(data_to_scale) |
| |
| |
| try: |
| |
| scaled_df_cols = df_copy[all_cols].columns.tolist() |
| target_idx_in_scaled = scaled_df_cols.index(target_col) |
| except AttributeError: |
| |
| |
| |
| if target_col in features_cols: |
| target_idx_in_scaled = features_cols.index(target_col) |
| elif target_col == 'returns': |
| target_idx_in_scaled = len(features_cols) |
| elif target_col == 'ma10': |
| target_idx_in_scaled = len(features_cols) + 1 |
| elif target_col == 'ma30': |
| target_idx_in_scaled = len(features_cols) + 2 |
| else: |
| print(f"Warning: Target column '{target_col}' not reliably found in scaled data. Defaulting to index 0.") |
| target_idx_in_scaled = 0 |
|
|
|
|
| X, y = [], [] |
| for i in range(look_back, len(scaled_data)): |
| X.append(scaled_data[i-look_back:i]) |
| y.append(scaled_data[i, target_idx_in_scaled]) |
| |
| return np.array(X), np.array(y), scaler, df_copy[all_cols].columns.tolist() |
|
|
| def create_deep_mql_model(input_shape): |
| """ |
| Creates a Deep Learning model (LSTM example) for MQL-like tasks. |
| This is a basic example and can be significantly enhanced. |
| """ |
| model = Sequential([ |
| LSTM(units=50, return_sequences=True, input_shape=input_shape), |
| Dropout(0.2), |
| LSTM(units=50, return_sequences=False), |
| Dropout(0.2), |
| Dense(units=25, activation='relu'), |
| Dense(units=1) |
| ]) |
| model.compile(optimizer='adam', loss='mean_squared_error') |
| return model |
|
|
| def generate_trading_signals(model, data_X, scaler, last_known_price, threshold=0.005): |
| """ |
| Generates trading signals based on model predictions. |
| - Predicts next step. |
| - Compares prediction with current price to generate signal. |
| |
| Signal: 1 (Buy), -1 (Sell), 0 (Hold) |
| """ |
| |
| |
| if data_X.ndim == 2: |
| data_X = np.expand_dims(data_X, axis=0) |
|
|
| predicted_scaled_value = model.predict(data_X) |
| |
| |
| |
| |
| num_features = data_X.shape[2] |
| dummy_array = np.zeros((len(predicted_scaled_value), num_features)) |
| |
| |
| |
| |
| target_column_index_in_scaler = 0 |
| dummy_array[:, target_column_index_in_scaler] = predicted_scaled_value.ravel() |
| |
| try: |
| predicted_value = scaler.inverse_transform(dummy_array)[:, target_column_index_in_scaler] |
| except ValueError as e: |
| print(f"Error during inverse_transform: {e}") |
| print("Ensure dummy_array shape matches scaler's n_features_in_.") |
| print(f"dummy_array shape: {dummy_array.shape}, scaler.n_features_in_: {scaler.n_features_in_}") |
| |
| return 0 |
|
|
|
|
| signal = 0 |
| if predicted_value > last_known_price * (1 + threshold): |
| signal = 1 |
| elif predicted_value < last_known_price * (1 - threshold): |
| signal = -1 |
| return signal, predicted_value[0] |
|
|
|
|
| if __name__ == '__main__': |
| |
| |
| |
| |
| |
| dates_mql = pd.date_range(start='2022-01-01', periods=500, freq='B') |
| data_mql_np = np.random.rand(500, 5) * 150 + 50 |
| raw_data_mql = pd.DataFrame(data_mql_np, index=dates_mql, columns=['Open', 'High', 'Low', 'Close', 'Volume']) |
| raw_data_mql['Close'] = raw_data_mql['Close'] + np.sin(np.linspace(0, 20, 500)) * 20 |
|
|
| if not raw_data_mql.empty: |
| look_back_mql = 60 |
| |
| features_mql = ['Close', 'Volume', 'Open', 'High', 'Low'] |
| target_mql = 'Close' |
|
|
| X_mql, y_mql, scaler_mql, scaled_cols_mql = preprocess_data_for_deep_mql( |
| raw_data_mql, |
| look_back=look_back_mql, |
| features_cols=features_mql, |
| target_col=target_mql |
| ) |
|
|
| if X_mql.shape[0] > 0: |
| print(f"X_mql shape: {X_mql.shape}, y_mql shape: {y_mql.shape}") |
|
|
| |
| model_mql = create_deep_mql_model(input_shape=(X_mql.shape[1], X_mql.shape[2])) |
| print("Training DeepMQL model (example)...") |
| |
| train_size = int(len(X_mql) * 0.8) |
| X_train_mql, y_train_mql = X_mql[:train_size], y_mql[:train_size] |
| |
| |
| if y_train_mql.ndim == 1: |
| y_train_mql = y_train_mql.reshape(-1, 1) |
|
|
| model_mql.fit(X_train_mql, y_train_mql, epochs=10, batch_size=32, verbose=1) |
| print("DeepMQL model trained.") |
|
|
| |
| |
| if len(X_mql) > train_size: |
| last_sequence = X_mql[-1] |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| original_close_series = raw_data_mql['Close'].iloc[len(raw_data_mql) - len(X_mql) + X_mql.shape[1] -1 - (len(X_mql) - (np.where(X_mql == last_sequence)[0][0])) : len(raw_data_mql) - (len(X_mql) - (np.where(X_mql == last_sequence)[0][0]))] |
| |
| |
| |
| |
| |
| |
| |
| last_actual_close_price = raw_data_mql[target_mql].iloc[-1] |
|
|
|
|
| print(f"\nGenerating signal based on last sequence (shape: {last_sequence.shape})...") |
| print(f"Last actual close price for reference: {last_actual_close_price}") |
| |
| signal, predicted_price = generate_trading_signals( |
| model_mql, |
| last_sequence, |
| scaler_mql, |
| last_actual_close_price, |
| threshold=0.001 |
| ) |
| print(f"Predicted Next '{target_mql}': {predicted_price:.2f}") |
| if signal == 1: |
| print("Signal: BUY") |
| elif signal == -1: |
| print("Signal: SELL") |
| else: |
| print("Signal: HOLD") |
| else: |
| print("Not enough data to generate a signal after training split.") |
| else: |
| print("X_mql is empty. Check preprocessing for DeepMQL.") |
| else: |
| print("Raw data for MQL is empty. Check data fetching.") |