Created
October 11, 2024 15:07
-
-
Save Klaudioz/2e35fa7d288bc34028189a46bb92c890 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import pandas as pd | |
| import numpy as np | |
| from sqlalchemy import create_engine | |
| from gym import spaces | |
| from stable_baselines3 import PPO | |
| from finrl.apps import apps | |
| from finrl.meta.env_stock_trading.env_stocktrading import StockTradingEnv | |
| from finrl.meta.preprocessor.preprocessors import FeatureEngineer | |
| # Connect to PostgreSQL database | |
| engine = create_engine('postgresql://username:password@localhost:5432/your_database') | |
| # Fetch OHLCV (Open, High, Low, Close, Volume) data for MEME pair | |
| query = """ | |
| SELECT datetime, open, high, low, close, volume | |
| FROM ohlcv_table | |
| WHERE symbol = 'MEME' -- Replace with your desired symbol | |
| ORDER BY datetime | |
| """ | |
| df = pd.read_sql(query, engine) | |
| # Calculate Volume Weighted Average Price (VWAP) | |
| # VWAP is a trading benchmark that gives the average price a security has traded at throughout the day, based on both volume and price | |
| df['vwap'] = (df['close'] * df['volume']).cumsum() / df['volume'].cumsum() | |
| # Perform feature engineering on the dataset | |
| fe = FeatureEngineer( | |
| use_technical_indicator=True, | |
| tech_indicator_list=['vwap', 'volume'] | |
| ) | |
| processed = fe.preprocess_data(df) | |
| # Define a custom environment for VWAP-based trading with a trailing stop | |
| class VWAPTrailingStopEnv(StockTradingEnv): | |
| def __init__(self, df, initial_amount=100000, trading_cost_pct=0.001, trailing_stop_pct=0.02): | |
| super().__init__(df, initial_amount=initial_amount, trading_cost_pct=trading_cost_pct) | |
| self.trailing_stop_pct = trailing_stop_pct # Percentage for trailing stop loss | |
| self.highest_price = 0 # Tracks the highest price seen for trailing stop | |
| def step(self, action): | |
| # Check if we've reached the end of the dataset | |
| self._done = self.day >= len(self.df.index.unique()) - 1 | |
| if self._done: | |
| return self._get_observation(), self.reward, self._done, {} | |
| self.current_price = self.df.loc[self.day, "close"].values[0] | |
| # VWAP entry logic: Buy if price is above VWAP and we're not in a position | |
| vwap = self.df.loc[self.day, "vwap"].values[0] | |
| if self.current_price > vwap and self.state[0] == 0: | |
| action = 1 # Buy | |
| # Trailing stop loss logic: Sell if price drops below the trailing stop level | |
| if self.state[0] > 0: # If we're in a long position | |
| self.highest_price = max(self.highest_price, self.current_price) | |
| if self.current_price <= self.highest_price * (1 - self.trailing_stop_pct): | |
| action = 2 # Sell | |
| # Execute the action and move to the next day | |
| self._take_action(action) | |
| self.day += 1 | |
| self.reward = self._get_reward() | |
| return self._get_observation(), self.reward, self._done, {} | |
| # Set up the trading environment | |
| env = VWAPTrailingStopEnv(processed) | |
| # Train the agent using Proximal Policy Optimization (PPO) algorithm | |
| model = PPO("MlpPolicy", env, verbose=1) | |
| model.learn(total_timesteps=10000) | |
| # Backtest the trained model | |
| df_account_value, df_actions = apps.test_one_episode(model, env) | |
| # Calculate returns and Sharpe ratio | |
| returns = (df_account_value['account_value'].pct_change().dropna()) | |
| sharpe_ratio = np.sqrt(252) * returns.mean() / returns.std() # Annualized Sharpe ratio | |
| # Print the results | |
| print(f"Final account value: ${df_account_value['account_value'].iloc[-1]:.2f}") | |
| print(f"Sharpe ratio: {sharpe_ratio:.2f}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment