{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "5c6d4e7b-966e-4878-96ec-5b72a4017ec2",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pickle"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "4a95451b-61c3-4b90-9462-d9319907f04c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def is_bearish_candle(candle):\n",
    "    start, end, high, low = candle\n",
    "    return (end < start) \n",
    "\n",
    "def is_bullish_candle(candle):\n",
    "    start, end, high, low = candle\n",
    "    return (end > start)\n",
    "\n",
    "def is_doji(candle):\n",
    "    start, end, high, low = candle\n",
    "    diff = abs(end - start)\n",
    "    return (10 * diff < (high - low)) and (abs(high - max(end, start)) > 10 * diff or abs(low - min(end, start)) > 10 * diff)\n",
    "\n",
    "def is_long_legged_doji(candle):\n",
    "    return is_doji(candle)  # long legged doji is characterized primarily by its long shadows\n",
    "\n",
    "def is_dragonfly_doji(candle):\n",
    "    start, end, high, low = candle\n",
    "    return is_doji(candle) and (high - max(end, start)) < (3 * abs(end - start))\n",
    "\n",
    "def is_gravestone_doji(candle):\n",
    "    start, end, high, low = candle\n",
    "    return is_doji(candle) and (min(end, start) - low) < (3 * abs(end - start))\n",
    "\n",
    "def is_hammer(candle):\n",
    "    start, end, high, low = candle\n",
    "    diff = abs(end - start)\n",
    "    return (high - max(end, start)) < (3 * diff) and (low - min(end, start)) > (3 * diff)\n",
    "\n",
    "def is_inverted_hammer(candle):\n",
    "    start, end, high, low = candle\n",
    "    diff = abs(end - start)\n",
    "    return (low - min(end, start)) < (3 * diff) and (high - max(end, start)) > (3 * diff)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "87072ced-4d41-40be-a56c-bbdff6b58278",
   "metadata": {},
   "outputs": [],
   "source": [
    "def did_candle_go_up(sequence):\n",
    "    # Return True if the last day's candle went up, False otherwise\n",
    "    return sequence[2][1] > sequence[1][1]\n",
    "\n",
    "def analyze_patterns(sequences):\n",
    "    results = {}\n",
    "    up_counts = {}  # Stores the number of times the last day's candle went up for each pattern\n",
    "    total_counts = {}  # Stores the total number of occurrences of each pattern\n",
    "    \n",
    "    for seq in sequences:\n",
    "        if len(seq) != 3:\n",
    "            continue\n",
    "\n",
    "        pattern_name = None\n",
    "\n",
    "        # Bearish Candle -> 3 different classes of dogi\n",
    "        if is_bearish_candle(seq[0]):\n",
    "            if is_long_legged_doji(seq[1]):\n",
    "                pattern_name = 'Bearish -> Long-legged Doji'\n",
    "\n",
    "                print(seq)\n",
    "            \n",
    "            elif is_dragonfly_doji(seq[1]):\n",
    "                pattern_name = 'Bearish -> Dragonfly Doji'\n",
    "            elif is_gravestone_doji(seq[1]):\n",
    "                pattern_name = 'Bearish -> Gravestone Doji'\n",
    "            \n",
    "            # Hammer\n",
    "            if is_hammer(seq[1]):\n",
    "                pattern_name = 'Bearish -> Hammer'\n",
    "            elif is_inverted_hammer(seq[1]):\n",
    "                pattern_name = 'Bearish -> Inverted Hammer'\n",
    "        \n",
    "        # Bullish Candle -> 3 different classes of dogi\n",
    "        elif is_bullish_candle(seq[0]):\n",
    "            if is_long_legged_doji(seq[1]):\n",
    "                pattern_name = 'Bullish -> Long-legged Doji'\n",
    "            elif is_dragonfly_doji(seq[1]):\n",
    "                pattern_name = 'Bullish -> Dragonfly Doji'\n",
    "            elif is_gravestone_doji(seq[1]):\n",
    "                pattern_name = 'Bullish -> Gravestone Doji'\n",
    "            \n",
    "            # Hammer\n",
    "            if is_hammer(seq[1]):\n",
    "                pattern_name = 'Bullish -> Hammer'\n",
    "            elif is_inverted_hammer(seq[1]):\n",
    "                pattern_name = 'Bullish -> Inverted Hammer'\n",
    "\n",
    "        # Update the counts based on whether the last day's candle went up\n",
    "        if pattern_name:\n",
    "            total_counts[pattern_name] = total_counts.get(pattern_name, 0) + 1\n",
    "            if did_candle_go_up(seq):\n",
    "                up_counts[pattern_name] = up_counts.get(pattern_name, 0) + 1\n",
    "    \n",
    "    # Calculate percentage of times the last day's candle went up for each pattern\n",
    "    for pattern, count in up_counts.items():\n",
    "        results[pattern] = count / total_counts[pattern]\n",
    "\n",
    "    return results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "064054eb-525f-453b-8e7c-914e6e75dc7f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load all_sequences from the pickle file\n",
    "with open('data_3candles.pkl', 'rb') as f:\n",
    "    all_sequences = pickle.load(f)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "08b3786d-7520-4943-b876-33d050840e9c",
   "metadata": {},
   "outputs": [],
   "source": [
    "results = analyze_patterns(all_sequences)\n",
    "for pattern, percent_up in results.items():\n",
    "    print(f\"{pattern}: {percent_up * 100:.2f}% went up\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0b137bcb-d259-4e46-a8b1-4bc4008358bb",
   "metadata": {},
   "source": [
    "# Optimization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "5b2c3995-ae3e-40a4-bf6f-4b57d0bcefcd",
   "metadata": {},
   "outputs": [],
   "source": [
    "from bayes_opt import BayesianOptimization\n",
    "\n",
    "def is_bearish_candle(candle):\n",
    "    start, end, high, low = candle\n",
    "    return (end < start) \n",
    "\n",
    "def is_bullish_candle(candle):\n",
    "    start, end, high, low = candle\n",
    "    return (end > start)\n",
    "\n",
    "def is_doji(candle, doji_diff_multiplier):\n",
    "    start, end, high, low = candle\n",
    "    diff = abs(end - start)\n",
    "    return (doji_diff_multiplier * diff < (high - low)) and \\\n",
    "           (abs(high - max(end, start)) > doji_diff_multiplier * diff or \\\n",
    "            abs(low - min(end, start)) > doji_diff_multiplier * diff)\n",
    "\n",
    "def is_long_legged_doji(candle, doji_diff_multiplier):\n",
    "    return is_doji(candle, doji_diff_multiplier)\n",
    "\n",
    "def is_dragonfly_doji(candle, doji_diff_multiplier, doji_abs_diff_multiplier):\n",
    "    start, end, high, low = candle\n",
    "    return is_doji(candle, doji_diff_multiplier) and \\\n",
    "           (high - max(end, start)) < (doji_abs_diff_multiplier * abs(end - start))\n",
    "\n",
    "def is_gravestone_doji(candle, doji_diff_multiplier, doji_abs_diff_multiplier):\n",
    "    start, end, high, low = candle\n",
    "    return is_doji(candle, doji_diff_multiplier) and \\\n",
    "           (min(end, start) - low) < (doji_abs_diff_multiplier * abs(end - start))\n",
    "\n",
    "def is_hammer(candle, hammer_abs_diff_multiplier):\n",
    "    start, end, high, low = candle\n",
    "    diff = abs(end - start)\n",
    "    return (high - max(end, start)) < (hammer_abs_diff_multiplier * diff) and \\\n",
    "           (low - min(end, start)) > (hammer_abs_diff_multiplier * diff)\n",
    "\n",
    "def is_inverted_hammer(candle, hammer_abs_diff_multiplier):\n",
    "    start, end, high, low = candle\n",
    "    diff = abs(end - start)\n",
    "    return (low - min(end, start)) < (hammer_abs_diff_multiplier * diff) and \\\n",
    "           (high - max(end, start)) > (hammer_abs_diff_multiplier * diff)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "e154ce6d-6a7b-4996-be19-7c73e26dace7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load sequences from the pickle file\n",
    "with open('data_3candles.pkl', 'rb') as f:\n",
    "    candles = pickle.load(f)\n",
    "\n",
    "def objective(doji_multiplier, hammer_abs_diff_multiplier):\n",
    "    # Counting the times when the patterns indicate a reversal\n",
    "    flipped_signals = 0\n",
    "    \n",
    "    for seq in candles:\n",
    "        # The sequence length should be 3 for the given logic\n",
    "        if len(seq) != 3:\n",
    "            continue\n",
    "\n",
    "        # Bearish Candle followed by a potential bullish reversal pattern and then a bullish candle\n",
    "        if is_bearish_candle(seq[0]):\n",
    "            if (is_long_legged_doji(seq[1], doji_multiplier) or \n",
    "                # is_dragonfly_doji(seq[1], doji_multiplier, doji_abs_diff_multiplier) or \n",
    "                # is_gravestone_doji(seq[1], doji_multiplier, doji_abs_diff_multiplier) or \n",
    "                is_hammer(seq[1], hammer_abs_diff_multiplier) or \n",
    "                is_inverted_hammer(seq[1], hammer_abs_diff_multiplier)) and is_bullish_candle(seq[2]):\n",
    "                flipped_signals += 1\n",
    "\n",
    "        # Bullish Candle followed by a potential bearish reversal pattern and then a bearish candle\n",
    "        elif is_bullish_candle(seq[0]):\n",
    "            if (is_long_legged_doji(seq[1], doji_multiplier) or \n",
    "                # is_dragonfly_doji(seq[1], doji_multiplier, doji_abs_diff_multiplier) or \n",
    "                # is_gravestone_doji(seq[1], doji_multiplier, doji_abs_diff_multiplier) or \n",
    "                is_hammer(seq[1], hammer_abs_diff_multiplier) or \n",
    "                is_inverted_hammer(seq[1], hammer_abs_diff_multiplier)) and is_bearish_candle(seq[2]):\n",
    "                flipped_signals += 1\n",
    "\n",
    "    return -flipped_signals\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "ed99df64-ea3a-45ce-9aac-c356f6f8019a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "|   iter    |  target   | doji_m... | hammer... |\n",
      "-------------------------------------------------\n",
      "| \u001b[0m1        \u001b[0m | \u001b[0m-2.038e+0\u001b[0m | \u001b[0m12.78    \u001b[0m | \u001b[0m6.291    \u001b[0m |\n",
      "| \u001b[0m2        \u001b[0m | \u001b[0m-2.272e+0\u001b[0m | \u001b[0m13.64    \u001b[0m | \u001b[0m5.269    \u001b[0m |\n",
      "| \u001b[0m3        \u001b[0m | \u001b[0m-2.212e+0\u001b[0m | \u001b[0m10.78    \u001b[0m | \u001b[0m5.875    \u001b[0m |\n",
      "| \u001b[95m4        \u001b[0m | \u001b[95m-1.889e+0\u001b[0m | \u001b[95m11.0     \u001b[0m | \u001b[95m7.351    \u001b[0m |\n",
      "| \u001b[0m5        \u001b[0m | \u001b[0m-3.842e+0\u001b[0m | \u001b[0m4.146    \u001b[0m | \u001b[0m3.543    \u001b[0m |\n",
      "| \u001b[95m6        \u001b[0m | \u001b[95m-1.615e+0\u001b[0m | \u001b[95m20.0     \u001b[0m | \u001b[95m8.0      \u001b[0m |\n",
      "| \u001b[0m7        \u001b[0m | \u001b[0m-4.68e+04\u001b[0m | \u001b[0m20.0     \u001b[0m | \u001b[0m2.0      \u001b[0m |\n",
      "| \u001b[0m8        \u001b[0m | \u001b[0m-1.66e+04\u001b[0m | \u001b[0m16.51    \u001b[0m | \u001b[0m8.0      \u001b[0m |\n",
      "| \u001b[0m9        \u001b[0m | \u001b[0m-2.346e+0\u001b[0m | \u001b[0m6.801    \u001b[0m | \u001b[0m8.0      \u001b[0m |\n",
      "| \u001b[0m10       \u001b[0m | \u001b[0m-1.706e+0\u001b[0m | \u001b[0m14.07    \u001b[0m | \u001b[0m8.0      \u001b[0m |\n",
      "| \u001b[0m11       \u001b[0m | \u001b[0m-1.63e+04\u001b[0m | \u001b[0m18.53    \u001b[0m | \u001b[0m8.0      \u001b[0m |\n",
      "| \u001b[0m12       \u001b[0m | \u001b[0m-1.622e+0\u001b[0m | \u001b[0m19.39    \u001b[0m | \u001b[0m8.0      \u001b[0m |\n",
      "=================================================\n",
      "{'target': -16152.0, 'params': {'doji_multiplier': 20.0, 'hammer_abs_diff_multiplier': 8.0}}\n"
     ]
    }
   ],
   "source": [
    "pbounds = {\n",
    "    'doji_multiplier': (4, 20),\n",
    "    'hammer_abs_diff_multiplier': (2, 8)\n",
    "}\n",
    "\n",
    "optimizer = BayesianOptimization(\n",
    "    f=objective,\n",
    "    pbounds=pbounds,\n",
    "    random_state=0,\n",
    "    allow_duplicate_points=True\n",
    ")\n",
    "\n",
    "optimizer.maximize(\n",
    "    init_points=4,\n",
    "    n_iter=8,\n",
    ")\n",
    "print(optimizer.max)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "176ab515-9e73-4fc7-87d8-424249d15a03",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "11670486-4834-4f1e-9f7d-8b3271cbd377",
   "metadata": {},
   "outputs": [],
   "source": [
    "def is_bearish_candle(candle):\n",
    "    start, end, high, low = candle\n",
    "    return (end < start) \n",
    "\n",
    "def is_bullish_candle(candle):\n",
    "    start, end, high, low = candle\n",
    "    return (end > start)\n",
    "\n",
    "def is_doji(candle):\n",
    "    start, end, high, low = candle\n",
    "    diff = abs(end - start)\n",
    "    return (11 * diff < (high - low)) and (abs(high - max(end, start)) > 11 * diff or abs(low - min(end, start)) > 10 * diff)\n",
    "\n",
    "def is_long_legged_doji(candle):\n",
    "    return is_doji(candle)  # long legged doji is characterized primarily by its long shadows\n",
    "\n",
    "def is_dragonfly_doji(candle):\n",
    "    start, end, high, low = candle\n",
    "    return is_doji(candle) and (high - max(end, start)) < (2 * abs(end - start))\n",
    "\n",
    "def is_gravestone_doji(candle):\n",
    "    start, end, high, low = candle\n",
    "    return is_doji(candle) and (min(end, start) - low) < (2 * abs(end - start))\n",
    "\n",
    "def is_hammer(candle):\n",
    "    start, end, high, low = candle\n",
    "    diff = abs(end - start)\n",
    "    return (high - max(end, start)) < (4 * diff) and (low - min(end, start)) > (4 * diff)\n",
    "\n",
    "def is_inverted_hammer(candle):\n",
    "    start, end, high, low = candle\n",
    "    diff = abs(end - start)\n",
    "    return (low - min(end, start)) < (4 * diff) and (high - max(end, start)) > (4 * diff)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "e6a12a27-a021-4b08-b150-bc7c4250b4f5",
   "metadata": {},
   "outputs": [],
   "source": [
    "def did_candle_go_up(sequence):\n",
    "    # Return True if the last day's candle went up, False otherwise\n",
    "    return sequence[2][1] > sequence[2][0]\n",
    "\n",
    "def analyze_patterns(sequences):\n",
    "    results = {}\n",
    "    up_counts = {}  # Stores the number of times the last day's candle went up for each pattern\n",
    "    total_counts = {}  # Stores the total number of occurrences of each pattern\n",
    "    \n",
    "    for seq in sequences:\n",
    "        if len(seq) != 3:\n",
    "            continue\n",
    "\n",
    "        pattern_name = None\n",
    "\n",
    "        # Bearish Candle -> 3 different classes of dogi\n",
    "        if is_bearish_candle(seq[0]):\n",
    "            if is_long_legged_doji(seq[1]):\n",
    "                pattern_name = 'Bearish -> Long-legged Doji'\n",
    "            # elif is_dragonfly_doji(seq[1]):\n",
    "            #     pattern_name = 'Bearish -> Dragonfly Doji'\n",
    "            # elif is_gravestone_doji(seq[1]):\n",
    "            #     pattern_name = 'Bearish -> Gravestone Doji'\n",
    "            \n",
    "            # Hammer\n",
    "            if is_hammer(seq[1]):\n",
    "                pattern_name = 'Bearish -> Hammer'\n",
    "            elif is_inverted_hammer(seq[1]):\n",
    "                pattern_name = 'Bearish -> Inverted Hammer'\n",
    "        \n",
    "        # Bullish Candle -> 3 different classes of dogi\n",
    "        elif is_bullish_candle(seq[0]):\n",
    "            if is_long_legged_doji(seq[1]):\n",
    "                pattern_name = 'Bullish -> Long-legged Doji'\n",
    "            # elif is_dragonfly_doji(seq[1]):\n",
    "            #     pattern_name = 'Bullish -> Dragonfly Doji'\n",
    "            # elif is_gravestone_doji(seq[1]):\n",
    "            #     pattern_name = 'Bullish -> Gravestone Doji'\n",
    "            \n",
    "            # Hammer\n",
    "            if is_hammer(seq[1]):\n",
    "                pattern_name = 'Bullish -> Hammer'\n",
    "            elif is_inverted_hammer(seq[1]):\n",
    "                pattern_name = 'Bullish -> Inverted Hammer'\n",
    "\n",
    "        # Update the counts based on whether the last day's candle went up\n",
    "        if pattern_name:\n",
    "            total_counts[pattern_name] = total_counts.get(pattern_name, 0) + 1\n",
    "            if did_candle_go_up(seq):\n",
    "                up_counts[pattern_name] = up_counts.get(pattern_name, 0) + 1\n",
    "    \n",
    "    # Calculate percentage of times the last day's candle went up for each pattern\n",
    "    for pattern, count in up_counts.items():\n",
    "        results[pattern] = count / total_counts[pattern]\n",
    "\n",
    "    return results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "1af94e61-5083-4e19-b97a-88f575f4252a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Bullish -> Inverted Hammer: 47.40% went up\n",
      "Bearish -> Inverted Hammer: 46.62% went up\n",
      "Bearish -> Long-legged Doji: 46.01% went up\n",
      "Bullish -> Long-legged Doji: 47.24% went up\n"
     ]
    }
   ],
   "source": [
    "results = analyze_patterns(all_sequences)\n",
    "for pattern, percent_up in results.items():\n",
    "    print(f\"{pattern}: {percent_up * 100:.2f}% went up\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b3e481f6-4fdc-4b5a-8245-cf71166c8f6b",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "prac",
   "language": "python",
   "name": "prac"
  },
  "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.9.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
