{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "4a6ab9a2-28a2-445d-8512-a0dc8d1b54e9",
   "metadata": {},
   "source": [
    "# Trading Decision Simulator\n",
    "\n",
    "## Description\n",
    "This document provides Python functions to simulate trading decisions using a predefined API. The API includes stock tickers, historical prices, and a `Trade` class to represent buy or sell actions. Each function demonstrates a unique trading strategy, such as momentum-based trading, mean reversion, portfolio diversification, and more. These examples can serve as a foundation for developing or testing algorithmic trading systems.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e610bf56-a46e-4aff-8de1-ab49d62b1ad3",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from dotenv import load_dotenv\n",
    "from openai import OpenAI\n",
    "from huggingface_hub import login, InferenceClient\n",
    "from transformers import AutoTokenizer\n",
    "import google.generativeai as google_genai\n",
    "import anthropic\n",
    "import gradio as gr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4f672e1c-87e9-4865-b760-370fa605e614",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Setting up environment\n",
    "load_dotenv()\n",
    "os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY', 'your-key-if-not-using-env')\n",
    "os.environ['ANTHROPIC_API_KEY'] = os.getenv('ANTHROPIC_API_KEY', 'your-key-if-not-using-env')\n",
    "os.environ['GOOGLE_API_KEY'] = os.getenv('GOOGLE_API_KEY', 'your-key-if-not-using-env')\n",
    "os.environ['HF_TOKEN'] = os.getenv('HF_TOKEN', 'your-key-if-not-using-env')\n",
    "os.environ['CODE_QWEN_URL'] = os.getenv('CODE_QWEN_URL', 'your-url-if-not-using-env')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8aa149ed-9298-4d69-8fe2-8f5de0f667da",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Initialize\n",
    "openai = OpenAI()\n",
    "claude = anthropic.Anthropic()\n",
    "google_genai.configure()\n",
    "code_qwen = InferenceClient(CODE_QWEN_URL)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cbb4319c-870f-4c04-99e2-6f54c650537a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Constants \n",
    "MODELS = {\n",
    "    \"GPT\": \"gpt-4o\", \n",
    "    \"Claude\": \"claude-3-5-sonnet-20240620\", \n",
    "    \"Gemini\": \"gemini-1.5-pro\", \n",
    "    \"CodeQwen\": \"Qwen/CodeQwen1.5-7B-Chat\"\n",
    "}\n",
    "\n",
    "MAX_TOKENS = 2000\n",
    "\n",
    "SYSTEM_PROMPT = \"\"\"\n",
    "You are an advanced code generation assistant capable of creating high-quality Python code for financial trading systems. \n",
    "Your task is to generate Python functions that simulate trading decisions based on the following API:\n",
    "\n",
    "API DETAILS:\n",
    "1. tickers: A list of stock tickers (strings) representing available stocks.\n",
    "2. prices: A dictionary where the key is a stock ticker (string) and the value is a list of historical prices (floats). The list is ordered with the most recent price first.\n",
    "3. Trade: A class used to represent trading actions.\n",
    "   - `Trade(ticker, quantity)` creates a trade object:\n",
    "     - Positive `quantity` (e.g., `100`) represents buying shares.\n",
    "     - Negative `quantity` (e.g., `-50`) represents selling/shorting shares.\n",
    "\n",
    "INSTRUCTIONS:\n",
    "- You will be provided with an example Python function to demonstrate the API.\n",
    "- Your job is to generate 5 additional Python functions, each implementing a unique trading strategy.\n",
    "- Ensure the functions are named sequentially (e.g., `trade2()`, `trade3()`, etc.).\n",
    "- Include clear comments explaining the logic behind each function.\n",
    "- Return a list of `Trade` objects from each function.\n",
    "- The output should only include the Python code. Do not include any introductions, conclusions, summaries, or additional context.\n",
    "\n",
    "CONSIDERATIONS FOR TRADING STRATEGIES:\n",
    "- Momentum-based strategies (e.g., trading based on price trends).\n",
    "- Mean reversion strategies (e.g., identifying overbought or oversold stocks).\n",
    "- Randomized strategies (e.g., simulating stochastic decision-making).\n",
    "- Portfolio diversification (e.g., distributing trades across multiple tickers).\n",
    "- Risk management strategies (e.g., limiting losses or locking in profits).\n",
    "\n",
    "EXAMPLE FUNCTION:\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8e7b3546-57aa-4c29-bc5d-f211970d04eb",
   "metadata": {},
   "outputs": [],
   "source": [
    "def user_prompt(example_function):\n",
    "    \"\"\"\n",
    "    Returns a user prompt for the model by appending the provided example function.\n",
    "    \"\"\"\n",
    "    return f\"\"\"\n",
    "{example_function}\n",
    "\n",
    "TASK:\n",
    "Based on the provided example function and API, please write 5 additional trading functions named `trade2()`, `trade3()`, and so on. Each function should implement a unique trading strategy as outlined in the system prompt. Make sure each function has clear comments explaining the logic and returns a list of `Trade` objects.\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "455728fd-be9b-4d7a-88f2-3afcf026303e",
   "metadata": {},
   "source": [
    "# Trade Function Example: `trade1`\n",
    "\n",
    "This Python script demonstrates a simple trading strategy implemented using a provided API. The `trade1` function identifies the top-performing stock over the last 5 days based on its average price and creates a trade object to buy 100 shares of the selected stock. The function leverages the following components:\n",
    "\n",
    "- **`tickers`**: A list of available stock tickers.\n",
    "- **`prices`**: A dictionary containing historical prices for each stock.\n",
    "- **`Trade`**: A class used to represent trading actions (buy or sell).\n",
    "- **`numpy`**: Used to calculate average prices efficiently.\n",
    "\n",
    "The example highlights a momentum-based strategy where the stock with the best recent performance is selected for trading.\n",
    "\n",
    "example:\n",
    "```python\n",
    "# Importing the required modules and classes for the trading simulation\n",
    "\n",
    "# `tickers` is a list of stock tickers (strings), representing available stocks to trade.\n",
    "import tickers\n",
    "\n",
    "# `prices` is a dictionary where:\n",
    "#   - The key is a stock ticker (string).\n",
    "#   - The value is a list of historical prices (floats), ordered with the most recent price first.\n",
    "import prices\n",
    "\n",
    "# `Trade` is a class that represents a trading decision. It takes two arguments:\n",
    "#   - `ticker`: A string representing the stock ticker.\n",
    "#   - `quantity`: An integer representing the number of shares to buy (positive) or sell/short (negative).\n",
    "# Example usage:\n",
    "#   Trade(\"IBM\", 100)  -> Buys 100 shares of IBM stock.\n",
    "#   Trade(\"IBM\", -50)  -> Sells or shorts 50 shares of IBM stock.\n",
    "import Trade\n",
    "\n",
    "# Additional modules for random number generation and numerical operations\n",
    "import random\n",
    "import numpy as np\n",
    "\n",
    "def trade1():\n",
    "    \"\"\"\n",
    "    Buys the top-performing stock based on its average price over the last 5 days.\n",
    "\n",
    "    Strategy:\n",
    "    - Calculate the average price of the last 5 days for each stock in `tickers`.\n",
    "    - Identify the stock with the highest average price.\n",
    "    - Create a trade object to buy 100 shares of the identified stock.\n",
    "    \n",
    "    Returns:\n",
    "        list[Trade]: A list containing a single trade object for the chosen stock.\n",
    "    \"\"\"\n",
    "    # Calculate the 5-day average price for each stock\n",
    "    avg_prices = {ticker: np.mean(prices[ticker][:5]) for ticker in tickers}\n",
    "\n",
    "    # Find the stock ticker with the highest 5-day average price\n",
    "    best_ticker = max(avg_prices, key=avg_prices.get)\n",
    "\n",
    "    # Create a trade object to buy 100 shares of the top-performing stock\n",
    "    trade = Trade(best_ticker, 100)\n",
    "\n",
    "    # Return the trade as a list\n",
    "    return [trade]\n",
    "\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ce0fa282-4e07-4bf8-8b49-7cf7ef4a7572",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A trading function example\n",
    "TRADING_FUNCTION_EXAMPLE = \"\"\"\n",
    "# tickers is a list of stock tickers (strings)\n",
    "import tickers\n",
    "\n",
    "# prices is a dict; the key is a ticker and the value is a list of historic prices, today first\n",
    "import prices\n",
    "\n",
    "# Trade represents a decision to buy or sell a quantity of a ticker\n",
    "# Trade(\"IBM\", 100) for a trade object representing purchasing 100 shares of IBM stock\n",
    "# Trade(\"IBM\", -50) for a trade object representing selling or shorting 50 shares of IBM stock\n",
    "import Trade\n",
    "\n",
    "import random\n",
    "import numpy as np\n",
    "\n",
    "def trade1():\n",
    "    # Buy top performing stock in the last 5 days\n",
    "    avg_prices = {ticker: np.mean(prices[ticker][:5]) for ticker in tickers}\n",
    "    best_ticker = max(avg_prices, key=avg_prices.get)\n",
    "    trade = Trade(best_ticker, 100)\n",
    "    return [trade]\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0be9f47d-5213-4700-b0e2-d444c7c738c0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# UI function to trade using GPT\n",
    "def trade_gpt(function_example):    \n",
    "    stream = openai.chat.completions.create(\n",
    "        model=MODELS[\"GPT\"], \n",
    "        messages=[\n",
    "            {\"role\": \"system\", \"content\": SYSTEM_PROMPT},\n",
    "            {\"role\": \"user\", \"content\": user_prompt(function_example)}\n",
    "        ], \n",
    "        stream=True\n",
    "    )\n",
    "    reply = \"\"\n",
    "    for chunk in stream:\n",
    "        reply += chunk.choices[0].delta.content or \"\"\n",
    "        yield reply.replace(\"```python\\n\", \"\").replace(\"```\", \"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8669f56b-8314-4582-a167-78842caea131",
   "metadata": {},
   "outputs": [],
   "source": [
    "# UI function to trade using Claude\n",
    "def trade_claude(function_example):\n",
    "    result = claude.messages.stream(\n",
    "        model=MODELS[\"Claude\"],\n",
    "        max_tokens=MAX_TOKENS,\n",
    "        system=SYSTEM_PROMPT,\n",
    "        messages=[{\"role\": \"user\", \"content\": user_prompt(function_example)}],\n",
    "    )\n",
    "    reply = \"\"\n",
    "    with result as stream:\n",
    "        for text in stream.text_stream:\n",
    "            reply += text\n",
    "            yield reply.replace(\"```python\\n\", \"\").replace(\"```\", \"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d27456d0-5cd3-4c2c-a12a-176d53142752",
   "metadata": {},
   "outputs": [],
   "source": [
    "# UI function to trade using Gemini\n",
    "def trade_gemini(function_example):\n",
    "    gemini = google_genai.GenerativeModel(\n",
    "        model_name=MODELS[\"Gemini\"],\n",
    "        system_instruction=SYSTEM_PROMPT\n",
    "    )\n",
    "    stream = gemini.generate_content(\n",
    "        contents=user_prompt(function_example),\n",
    "        stream=True\n",
    "    )\n",
    "    reply = \"\"\n",
    "    for chunk in stream:\n",
    "        reply += chunk.text or \"\"\n",
    "        yield reply.replace(\"```python\\n\", \"\").replace(\"```\", \"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0a9fb676-83c3-452e-abeb-8712ebdee1d1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# UI function to trade using CodeQwen\n",
    "def trade_code_qwen(function_example):\n",
    "    tokenizer = AutoTokenizer.from_pretrained(MODELS[\"CodeQwen\"])\n",
    "    model_input = tokenizer.apply_chat_template(\n",
    "        conversation=[\n",
    "            {\"role\": \"system\", \"content\": SYSTEM_PROMPT},\n",
    "            {\"role\": \"user\", \"content\": user_prompt(function_example)}\n",
    "        ],\n",
    "        tokenize=False,\n",
    "        add_generation_prompt=True\n",
    "    )\n",
    "    stream = code_qwen.text_generation(\n",
    "        prompt=model_input,\n",
    "        stream=True,\n",
    "        details=True,\n",
    "        max_new_tokens=MAX_TOKENS\n",
    "    )\n",
    "    reply = \"\"\n",
    "    for chunk in stream:\n",
    "        reply += chunk.token.text or \"\"\n",
    "        yield reply.replace(\"```python\\n\", \"\").replace(\"```\", \"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2f1ae8f5-16c8-40a0-aa18-63b617df078d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# UI function to select model from dropdown \n",
    "def trade(trading_function, model):\n",
    "    if model==\"GPT\":\n",
    "        yield from trade_gpt(trading_function)\n",
    "    elif model==\"Claude\":\n",
    "        yield from trade_claude(trading_function)\n",
    "    elif model==\"Gemini\":\n",
    "        yield from trade_gemini(trading_function)\n",
    "    elif model==\"CodeQwen\":\n",
    "        yield from trade_code_qwen(trading_function)\n",
    "    else:\n",
    "        raise ValueError(\"Unknown Model\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4e6af1cd-f3d9-43f0-91d9-9800d9681a77",
   "metadata": {},
   "outputs": [],
   "source": [
    "# CSS styling for the UI\n",
    "UI_CSS = \"\"\"\n",
    "#title {\n",
    "    text-align: center;\n",
    "    font-size: 2.5em;\n",
    "    font-weight: bold;\n",
    "    margin-bottom: 10px;\n",
    "}\n",
    "\n",
    "#description {\n",
    "    text-align: left;\n",
    "    font-size: 1.2em;\n",
    "    font-weight: bold;\n",
    "    margin-bottom: 20px;\n",
    "    color: #BBB;\n",
    "}\n",
    "\n",
    "#simulate-btn {\n",
    "    height: 3em;\n",
    "    font-size: 2em !important;\n",
    "    padding: 12px 25px !important;\n",
    "    border-radius: 10px !important;\n",
    "    border: none !important;\n",
    "    cursor: pointer;\n",
    "    transition: background-color 0.3s, transform 0.2s; /* Smooth effects */\n",
    "}\n",
    "\n",
    "#simulate-btn:hover {\n",
    "    background-color: #FFC107 !important; /* Bright golden-yellow on hover */\n",
    "    transform: scale(1.05); /* Slight zoom effect */\n",
    "    box-shadow: 0 6px 8px rgba(0, 0, 0, 0.25); /* Enhance shadow on hover */\n",
    "}\n",
    "\n",
    "#simulate-btn:active {\n",
    "    background-color: #B8860B !important; /* Darker goldenrod on click */\n",
    "    transform: scale(0.95); /* Slight press effect */\n",
    "    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* Reduce shadow on click */\n",
    "}\n",
    "\n",
    "#simulate-btn,\n",
    "#trading-decisions {\n",
    "    background-color: #DAA520 !important; /* Goldenrod color same as #simulate-btn */\n",
    "    color: #FFFFFF !important; /* White text for contrast */\n",
    "    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3); /* Subtle shadow for depth */\n",
    "}\n",
    "\n",
    "#trading-decisions {\n",
    "    border: 2px solid #B8860B; /* Darker goldenrod border */\n",
    "}\n",
    "\n",
    "#trading-decisions:focus {\n",
    "    outline: none;\n",
    "    box-shadow: 0 0 8px #FFC107; /* Bright golden-yellow glow on focus */\n",
    "}\n",
    "\n",
    "#example-function, \n",
    "#model-dropdown {\n",
    "    background-color: #007965 !important; /* Darker and sharper teal for better contrast */\n",
    "    color: #FFFFFF !important; /* Pure white for strong visibility */\n",
    "    cursor: pointer;\n",
    "    border: 2px solid #00594D; /* Deep teal border for emphasis */\n",
    "    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.9); /* Strong shadow for depth */\n",
    "}\n",
    "\n",
    "#example-function:focus,\n",
    "#model-dropdown:focus {\n",
    "    outline: none;\n",
    "    box-shadow: 0 0 10px #00A389; /* Vibrant teal glow on focus */\n",
    "}\n",
    "\n",
    "#model-dropdown:hover {\n",
    "    background-color: #005F4A !important; /* Darker teal for hover effect */\n",
    "    box-shadow: 0 6px 10px rgba(0, 0, 0, 0.4); /* Enhanced shadow on hover */\n",
    "    border-color: #00A389; /* Change border color for hover */\n",
    "}\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f733330f-6945-4be4-a2ab-9e68c94f70f0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Gradio UI\n",
    "with gr.Blocks(css=UI_CSS) as ui:\n",
    "    # Title for the application\n",
    "    gr.Markdown(\"<div id='title'>🛠️ Trading Strategy Simulator</div><br>\")\n",
    "    \n",
    "    # Input and output section\n",
    "    with gr.Row():\n",
    "        trading_f = gr.Textbox(\n",
    "            label=\"📄 Trading Function Input\",\n",
    "            placeholder=\"Paste your trading function here...\",\n",
    "            lines=15,\n",
    "            value=TRADING_FUNCTION_EXAMPLE,\n",
    "            elem_id=\"example-function\"\n",
    "        )\n",
    "        decisions = gr.Textbox(\n",
    "            label=\"📊 Generated Trading Decisions\",\n",
    "            placeholder=\"Trading decisions will appear here...\",\n",
    "            lines=20,\n",
    "            interactive=False,\n",
    "            elem_id=\"trading-decisions\"\n",
    "        )\n",
    "    \n",
    "    with gr.Row():\n",
    "        # Dropdown scaled to take 1 part of the row\n",
    "        model = gr.Dropdown(\n",
    "            choices=MODELS,\n",
    "            label=\"🤖 Select AI Model\",\n",
    "            value=\"GPT\",\n",
    "            scale=1,\n",
    "            elem_id=\"model-dropdown\"\n",
    "        )\n",
    "        # Markdown for the description scaled to 2 parts of the row\n",
    "        with gr.Column(scale=2):\n",
    "            gr.Markdown(\n",
    "                \"\"\"\n",
    "                <div id='description'>\n",
    "                This interface allows you to test and simulate trading strategies using a predefined example function.\n",
    "                Simply input a trading function, select your preferred AI model, and see the generated trading decisions in action.<br>\n",
    "                Experiment with different strategies to refine your approach and analyze outcomes effectively.\n",
    "                </div>\n",
    "                \"\"\"\n",
    "            )\n",
    "        # Button scaled to take 1 part of the row\n",
    "        trade_btn = gr.Button(\n",
    "            \"💼 Simulate Trading\",\n",
    "            elem_id=\"simulate-btn\",\n",
    "            scale=1\n",
    "        )\n",
    "\n",
    "    # Action button behavior\n",
    "    trade_btn.click(\n",
    "        fn=trade, \n",
    "        inputs=[trading_f, model], \n",
    "        outputs=[decisions]\n",
    "    )\n",
    "\n",
    "# Launch the UI in a browser\n",
    "ui.launch(inbrowser=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9d0ad093-425b-488e-8c3f-67f729dd9c06",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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": 5
}