{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Trade with ChatGPT"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "sys.path.append(\"D:\\python_project\\FinRL-Meta\\FinRL-Meta\")  # Your FinRL-Meta dir\n",
    "import pandas as pd\n",
    "from meta.data_processors.akshare import Akshare # https://github.com/AI4Finance-Foundation/FinRL-meta\n",
    "import datetime\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Read data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>CODE</th>\n",
       "      <th>NAME</th>\n",
       "      <th>DATE</th>\n",
       "      <th>CREATED_DATE</th>\n",
       "      <th>text_a</th>\n",
       "      <th>DESCRIPTION</th>\n",
       "      <th>READ</th>\n",
       "      <th>MARKET</th>\n",
       "      <th>CHANGE</th>\n",
       "      <th>FIRST_DAY</th>\n",
       "      <th>...</th>\n",
       "      <th>A0_mask</th>\n",
       "      <th>A1_mask</th>\n",
       "      <th>AV_num</th>\n",
       "      <th>trade_date</th>\n",
       "      <th>open_close_chg</th>\n",
       "      <th>co_label</th>\n",
       "      <th>cc_label</th>\n",
       "      <th>stock_factors</th>\n",
       "      <th>label</th>\n",
       "      <th>chatgpt_res</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>600519</td>\n",
       "      <td>贵州茅台</td>\n",
       "      <td>2021-01-07 18:24:00</td>\n",
       "      <td>2021-01-07 18:23:00</td>\n",
       "      <td>贵州茅台公告，董事会于2021年1月6日收到公司董事王焱的书面辞职报告，王焱因工作变动，申请...</td>\n",
       "      <td>贵州茅台公告，董事会于2021年1月6日收到公司董事王焱的书面辞职报告，王焱因工作变动，申请...</td>\n",
       "      <td>5034011.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.000935</td>\n",
       "      <td>2021-01-07</td>\n",
       "      <td>...</td>\n",
       "      <td>[[0. 0. 0. ... 0. 0. 0.]\\n [0. 0. 0. ... 0. 0....</td>\n",
       "      <td>[[0. 0. 0. ... 0. 0. 0.]\\n [0. 0. 0. ... 0. 0....</td>\n",
       "      <td>3.0</td>\n",
       "      <td>2021-01-07</td>\n",
       "      <td>0.247727</td>\n",
       "      <td>4.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>[39.43367824665831, 39.12671101868472, 39.9102...</td>\n",
       "      <td>1</td>\n",
       "      <td>公司高管变动通常会对公司的经营和股票价格产生一定的影响，但具体影响的程度和方向需要综合考虑多...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>1 rows × 42 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "     CODE  NAME                 DATE         CREATED_DATE  \\\n",
       "0  600519  贵州茅台  2021-01-07 18:24:00  2021-01-07 18:23:00   \n",
       "\n",
       "                                              text_a  \\\n",
       "0  贵州茅台公告，董事会于2021年1月6日收到公司董事王焱的书面辞职报告，王焱因工作变动，申请...   \n",
       "\n",
       "                                         DESCRIPTION       READ  MARKET  \\\n",
       "0  贵州茅台公告，董事会于2021年1月6日收到公司董事王焱的书面辞职报告，王焱因工作变动，申请...  5034011.0     1.0   \n",
       "\n",
       "     CHANGE   FIRST_DAY  ...  \\\n",
       "0  0.000935  2021-01-07  ...   \n",
       "\n",
       "                                             A0_mask  \\\n",
       "0  [[0. 0. 0. ... 0. 0. 0.]\\n [0. 0. 0. ... 0. 0....   \n",
       "\n",
       "                                             A1_mask  AV_num  trade_date  \\\n",
       "0  [[0. 0. 0. ... 0. 0. 0.]\\n [0. 0. 0. ... 0. 0....     3.0  2021-01-07   \n",
       "\n",
       "  open_close_chg  co_label  cc_label  \\\n",
       "0       0.247727       4.0       4.0   \n",
       "\n",
       "                                       stock_factors  label  \\\n",
       "0  [39.43367824665831, 39.12671101868472, 39.9102...      1   \n",
       "\n",
       "                                         chatgpt_res  \n",
       "0  公司高管变动通常会对公司的经营和股票价格产生一定的影响，但具体影响的程度和方向需要综合考虑多...  \n",
       "\n",
       "[1 rows x 42 columns]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv(\"./data/maotai.csv\")\n",
    "df.head(1)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Generate Signal from ChatGPT"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_signal_from_chatgpt(x):\n",
    "    chatgpt_res = x.chatgpt_res\n",
    "    if \"持有不动\" in chatgpt_res:\n",
    "        signal = 0\n",
    "    if \"小幅加仓\" in chatgpt_res:\n",
    "        signal = 1\n",
    "    elif \"小幅减仓\" in chatgpt_res:\n",
    "        signal = -1\n",
    "    if \"大幅加仓\" in chatgpt_res:\n",
    "        signal = 2\n",
    "    elif \"大幅减仓\" in chatgpt_res:\n",
    "        signal = -2\n",
    "    return signal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "df[\"signal\"] = df.apply(generate_signal_from_chatgpt,axis = 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    -1\n",
       "1     0\n",
       "2     1\n",
       "3     0\n",
       "4     0\n",
       "5     0\n",
       "6     1\n",
       "7     0\n",
       "8     0\n",
       "9     0\n",
       "10   -1\n",
       "11    1\n",
       "12   -1\n",
       "13    0\n",
       "14    1\n",
       "Name: signal, dtype: int64"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df[\"signal\"]"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Generate Signal by yourself\n",
    "Here the result of ChatGPT is just a suggestion, you need to make trading signal after considering both news and the result of ChatGPT"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_signal_from_chatgpt_by_yourself(x):\n",
    "    chatgpt_res = x.chatgpt_res\n",
    "    news = x.text_a\n",
    "    signal = input(\n",
    "        f'- {news}\\n - {chatgpt_res}\\n (Please input 1 for buy or 0 for hold or -1 for sell)'\n",
    "        )\n",
    "    return int(signal)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "df[\"signal_by_yourself\"] = df.apply(generate_signal_from_chatgpt_by_yourself,axis = 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    -1\n",
       "1     1\n",
       "2     1\n",
       "3     0\n",
       "4     1\n",
       "5     0\n",
       "6     1\n",
       "7     1\n",
       "8     1\n",
       "9     1\n",
       "10   -1\n",
       "11    1\n",
       "12    1\n",
       "13    0\n",
       "14    1\n",
       "Name: signal_by_yourself, dtype: int64"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df[\"signal_by_yourself\"]"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Fetching price data from FinRL-Meta"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "df.DATE = pd.to_datetime(df.DATE)\n",
    "df.DATE = df.DATE.dt.date.astype(str)\n",
    "max_date = datetime.datetime.strptime(df.DATE.max(),\"%Y-%m-%d\")\n",
    "max_date += datetime.timedelta(days=10)\n",
    "max_date = max_date.strftime(\"%Y-%m-%d\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "time_interval = \"daily\"\n",
    "start_date= df.DATE.min()\n",
    "end_date = max_date\n",
    "adjust=\"\"\n",
    "\n",
    "ticket_list=[f'{df.iloc[0].CODE}.SH', ]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 1/1 [00:00<00:00,  3.00it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Download complete! Dataset saved to ./data/dataset.csv. \n",
      "Shape of DataFrame: (196, 8)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(196, 8)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "as_processor = Akshare(\"akshare\",start_date=start_date,end_date=end_date,time_interval=time_interval)\n",
    "as_processor.download_data(ticket_list)\n",
    "as_processor.dataframe.shape"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Trading\n",
    "Since we only have the news for several days here, we only calculated the dicision results made by Chatgpt or by combining Chatgpt and your own opinion"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>tic</th>\n",
       "      <th>time</th>\n",
       "      <th>open</th>\n",
       "      <th>high</th>\n",
       "      <th>low</th>\n",
       "      <th>close</th>\n",
       "      <th>volume</th>\n",
       "      <th>day</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>600519.SH</td>\n",
       "      <td>2021-01-07</td>\n",
       "      <td>2097.0</td>\n",
       "      <td>2140.0</td>\n",
       "      <td>2075.0</td>\n",
       "      <td>2140.0</td>\n",
       "      <td>37931</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         tic        time    open    high     low   close  volume  day\n",
       "0  600519.SH  2021-01-07  2097.0  2140.0  2075.0  2140.0   37931    3"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "price_df = as_processor.dataframe\n",
    "price_df = price_df.reset_index(drop=True)\n",
    "price_df.head(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "def cal_reward(x,by_yourself = False, hold = False):\n",
    "    # get price\n",
    "    this_date = x.DATE\n",
    "    this_price = price_df[price_df.time == this_date]\n",
    "    \n",
    "    while this_price.shape[0] == 0:\n",
    "        this_date = datetime.datetime.strptime(this_date,\"%Y-%m-%d\")\n",
    "        this_date += datetime.timedelta(days=1)\n",
    "        this_date = this_date.strftime(\"%Y-%m-%d\")\n",
    "        this_price = price_df[price_df.time == this_date]\n",
    "    \n",
    "    next_price = price_df.iloc[this_price.index+1]\n",
    "    this_close = this_price.close.item()\n",
    "    next_open = next_price.open.item()\n",
    "    next_close = next_price.close.item() # T+1\n",
    "    \n",
    "    if hold:\n",
    "        signal = 1\n",
    "    else:\n",
    "        if by_yourself:\n",
    "            signal = x.signal_by_yourself\n",
    "        else:\n",
    "            signal = x.signal\n",
    "\n",
    "    reward = signal * (next_close-this_close)/this_close\n",
    "    return reward\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "df[\"reward\"] = df.apply(lambda x:cal_reward(x),axis = 1)\n",
    "df[\"reward_by_yourself\"] = df.apply(lambda x:cal_reward(x,by_yourself = True),axis = 1)\n",
    "df[\"reward_hold\"] = df.apply(lambda x:cal_reward(x,hold = True),axis = 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "reward_list = (df[\"reward\"] +1 ).cumprod().to_list()\n",
    "reward_hold_list = (df[\"reward_hold\"] +1 ).cumprod().to_list()\n",
    "reward_yourself_list = (df[\"reward_by_yourself\"] +1 ).cumprod().to_list()\n",
    "reward_list = [i/reward_list[0] for i in reward_list]\n",
    "reward_hold_list = [i/reward_hold_list[0] for i in reward_hold_list]\n",
    "reward_yourself_list = [i/reward_yourself_list[0] for i in reward_yourself_list]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 37660 characters]",
      "text/plain": [
       "<Figure size 1440x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "date_list = df.DATE\n",
    "plt.figure(figsize=(20,5))\n",
    "plt.plot(date_list, reward_list, label = \"Reward by ChatGPT\")\n",
    "plt.plot(date_list, reward_yourself_list, label= \"Reward with ChatGPT\")\n",
    "plt.plot(date_list, reward_hold_list, label= \"Buy and hold\")\n",
    "plt.title(\"Maotai ChatGPT Trading Results\")\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "finrl",
   "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.7.12"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "afd6dc03c9be451573fc2885de79a969af6a24a159f11a3ead741ab7a9ff405f"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
