Skip to content

Commit

Permalink
Merge pull request #576 from ashis2004/h12
Browse files Browse the repository at this point in the history
Stress testing financial portfolio added
  • Loading branch information
Akshat111111 authored Jul 22, 2024
2 parents 8621e58 + 3f63a2d commit 6f9cc4e
Show file tree
Hide file tree
Showing 3 changed files with 650 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "l4r3fazkwMCa",
"outputId": "4bb294cb-24ba-43a6-edcb-c5ff6b7deff4"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Dataset saved to financial_portfolio_data.csv\n"
]
}
],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"import datetime\n",
"\n",
"# Parameters for the synthetic data generation\n",
"num_records = 1000\n",
"start_date = datetime.datetime(2020, 1, 1)\n",
"date_range = pd.date_range(start_date, periods=num_records, freq='H')\n",
"\n",
"# Generate synthetic data\n",
"np.random.seed(42) # For reproducibility\n",
"asset_1_prices = np.cumsum(np.random.randn(num_records)) + 100\n",
"asset_2_prices = np.cumsum(np.random.randn(num_records)) + 150\n",
"asset_3_prices = np.cumsum(np.random.randn(num_records)) + 200\n",
"portfolio_values = asset_1_prices + asset_2_prices + asset_3_prices + np.random.randn(num_records) * 10\n",
"market_index = np.cumsum(np.random.randn(num_records)) + 1000\n",
"\n",
"# Create a DataFrame\n",
"data = {\n",
" 'timestamp': date_range,\n",
" 'Asset_1': asset_1_prices,\n",
" 'Asset_2': asset_2_prices,\n",
" 'Asset_3': asset_3_prices,\n",
" 'Portfolio_Value': portfolio_values,\n",
" 'Market_Index': market_index\n",
"}\n",
"\n",
"df = pd.DataFrame(data)\n",
"\n",
"# Save the DataFrame to a CSV file\n",
"csv_file_path = 'financial_portfolio_data.csv'\n",
"df.to_csv(csv_file_path, index=False)\n",
"print(f\"Dataset saved to {csv_file_path}\")\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "oVNru4wBw89k",
"outputId": "e51296b1-cbb4-4656-f046-bc4e73a7caa4"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
" timestamp Asset_1 Asset_2 Asset_3 Portfolio_Value \\\n",
"0 2020-01-01 00:00:00 100.496714 151.399355 199.324822 432.142816 \n",
"1 2020-01-01 01:00:00 100.358450 152.323989 199.180303 443.258892 \n",
"2 2020-01-01 02:00:00 101.006138 152.383619 198.387883 447.641586 \n",
"3 2020-01-01 03:00:00 102.529168 151.736683 198.079922 471.222649 \n",
"4 2020-01-01 04:00:00 102.295015 152.434906 196.186307 456.481759 \n",
"\n",
" Market_Index \n",
"0 999.136506 \n",
"1 999.105303 \n",
"2 999.123320 \n",
"3 999.595950 \n",
"4 998.229092 \n"
]
}
],
"source": [
"# Load the dataset to preview\n",
"loaded_df = pd.read_csv(csv_file_path)\n",
"print(loaded_df.head())\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"id": "WaIPjci2w-2-"
},
"outputs": [],
"source": [
"import gym\n",
"from gym import spaces\n",
"\n",
"class PortfolioEnv(gym.Env):\n",
" def __init__(self, df):\n",
" super(PortfolioEnv, self).__init__()\n",
" self.df = df\n",
" self.current_step = 0\n",
" self.action_space = spaces.Discrete(3) # Actions: 0 = hold, 1 = buy, 2 = sell\n",
" self.observation_space = spaces.Box(low=-np.inf, high=np.inf, shape=(5,), dtype=np.float32)\n",
" self.balance = 10000\n",
" self.portfolio_value = self.balance\n",
"\n",
" def reset(self):\n",
" self.current_step = 0\n",
" self.balance = 10000\n",
" self.portfolio_value = self.balance\n",
" return self._next_observation()\n",
"\n",
" def _next_observation(self):\n",
" obs = self.df.iloc[self.current_step][['Asset_1', 'Asset_2', 'Asset_3', 'Portfolio_Value', 'Market_Index']].values\n",
" return obs\n",
"\n",
" def step(self, action):\n",
" obs = self._next_observation()\n",
" self.current_step += 1\n",
"\n",
" reward = 0\n",
" if action == 1: # Buy\n",
" self.balance -= obs[3] # Subtract portfolio value\n",
" reward = obs[3] # Reward is the portfolio value\n",
" elif action == 2: # Sell\n",
" self.balance += obs[3] # Add portfolio value\n",
" reward = -obs[3] # Negative reward as penalty for selling\n",
"\n",
" self.portfolio_value = self.balance + obs[3]\n",
" done = self.current_step >= len(self.df) - 1\n",
" return obs, reward, done, {}\n",
"\n",
" def render(self, mode='human'):\n",
" print(f'Step: {self.current_step}, Balance: {self.balance}, Portfolio Value: {self.portfolio_value}')\n",
"\n",
"# Create the environment\n",
"env = PortfolioEnv(loaded_df)\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"id": "An2hCoUJxBNl"
},
"outputs": [],
"source": [
"from collections import deque\n",
"import random\n",
"\n",
"class QLearningAgent:\n",
" def __init__(self, state_size, action_size):\n",
" self.state_size = state_size\n",
" self.action_size = action_size\n",
" self.memory = deque(maxlen=2000)\n",
" self.gamma = 0.95\n",
" self.epsilon = 1.0\n",
" self.epsilon_min = 0.01\n",
" self.epsilon_decay = 0.995\n",
" self.learning_rate = 0.001\n",
" self.q_table = {}\n",
"\n",
" def get_qs(self, state):\n",
" return self.q_table.get(tuple(state.flatten()), np.zeros(self.action_size))\n",
"\n",
" def remember(self, state, action, reward, next_state, done):\n",
" self.memory.append((state, action, reward, next_state, done))\n",
"\n",
" def act(self, state):\n",
" if np.random.rand() <= self.epsilon:\n",
" return random.randrange(self.action_size)\n",
" qs = self.get_qs(state)\n",
" return np.argmax(qs)\n",
"\n",
" def replay(self, batch_size):\n",
" minibatch = random.sample(self.memory, batch_size)\n",
" for state, action, reward, next_state, done in minibatch:\n",
" target = reward\n",
" if not done:\n",
" target = reward + self.gamma * np.amax(self.get_qs(next_state))\n",
" qs = self.get_qs(state)\n",
" qs[action] = target\n",
" self.q_table[tuple(state.flatten())] = qs\n",
" if self.epsilon > self.epsilon_min:\n",
" self.epsilon *= self.epsilon_decay\n",
"\n",
"# Initialize the agent\n",
"state_size = env.observation_space.shape[0]\n",
"action_size = env.action_space.n\n",
"agent = QLearningAgent(state_size, action_size)\n",
"\n",
"# Train the agent\n",
"episodes = 500\n",
"batch_size = 32\n",
"\n",
"for e in range(episodes):\n",
" state = env.reset()\n",
" state = np.reshape(state, [1, state_size])\n",
"\n",
" for time in range(200):\n",
" action = agent.act(state)\n",
" next_state, reward, done, _ = env.step(action)\n",
" next_state = np.reshape(next_state, [1, state_size])\n",
"\n",
" agent.remember(state, action, reward, next_state, done)\n",
" state = next_state\n",
"\n",
" if done:\n",
" print(f\"Episode: {e+1}/{episodes}, Score: {reward}, Epsilon: {agent.epsilon:.2}\")\n",
" break\n",
"\n",
" if len(agent.memory) > batch_size:\n",
" agent.replay(batch_size)\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"id": "OmRsM0J8xGHQ"
},
"outputs": [],
"source": [
"# Evaluate the agent\n",
"state = env.reset()\n",
"state = np.reshape(state, [1, state_size])\n",
"total_reward = 0\n",
"\n",
"for time in range(500):\n",
" action = agent.act(state)\n",
" next_state, reward, done, _ = env.step(action)\n",
" next_state = np.reshape(next_state, [1, state_size])\n",
" total_reward += reward\n",
" state = next_state\n",
"\n",
" if done:\n",
" print(f\"Final Balance: {total_reward}\")\n",
" break\n"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Loading

0 comments on commit 6f9cc4e

Please sign in to comment.