├── current_status.json ├── data_structure_temp.json ├── data_creation 2.ipynb └── data_creation.ipynb /current_status.json: -------------------------------------------------------------------------------- 1 | { 2 | "total completed index": 1110690, 3 | "completed index": 28390, 4 | "total pattern identified": 1429, 5 | "total double top": 815, 6 | "total head and shoulders": 614, 7 | "total time spent": 113643.70297217369 8 | } -------------------------------------------------------------------------------- /data_structure_temp.json: -------------------------------------------------------------------------------- 1 | { 2 | "x_data":[1,2,3,4,4,4], 3 | 4 | "raw_data":[1,2,3,4,5,6,7], 5 | 6 | "pattern_type":"DT or H&S", 7 | 8 | "pattern_featuers":[1,2,3,4,5], 9 | 10 | "y_data":[0,0,0,0,1,1,1,1,0,0,0,0], 11 | 12 | "start_index":938, 13 | 14 | "end_index":333 15 | } -------------------------------------------------------------------------------- /data_creation 2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import os\n", 10 | "import time\n", 11 | "import json\n", 12 | "import numpy as np\n", 13 | "import pandas as pd\n", 14 | "import threading\n", 15 | "\n", 16 | "from scipy.interpolate import interp1d\n", 17 | "from scipy import signal\n", 18 | "\n", 19 | "import matplotlib.pyplot as plt\n", 20 | "import matplotlib\n", 21 | "from matplotlib.figure import Figure\n", 22 | "from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg\n", 23 | "\n", 24 | "from mpl_finance import candlestick_ohlc\n", 25 | "import mpl_finance as mplf\n", 26 | "\n", 27 | "import tkinter as tk\n", 28 | "from tkinter import *\n", 29 | "from tkinter import ttk\n", 30 | "\n", 31 | "import tensorflow as tf\n", 32 | "\n" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "file_names = os.listdir(\"D:\\\\market_train\\\\dataset\\\\nifty 1m\")\n", 42 | "\n", 43 | "\n", 44 | "file_name = \"ASIANPAINT_with_indicators_.csv\"\n", 45 | "csv_data = pd.read_csv(\"D:\\\\market_train\\\\dataset\\\\data creation\\\\\"+file_name)\n", 46 | "csv_data['date'] = pd.to_datetime(csv_data['date'])\n" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": null, 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "def normalize(data, window_limit):\n", 56 | " data = np.array(data,dtype=np.float32)\n", 57 | "\n", 58 | " max_value = max(data[0:window_limit])\n", 59 | " min_value = min(data[0:window_limit])\n", 60 | " if min_value != max_value:\n", 61 | " normalized_data = (data - min_value) / (max_value - min_value)\n", 62 | "\n", 63 | " min_value = min(normalized_data[0:window_limit])\n", 64 | " max_value = max(normalized_data[0:window_limit])\n", 65 | "\n", 66 | " normalized_data = (normalized_data - min_value) / (max_value - min_value)\n", 67 | "\n", 68 | " return normalized_data,True\n", 69 | " else:\n", 70 | " return False,False\n", 71 | " \n", 72 | "def low_pass_filter(data):\n", 73 | "\n", 74 | " sampling_frequency = 1.0 \n", 75 | " nyquist_frequency = 0.5 * sampling_frequency\n", 76 | " cutoff_frequency = 0.4\n", 77 | " order = int(len(data)/6)+1\n", 78 | " #print(order)\n", 79 | " try:\n", 80 | " b, a = signal.butter(order, cutoff_frequency, btype='low')\n", 81 | " filtered_data = signal.filtfilt(b, a, data)\n", 82 | " except:\n", 83 | " return False,False\n", 84 | " return filtered_data,True\n", 85 | "\n", 86 | "def interpolate_sequence(data, target_size):\n", 87 | " \n", 88 | "\n", 89 | " x = np.arange(len(data))\n", 90 | " f = interp1d(x, data, kind='cubic')\n", 91 | " new_x = np.linspace(0, len(data) - 1, target_size)\n", 92 | " interpolated_data = f(new_x)\n", 93 | " \n", 94 | " return interpolated_data.tolist()\n", 95 | "\n", 96 | "def invert_sequence(data):\n", 97 | " data = np.array(data)\n", 98 | " max_value = max(data)\n", 99 | " inverted_data = [max_value - x for x in data]+max_value\n", 100 | " return inverted_data - 1\n", 101 | "\n" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "metadata": {}, 108 | "outputs": [], 109 | "source": [ 110 | "class Tree:\n", 111 | " def __init__(self, start, end):\n", 112 | " self.start = start\n", 113 | " self.end = end\n", 114 | " self.left = None\n", 115 | " self.right = None\n", 116 | "\n", 117 | "\n", 118 | "class Write_to_csv:\n", 119 | " \n", 120 | " def __init__(self) -> None:\n", 121 | " global counter\n", 122 | " self.current_pattern = None\n", 123 | " self.start_index = None\n", 124 | " self.shoulder1_index = None\n", 125 | " self.shoulder2_index = None\n", 126 | " self.neckline_index = None\n", 127 | " self.neckline1_index = None\n", 128 | " self.neckline2_index = None\n", 129 | " self.head_index = None\n", 130 | " self.top1_index = None\n", 131 | " self.top2_index = None\n", 132 | " self.target_index = None\n", 133 | " self.price_counter = 0\n", 134 | " self.changes = None\n", 135 | " self.save_data_thread = threading.Thread(target=self.save_data_to_csv)\n", 136 | " self.save_data_thread.start()\n", 137 | " self.start_time = time.time()\n", 138 | " self.current_state = {}\n", 139 | " with open('current_status.json','r') as json_status_file:\n", 140 | " self.current_state = json.load(json_status_file)\n", 141 | " counter = self.current_state['completed index']\n", 142 | " self.previous_counter = counter\n", 143 | "\n", 144 | " process_graph.update_plot(0)\n", 145 | " Label_changes.show_counter()\n", 146 | "\n", 147 | "\n", 148 | "\n", 149 | "\n", 150 | " def save_data_to_csv(self):\n", 151 | " while True:\n", 152 | " time.sleep(60)\n", 153 | " self.current_state['completed index'] = counter\n", 154 | " self.current_state['total time spent'] += time.time() - self.start_time\n", 155 | " self.current_state['total completed index'] += counter - self.previous_counter\n", 156 | " self.start_time = time.time()\n", 157 | " self.previous_counter = counter\n", 158 | "\n", 159 | "\n", 160 | " with open('current_status.json','w') as json_status_file:\n", 161 | " json.dump(self.current_state,json_status_file)\n", 162 | "\n", 163 | " if self.changes != None:\n", 164 | " csv_data.to_csv('D:\\\\market_train\\\\dataset\\\\data creation\\\\'+file_name, index=False )\n", 165 | " print(\"saved changes\")\n", 166 | " self.changes = None\n", 167 | " else:\n", 168 | " print(\"no changes saved\")\n", 169 | " \n", 170 | "\n", 171 | " def write_double_top_to_csv(self,value1,value2,value3,value4,value5):\n", 172 | " if self.current_pattern == \"DOUBLE TOP\":\n", 173 | " self.changes = 1\n", 174 | " self.start_index = value1 + counter\n", 175 | " self.top1_index = value2 + counter\n", 176 | " self.neckline_index = value3 + counter\n", 177 | " self.top2_index = value4 + counter\n", 178 | " self.target_index = value5 + counter\n", 179 | "\n", 180 | "\n", 181 | " for index in range(self.start_index,self.target_index+1,1):\n", 182 | " csv_data.at[index,'patternName_doubletop'] = 'DT'\n", 183 | "\n", 184 | " csv_data.at[self.start_index,'patternFeatures_doubletop'] = 'START'\n", 185 | " csv_data.at[self.top1_index,'patternFeatures_doubletop'] = 'TOP 1'\n", 186 | " csv_data.at[self.neckline_index,'patternFeatures_doubletop'] = 'NECKLINE'\n", 187 | " csv_data.at[self.top2_index,'patternFeatures_doubletop'] = 'TOP 2'\n", 188 | " csv_data.at[self.target_index,'patternFeatures_doubletop'] = 'TARGET'\n", 189 | "\n", 190 | " self.current_state['total pattern identified'] += 1\n", 191 | " self.current_state['total double top'] += 1\n", 192 | "\n", 193 | " #csv_data.to_csv('D:\\\\market_train\\\\dataset\\\\temp_data_creation_updated.csv')\n", 194 | "\n", 195 | "\n", 196 | " print(self.start_index,\n", 197 | " self.top1_index,\n", 198 | " self.neckline_index,\n", 199 | " self.top2_index,\n", 200 | " self.target_index,\n", 201 | " self.current_pattern)\n", 202 | " \n", 203 | " def write_head_and_shoulders_to_csv(self,value1,value2,value3,value4,value5,value6,value7):\n", 204 | " if self.current_pattern == \"HEAD AND SHOULDERS\":\n", 205 | " self.changes = 1\n", 206 | " self.start_index = value1 + counter\n", 207 | " self.shoulder1_index = value2 + counter\n", 208 | " self.neckline1_index = value3 + counter\n", 209 | " self.head_index = value4 + counter\n", 210 | " self.neckline2_index = value5 + counter\n", 211 | " self.shoulder2_index = value6 + counter\n", 212 | " self.target_index = value7 + counter\n", 213 | "\n", 214 | "\n", 215 | " for index in range(self.start_index,self.target_index+1,1):\n", 216 | " csv_data.at[index,'patternName_headandshoulders'] = 'H&S'\n", 217 | "\n", 218 | " csv_data.at[self.start_index,'patternFeatures_headandshoulders'] = 'START'\n", 219 | " csv_data.at[self.shoulder1_index,'patternFeatures_headandshoulders'] = 'SHOULDER 1'\n", 220 | " csv_data.at[self.neckline1_index,'patternFeatures_headandshoulders'] = 'NECKLINE 1'\n", 221 | " csv_data.at[self.head_index,'patternFeatures_headandshoulders'] = 'HEAD'\n", 222 | " csv_data.at[self.neckline2_index,'patternFeatures_headandshoulders'] = 'NECKLINE 2'\n", 223 | " csv_data.at[self.shoulder2_index,'patternFeatures_headandshoulders'] = 'SHOULDER 2'\n", 224 | " csv_data.at[self.target_index,'patternFeatures_headandshoulders'] = 'TARGET'\n", 225 | " \n", 226 | " self.current_state['total pattern identified'] += 1\n", 227 | " self.current_state['total head and shoulders'] += 1\n", 228 | "\n", 229 | " #csv_data.to_csv('D:\\\\market_train\\\\dataset\\\\temp_data_creation_updated.csv')\n", 230 | "\n", 231 | "\n", 232 | "\n", 233 | "\n", 234 | " print(self.start_index,\n", 235 | " self.shoulder1_index,\n", 236 | " self.neckline1_index,\n", 237 | " self.head_index,\n", 238 | " self.neckline2_index,\n", 239 | " self.shoulder2_index,\n", 240 | " self.target_index,\n", 241 | " self.current_pattern)\n", 242 | "\n", 243 | "\n", 244 | "class process_graph:\n", 245 | "\n", 246 | " def __init__(self) -> None:\n", 247 | " self.start_price = None\n", 248 | " self.shoulder1_price = None\n", 249 | " self.shoulder2_price = None\n", 250 | " self.neckline_price = None\n", 251 | " self.neckline1_price = None\n", 252 | " self.neckline2_price = None\n", 253 | " self.head_price = None\n", 254 | " self.top1_price = None\n", 255 | " self.top2_price = None\n", 256 | " self.target_price = None\n", 257 | " self.price_counter = 0\n", 258 | "\n", 259 | " def update_plot(self, counter_increment, prediction = np.ones(100), start_pred = 0, end_pred = 100):\n", 260 | " global counter\n", 261 | " counter += counter_increment\n", 262 | " stock_prices = csv_data[counter:counter+400]\n", 263 | "\n", 264 | " ax.clear() \n", 265 | "\n", 266 | " bar_bottom = min(stock_prices['open'])\n", 267 | " price_difference = max(stock_prices['open']) - min(stock_prices['open'])\n", 268 | " prediction = prediction * price_difference \n", 269 | " prediction = prediction - prediction * 0.8\n", 270 | " ax.bar(range(start_pred,end_pred),prediction,bottom=min(stock_prices['open']))\n", 271 | " mplf.candlestick2_ohlc(ax, stock_prices['open'], stock_prices['high'], stock_prices['low'], stock_prices['close'],\n", 272 | " width=0.7, colorup='g', colordown='r')\n", 273 | " canvas.draw()\n", 274 | "\n", 275 | " def reset(self):\n", 276 | " self.start_price = None\n", 277 | " self.shoulder1_price = None\n", 278 | " self.shoulder2_price = None\n", 279 | " self.neckline_price = None\n", 280 | " self.neckline1_price = None\n", 281 | " self.neckline2_price = None\n", 282 | " self.head_price = None\n", 283 | " self.top1_price = None\n", 284 | " self.top2_price = None\n", 285 | " self.target_price = None\n", 286 | " self.price_counter = 0\n", 287 | "\n", 288 | " def on_button_press(self,pattern):\n", 289 | " Write_to_csv.current_pattern = pattern\n", 290 | " if pattern == 'DOUBLE TOP':\n", 291 | " Label_changes.change_label_double_top(0)\n", 292 | " elif pattern == 'HEAD AND SHOULDERS':\n", 293 | " Label_changes.change_label_head_and_shoulder(0)\n", 294 | " \n", 295 | "\n", 296 | "\n", 297 | " def on_key(self,event):\n", 298 | " if event.key == 'right':\n", 299 | " self.update_plot(40)\n", 300 | " Label_changes.show_counter()\n", 301 | " if event.key == 'left':\n", 302 | " self.update_plot(-20)\n", 303 | " Label_changes.show_counter()\n", 304 | "\n", 305 | " if event.key == 'shift':\n", 306 | " pred, start, stop = DT_model.get_prediction()\n", 307 | " self.update_plot(0, pred, start, stop)\n", 308 | " Label_changes.show_counter()\n", 309 | "\n", 310 | "\n", 311 | " def on_click(self,event):\n", 312 | " x = event.x\n", 313 | " y = event.y\n", 314 | "\n", 315 | " price_value = (x/4) - 25 \n", 316 | " price_value = int(price_value) \n", 317 | " \n", 318 | " Label_changes.show_price(price_value)\n", 319 | "\n", 320 | " if Write_to_csv.current_pattern == 'DOUBLE TOP':\n", 321 | " self.update_double_top_prices(price_value)\n", 322 | " Label_changes.change_label_double_top(self.price_counter)\n", 323 | " elif Write_to_csv.current_pattern == 'HEAD AND SHOULDERS':\n", 324 | " self.update_head_and_shoulder_prices(price_value)\n", 325 | " Label_changes.change_label_head_and_shoulder(self.price_counter)\n", 326 | " \n", 327 | "\n", 328 | "\n", 329 | " \n", 330 | " def update_double_top_prices(self,price):\n", 331 | "\n", 332 | " self.price_counter += 1\n", 333 | "\n", 334 | " match self.price_counter:\n", 335 | " case 1:\n", 336 | " self.start_price = price\n", 337 | " case 2:\n", 338 | " self.top1_price = price\n", 339 | " case 3:\n", 340 | " self.neckline_price = price\n", 341 | " case 4:\n", 342 | " self.top2_price = price\n", 343 | " case 5:\n", 344 | " self.target_price = price\n", 345 | "\n", 346 | " if self.price_counter == 5:\n", 347 | " Write_to_csv.write_double_top_to_csv(self.start_price,\n", 348 | " self.top1_price,\n", 349 | " self.neckline_price,\n", 350 | " self.top2_price,\n", 351 | " self.target_price)\n", 352 | " self.reset()\n", 353 | " Label_changes.reset()\n", 354 | "\n", 355 | " #print(self.start_price,self.top1_price,self.neckline_price,self.top2_price,self.target_price,self.price_counter)\n", 356 | "\n", 357 | " def update_head_and_shoulder_prices(self,price):\n", 358 | "\n", 359 | " self.price_counter += 1\n", 360 | "\n", 361 | " match self.price_counter: \n", 362 | " case 1:\n", 363 | " self.start_price = price\n", 364 | " case 2:\n", 365 | " self.shoulder1_price = price\n", 366 | " case 3:\n", 367 | " self.neckline1_price = price\n", 368 | " case 4:\n", 369 | " self.head_price = price\n", 370 | " case 5:\n", 371 | " self.neckline2_price = price\n", 372 | " case 6:\n", 373 | " self.shoulder2_price = price\n", 374 | " case 7:\n", 375 | " self.target_price = price\n", 376 | "\n", 377 | " if self.price_counter == 7:\n", 378 | " Write_to_csv.write_head_and_shoulders_to_csv(self.start_price,\n", 379 | " self.shoulder1_price,\n", 380 | " self.neckline1_price,\n", 381 | " self.head_price,\n", 382 | " self.neckline2_price,\n", 383 | " self.shoulder2_price,\n", 384 | " self.target_price)\n", 385 | " self.reset()\n", 386 | " Label_changes.reset()\n", 387 | " #print(self.start_price, self.shoulder1_price,self.neckline1_price,self.head_price,self.neckline2_price,self.shoulder2_price,self.target_price,self.price_counter)\n", 388 | "\n", 389 | "\n", 390 | " \n", 391 | "\n", 392 | "\n", 393 | "class Label_changes:\n", 394 | " def __init__(self) -> None:\n", 395 | "\n", 396 | "\n", 397 | " self.price_frame = tk.Frame(app)\n", 398 | " self.price_frame.grid(row=1,column=1,padx=10,pady=10)\n", 399 | "\n", 400 | " self.price_value_label = ttk.Label(self.price_frame,text=0)\n", 401 | " self.price_value_label.grid(row=0,column=0,padx=10,pady=10)\n", 402 | "\n", 403 | " self.current_counter_label = ttk.Label(self.price_frame,text=0)\n", 404 | " self.current_counter_label.grid(row=1,column=0,padx=10,pady=10)\n", 405 | "\n", 406 | " self.clicked_prices_status_frame = tk.Frame(app)\n", 407 | " self.clicked_prices_status_frame.grid(row=1,column=0,padx=10,pady=10)\n", 408 | "\n", 409 | "\n", 410 | "\n", 411 | " self.start = ttk.Label(self.clicked_prices_status_frame,text='START',background='red',foreground='white')\n", 412 | " self.top1 = ttk.Label(self.clicked_prices_status_frame,text='TOP 1',background='red',foreground='white')\n", 413 | " self.neckline = ttk.Label(self.clicked_prices_status_frame,text='NECKLINE',background='red',foreground='white')\n", 414 | " self.top2 = ttk.Label(self.clicked_prices_status_frame,text='TOP 2',background='red',foreground='white')\n", 415 | " self.shoulder1 = ttk.Label(self.clicked_prices_status_frame,text='SHOULDER 1',background='red',foreground='white')\n", 416 | " self.neckline1 = ttk.Label(self.clicked_prices_status_frame,text='NECKLINE 1',background='red',foreground='white')\n", 417 | " self.head = ttk.Label(self.clicked_prices_status_frame,text='HEAD',background='red',foreground='white')\n", 418 | " self.neckline2 = ttk.Label(self.clicked_prices_status_frame,text='NECKLINE 2',background='red',foreground='white')\n", 419 | " self.shoulder2 = ttk.Label(self.clicked_prices_status_frame,text='SHOULDER 2',background='red',foreground='white')\n", 420 | " self.target = ttk.Label(self.clicked_prices_status_frame,text='TARGET',background='red',foreground='white')\n", 421 | "\n", 422 | "\n", 423 | "\n", 424 | "\n", 425 | "\n", 426 | "\n", 427 | "\n", 428 | " def reset(self):\n", 429 | " self.price_counter = 0\n", 430 | "\n", 431 | " try:\n", 432 | " self.start.config(background='red')\n", 433 | " self.start.grid_forget()\n", 434 | " except:pass\n", 435 | " try:\n", 436 | " self.shoulder1.config(background='red')\n", 437 | " self.shoulder1.grid_forget() \n", 438 | " except:pass\n", 439 | " try:\n", 440 | " self.shoulder2.config(background='red')\n", 441 | " self.shoulder2.grid_forget() \n", 442 | " except:pass\n", 443 | " try:\n", 444 | " self.neckline.config(background='red')\n", 445 | " self.neckline.grid_forget()\n", 446 | " except:pass\n", 447 | " try:\n", 448 | " self.neckline1.config(background='red')\n", 449 | " self.neckline1.grid_forget()\n", 450 | " except:pass\n", 451 | " try:\n", 452 | " self.neckline2.config(background='red')\n", 453 | " self.neckline2.grid_forget()\n", 454 | " except:pass\n", 455 | " try:\n", 456 | " self.head.config(background='red')\n", 457 | " self.head.grid_forget()\n", 458 | " except:pass\n", 459 | " try:\n", 460 | " self.top1.config(background='red')\n", 461 | " self.top1.grid_forget()\n", 462 | " except:pass\n", 463 | " try:\n", 464 | " self.top2.config(background='red')\n", 465 | " self.top2.grid_forget()\n", 466 | " except:pass\n", 467 | " try:\n", 468 | " self.target.config(background='red')\n", 469 | " self.target.grid_forget()\n", 470 | " except:pass\n", 471 | "\n", 472 | "\n", 473 | "\n", 474 | " def change_label_double_top(self,value):\n", 475 | " \n", 476 | " if value == 0:\n", 477 | " self.reset()\n", 478 | " process_graph.reset()\n", 479 | " \n", 480 | " self.start.grid(row=0,column=0,padx=10,pady=10)\n", 481 | " self.top1.grid(row=0,column=1,padx=10,pady=10)\n", 482 | " self.neckline.grid(row=0,column=2,padx=10,pady=10)\n", 483 | " self.top2.grid(row=0,column=3,padx=10,pady=10)\n", 484 | " self.target.grid(row=0,column=4,padx=10,pady=10)\n", 485 | " \n", 486 | "\n", 487 | " match value:\n", 488 | " case 1:\n", 489 | " self.start.config(background='green')\n", 490 | " case 2:\n", 491 | " self.top1.config(background='green')\n", 492 | " case 3:\n", 493 | " self.neckline.config(background='green')\n", 494 | " case 4:\n", 495 | " self.top2.config(background='green')\n", 496 | " case 5:\n", 497 | " self.target.config(background='green')\n", 498 | "\n", 499 | " def change_label_head_and_shoulder(self,value):\n", 500 | "\n", 501 | " if value == 0:\n", 502 | " self.reset()\n", 503 | " process_graph.reset()\n", 504 | "\n", 505 | " self.start.grid(row=0,column=0,padx=10,pady=10)\n", 506 | " self.shoulder1.grid(row=0,column=1,padx=10,pady=10)\n", 507 | " self.neckline1.grid(row=0,column=2,padx=10,pady=10)\n", 508 | " self.head.grid(row=0,column=3,padx=10,pady=10)\n", 509 | " self.neckline2.grid(row=0,column=4,padx=10,pady=10)\n", 510 | " self.shoulder2.grid(row=0,column=5,padx=10,pady=10)\n", 511 | " self.target.grid(row=0,column=6,padx=10,pady=10)\n", 512 | " \n", 513 | "\n", 514 | " match value:\n", 515 | " case 1:\n", 516 | " self.start.config(background='green')\n", 517 | " case 2:\n", 518 | " self.shoulder1.config(background='green')\n", 519 | " case 3:\n", 520 | " self.neckline1.config(background='green')\n", 521 | " case 4:\n", 522 | " self.head.config(background='green')\n", 523 | " case 5:\n", 524 | " self.neckline2.config(background='green')\n", 525 | " case 6:\n", 526 | " self.shoulder2.config(background='green')\n", 527 | " case 7:\n", 528 | " self.target.config(background='green')\n", 529 | "\n", 530 | "\n", 531 | " def show_price(self,price_value):\n", 532 | " \n", 533 | " self.price_value_label.config(text=price_value,font=('Helvetica bold', 20))\n", 534 | " \n", 535 | " def show_counter(self):\n", 536 | " self.current_counter_label.config(text=counter,font=('Helvetica bold', 20))\n", 537 | "\n", 538 | "\n", 539 | "class DT_model:\n", 540 | " def __init__(self) -> None:\n", 541 | " self.find_pattern_status = False\n", 542 | " self.stock_prices = None\n", 543 | " self.prediction = None\n", 544 | "\n", 545 | "\n", 546 | " def split_and_predict(self, node):\n", 547 | "\n", 548 | " if node is not None and node.end - node.start > 100 and self.find_pattern_status == False:\n", 549 | "\n", 550 | "\n", 551 | " left_value = node.end - ((node.end - node.start) / 2)\n", 552 | " node.left = Tree(node.start, left_value)\n", 553 | " self.split_and_predict(node.left)\n", 554 | "\n", 555 | " right_value = node.start + ((node.end - node.start) / 2)\n", 556 | " node.right = Tree(right_value, node.end)\n", 557 | " self.split_and_predict(node.right)\n", 558 | "\n", 559 | " self.find_pattern_status, self.prediction = self.find_pattern(counter + node.start, counter + node.end)\n", 560 | "\n", 561 | " return self.prediction, node.start, node.end\n", 562 | " \n", 563 | "\n", 564 | " else:\n", 565 | " return None \n", 566 | "\n", 567 | " def find_pattern(self, start, end):\n", 568 | " global model\n", 569 | " stock_prices = np.array(csv_data['close'][int(start):int(end)])\n", 570 | " stock_prices,_ = normalize(stock_prices,len(stock_prices))\n", 571 | " stock_prices = interpolate_sequence(stock_prices, 100)\n", 572 | " stock_prices = np.array(stock_prices)\n", 573 | " stock_prices = stock_prices.reshape(1,100)\n", 574 | "\n", 575 | " output = model.predict(stock_prices)\n", 576 | " #print(output)\n", 577 | " evaluation,_,_ = self.evaluate_prediction(output.reshape(100))\n", 578 | " if evaluation:\n", 579 | " output = interpolate_sequence(output.reshape(100), int(end - start))\n", 580 | " return True,np.array(output)\n", 581 | " else:\n", 582 | " return False,None\n", 583 | " \n", 584 | "\n", 585 | "\n", 586 | " def evaluate_prediction(self,output, min_threshold = 0.5, min_no_of_max = 8):\n", 587 | " \n", 588 | " no_of_maxes = 0\n", 589 | " output_pass = 0\n", 590 | " start = 0\n", 591 | " end = 0\n", 592 | " for index,value in enumerate(output):\n", 593 | "\n", 594 | " if no_of_maxes >= min_no_of_max:\n", 595 | " output_pass = 1\n", 596 | " if value >= 0.9:\n", 597 | " no_of_maxes += 1\n", 598 | " else:\n", 599 | " if no_of_maxes < min_no_of_max:\n", 600 | " no_of_maxes = 0\n", 601 | " elif no_of_maxes >= min_no_of_max:\n", 602 | " end = index \n", 603 | " start = index - no_of_maxes \n", 604 | " break\n", 605 | "\n", 606 | " return output_pass,start,end\n", 607 | "\n", 608 | "\n", 609 | " def get_prediction(self):\n", 610 | " global counter\n", 611 | " counter += 50\n", 612 | " while counter < len(csv_data):\n", 613 | " self.find_pattern_status = False\n", 614 | " self.prediction = None\n", 615 | " node = Tree(0,400)\n", 616 | " output, start, end = self.split_and_predict(node)\n", 617 | "\n", 618 | " if self.find_pattern_status:\n", 619 | " print(\"output passed\")\n", 620 | " return output, start, end\n", 621 | " else:\n", 622 | " counter+=100\n", 623 | " print(\"Can't find pattern, trying again!\")\n", 624 | " print(\"-------------file done--------------\")\n", 625 | "\n", 626 | "\n", 627 | "\n", 628 | "\n", 629 | "model = tf.keras.models.load_model(\"D:\\\\market_train\\\\models\\\\double_top.h5\")\n", 630 | "\n", 631 | "\n", 632 | "counter = 0\n", 633 | "start_time = time.time()\n", 634 | "\n", 635 | "app = tk.Tk()\n", 636 | "app.title(\"plot\")\n", 637 | "\n", 638 | "\n", 639 | "\n", 640 | "fig = Figure(figsize=(18, 8), dpi=100)\n", 641 | "fig.subplots_adjust(left=0.01, right=0.99, top=0.95, bottom=0.05) \n", 642 | "ax = fig.add_subplot(111)\n", 643 | "\n", 644 | "canvas = FigureCanvasTkAgg(fig, master=app)\n", 645 | "canvas_widget = canvas.get_tk_widget()\n", 646 | "canvas_widget.grid(row=0,column=0,padx=10,pady=10)\n", 647 | "\n", 648 | "bottons_frame = tk.Frame(app)\n", 649 | "bottons_frame.grid(row=0,column=1,padx=10,pady=10)\n", 650 | "\n", 651 | "Double_top_button = tk.Button(bottons_frame, text=\"Double top\", command=lambda: process_graph.on_button_press('DOUBLE TOP'),height=20,width=10)\n", 652 | "Double_top_button.grid(row=0,column=1,padx=10,pady=10)\n", 653 | "\n", 654 | "Head_and_shoulders_button = tk.Button(bottons_frame, text=\"Head and shoulders\", command=lambda: process_graph.on_button_press('HEAD AND SHOULDERS'),height=20,width=10)\n", 655 | "Head_and_shoulders_button.grid(row=1, column=1, padx=10, pady=10, sticky=\"w\")\n", 656 | "\n", 657 | "#process_graph.update_plot(0)\n", 658 | "\n", 659 | "Label_changes = Label_changes()\n", 660 | "process_graph = process_graph()\n", 661 | "Write_to_csv = Write_to_csv()\n", 662 | "DT_model = DT_model()\n", 663 | "\n", 664 | "\n", 665 | "canvas.mpl_connect('key_press_event',process_graph.on_key)\n", 666 | "canvas_widget.bind(\"\", process_graph.on_click)\n", 667 | "\n", 668 | "app.mainloop()" 669 | ] 670 | }, 671 | { 672 | "cell_type": "code", 673 | "execution_count": null, 674 | "metadata": {}, 675 | "outputs": [], 676 | "source": [ 677 | "x_data = []\n", 678 | "y_data = []\n", 679 | "\n", 680 | "counter = 0\n", 681 | "close = csv_data['open']\n", 682 | "\n", 683 | "while True:\n", 684 | " if csv_data['patternName_doubletop'][counter] == 'DT':\n", 685 | " x_temp = []\n", 686 | " print(csv_data['patternName_doubletop'][counter])\n", 687 | " for i in range(counter,len(close)):\n", 688 | " if csv_data['patternName_doubletop'][i] == 'DT':\n", 689 | " x_temp.append(close[i])\n", 690 | " else:\n", 691 | " counter = i\n", 692 | " break\n", 693 | " x_data.append(x_temp)\n", 694 | " counter += 1\n", 695 | " if counter >= len(close):\n", 696 | " break\n", 697 | " \n", 698 | "\n" 699 | ] 700 | }, 701 | { 702 | "cell_type": "code", 703 | "execution_count": null, 704 | "metadata": {}, 705 | "outputs": [], 706 | "source": [ 707 | "class Tree:\n", 708 | " def __init__(self, start, end):\n", 709 | " self.start = start\n", 710 | " self.end = end\n", 711 | " self.left = None\n", 712 | " self.right = None\n", 713 | "\n", 714 | "def traverse(node):\n", 715 | "\n", 716 | " if node is not None and node.end - node.start >= 100:\n", 717 | "\n", 718 | "\n", 719 | " left_value = node.end - ((node.end - node.start) / 2)\n", 720 | " node.left = Tree(node.start, left_value)\n", 721 | " traverse(node.left)\n", 722 | "\n", 723 | " right_value = node.start + ((node.end - node.start) / 2)\n", 724 | " node.right = Tree(right_value, node.end)\n", 725 | " traverse(node.right)\n", 726 | " \n", 727 | " print(node.start,node.end)\n", 728 | "\n", 729 | " else:\n", 730 | " return None\n", 731 | "\n", 732 | "node = Tree(0,400)\n", 733 | "traverse(node)" 734 | ] 735 | }, 736 | { 737 | "cell_type": "code", 738 | "execution_count": null, 739 | "metadata": {}, 740 | "outputs": [], 741 | "source": [ 742 | "class Tree:\n", 743 | " def __init__(self, start, end):\n", 744 | " self.start = start\n", 745 | " self.end = end\n", 746 | " self.left = None\n", 747 | " self.right = None\n", 748 | "\n", 749 | "\n", 750 | "def traverse(node):\n", 751 | "\n", 752 | " if node is not None and node.end - node.start > 100:\n", 753 | "\n", 754 | "\n", 755 | " left_value = node.end - ((node.end - node.start) / 2)\n", 756 | " node.left = Tree(node.start, left_value)\n", 757 | " traverse(node.left)\n", 758 | "\n", 759 | " right_value = node.start + ((node.end - node.start) / 2)\n", 760 | " node.right = Tree(right_value, node.end)\n", 761 | " traverse(node.right)\n", 762 | " \n", 763 | " else:\n", 764 | " return None\n", 765 | "\n", 766 | "\n", 767 | "\n", 768 | "node = Tree(0,800)\n", 769 | "\n", 770 | "traverse(node)\n", 771 | "\n", 772 | "def postorder_traversal(node):\n", 773 | " if node is not None:\n", 774 | " postorder_traversal(node.left)\n", 775 | "\n", 776 | " # Traverse the right subtree\n", 777 | " postorder_traversal(node.right)\n", 778 | "\n", 779 | " # Visit the current node (print its value)\n", 780 | " print(\"node\",node.start, node.end)\n", 781 | " \n", 782 | " #if node.start == 400:\n", 783 | " # return None\n", 784 | " \n", 785 | "postorder_traversal(node)" 786 | ] 787 | }, 788 | { 789 | "cell_type": "code", 790 | "execution_count": 1, 791 | "metadata": {}, 792 | "outputs": [ 793 | { 794 | "name": "stdout", 795 | "output_type": "stream", 796 | "text": [ 797 | "None\n", 798 | "65930\n", 799 | "None\n", 800 | "65930\n", 801 | "None\n", 802 | "65930\n", 803 | "None\n", 804 | "65930\n", 805 | "None\n", 806 | "65930\n", 807 | "None\n", 808 | "65930\n", 809 | "None\n", 810 | "65930\n", 811 | "None\n", 812 | "65930\n", 813 | "NiceHash Miner v3.1.0.9\n", 814 | "198764\n", 815 | "minimised 1\n", 816 | "198764\n", 817 | "minimised 2\n", 818 | "NiceHash Miner v3.1.0.9\n", 819 | "minimised third\n", 820 | "NiceHash Miner v3.1.0.9\n", 821 | "minimised third\n", 822 | "None\n", 823 | "None\n", 824 | "65930\n", 825 | "None\n", 826 | "65930\n", 827 | "NiceHash Miner v3.1.0.9\n", 828 | "721532\n", 829 | "minimised 1\n", 830 | "721532\n", 831 | "minimised 2\n", 832 | "minimised third\n", 833 | "NiceHash Miner v3.1.0.9\n", 834 | "minimised third\n" 835 | ] 836 | } 837 | ], 838 | "source": [ 839 | "import win32gui\n", 840 | "import win32con\n", 841 | "import time\n", 842 | "import subprocess\n", 843 | "\n", 844 | "def get_open_windows():\n", 845 | " windows = []\n", 846 | " win32gui.EnumWindows(enum_windows_callback, windows)\n", 847 | "\n", 848 | " for window_name in windows:\n", 849 | " if \"NiceHash Miner v\" in window_name:\n", 850 | " return window_name\n", 851 | "\n", 852 | "\n", 853 | "def enum_windows_callback(hwnd, windows):\n", 854 | " window_title = win32gui.GetWindowText(hwnd)\n", 855 | " if window_title:\n", 856 | " windows.append(window_title)\n", 857 | "\n", 858 | "\n", 859 | "def minimise_window():\n", 860 | "\n", 861 | " while True:\n", 862 | " window_name = get_open_windows()\n", 863 | " print(window_name)\n", 864 | " hwnd = win32gui.FindWindow(None, window_name)\n", 865 | " print(hwnd)\n", 866 | " if hwnd != 0 and window_name != None:\n", 867 | " time.sleep(0.1)\n", 868 | " win32gui.ShowWindow(hwnd, win32con.SW_FORCEMINIMIZE)\n", 869 | " print(\"minimised 1\")\n", 870 | " break\n", 871 | " else:\n", 872 | " time.sleep(1)\n", 873 | "\n", 874 | " while True:\n", 875 | " hwnd = win32gui.FindWindow(None, window_name)\n", 876 | " print(hwnd)\n", 877 | " if hwnd != 0:\n", 878 | " time.sleep(1)\n", 879 | " win32gui.ShowWindow(hwnd, win32con.SW_FORCEMINIMIZE)\n", 880 | " print(\"minimised 2\")\n", 881 | " break\n", 882 | " else:\n", 883 | " time.sleep(1)\n", 884 | "\n", 885 | "\n", 886 | "def open_nicehash():\n", 887 | "\n", 888 | " path_student = \"C:\\\\Users\\\\aids\\\\AppData\\\\Local\\\\Programs\\\\NiceHash Miner\\\\NiceHashMiner.exe\"\n", 889 | " path_aids = \"C:\\\\Users\\\\lenovo\\\\AppData\\\\Local\\\\Programs\\\\NiceHash Miner\\\\NiceHashMiner.exe\"\n", 890 | "\n", 891 | "\n", 892 | " try:\n", 893 | " subprocess.Popen(path_student)\n", 894 | " except:\n", 895 | " try:\n", 896 | " subprocess.Popen(path_aids)\n", 897 | " except:\n", 898 | " pass\n", 899 | " \n", 900 | "\n", 901 | "\n", 902 | "if __name__ == \"__main__\":\n", 903 | " \n", 904 | "\n", 905 | " minimise_window()\n", 906 | "\n", 907 | " while True:\n", 908 | " window_name = get_open_windows()\n", 909 | " print(window_name)\n", 910 | " if window_name == None:\n", 911 | " open_nicehash()\n", 912 | " minimise_window()\n", 913 | " \n", 914 | "\n", 915 | " hwnd = win32gui.FindWindow(None, window_name)\n", 916 | "\n", 917 | " if hwnd != 0:\n", 918 | " win32gui.ShowWindow(hwnd, win32con.SW_FORCEMINIMIZE)\n", 919 | " print(\"minimised third\")\n", 920 | " time.sleep(20)\n", 921 | "\n", 922 | "\n", 923 | "\n", 924 | " \n" 925 | ] 926 | }, 927 | { 928 | "cell_type": "code", 929 | "execution_count": 6, 930 | "metadata": {}, 931 | "outputs": [ 932 | { 933 | "name": "stdout", 934 | "output_type": "stream", 935 | "text": [ 936 | "['Task Switching', 'System tray overflow window.', 'CiceroUIWndFrame', 'Battery Meter', 'Network Flyout', '● data_creation 2.ipynb - market_train - Visual Studio Code', 'GDI+ Window (app_nhm.exe)', 'CiceroUIWndFrame', 'NiceHash Miner v3.1.0.9', 'MediaContextNotificationWindow', '.NET-BroadcastEventWindow.ecabc2.0', 'SystemResourceNotifyWindow', 'Minimize Window Script - Google Chrome', 'Downloads - Google Chrome', 'FnHotkeyUtility', 'Neat Download Manager 1.2', 'Code', 'DDE Server Window', 'DesktopWindowXamlSource', 'DesktopWindowXamlSource', 'AMD Software: Adrenalin Edition', 'RadeonSoftware', 'RadeonSoftware', 'RadeonSoftware', 'Mail', 'Inbox - Gmail \\u200e- Mail', 'Realtek Audio Console', 'Realtek Audio Console', 'DesktopWindowXamlSource', 'Nahimic', 'Nahimic', 'GDI+ Window (PhoneExperienceHost.exe)', '.NET-BroadcastEventWindow.2f3e4cc.0', 'Windows Input Experience', 'AMD:DVR-CapturingWindow', 'GDI+ Window (AMDRSServ.exe)', 'AMD:CCC-AEMCapturingWindow', 'NVIDIA GeForce Overlay DT', 'NVIDIA NodeJS Share Window', '{1274D398-C3C8-422E-87DD-2FAFFD5A7F2F}', '{2A335767-FC94-417F-ABC4-B4122ADBEE60}', '{5AEA657D-F3F5-4BD8-BFE9-A4B537FA24C3}', 'RealtekAudioBackgroundProcessClass', 'UxdService', 'Location Notification', 'MS_WebcheckMonitor', 'BluetoothNotificationAreaIconWindowClass', 'DDE Server Window', 'FNForMonitorMic', 'NvSvc', 'Windows Push Notifications Platform', 'BroadcastListenerWindow', 'BroadcastListenerWindow', 'BroadcastListenerWindow', 'GDI+ Window (FnHotkeyUtility.exe)', 'Fn_Hotkey_CapsLKNumLK', 'SmartDC', 'AMD EEU Client', 'Task Host Window', 'NvContainerWindowClass00002EFC', 'NvContainerWindowClass00003738', 'NvContainerWindowClass00001BC0', 'NvContainerWindowClass00001934', 'DWM Notification Window', 'BroadcastListenerWindow', 'NVIDIA GeForce Overlay', 'RadeonSoftware', 'Program Manager', 'MSCTFIME UI', 'Default IME', 'MSCTFIME UI', 'Default IME', 'Default IME', 'MSCTFIME UI', 'Default IME', 'Default IME', 'MSCTFIME UI', 'Default IME', 'Default IME', 'MSCTFIME UI', 'Default IME', 'Default IME', 'Default IME', 'MSCTFIME UI', 'Default IME', 'MSCTFIME UI', 'Default IME', 'MSCTFIME UI', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'MSCTFIME UI', 'Default IME', 'MSCTFIME UI', 'Default IME', 'MSCTFIME UI', 'Default IME', 'Default IME', 'MSCTFIME UI', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'MSCTFIME UI', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'MSCTFIME UI', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'Default IME', 'MSCTFIME UI', 'Default IME']\n", 937 | "Open Windows:\n" 938 | ] 939 | } 940 | ], 941 | "source": [ 942 | "import win32gui\n", 943 | "\n", 944 | "def get_open_windows():\n", 945 | " windows = []\n", 946 | " win32gui.EnumWindows(enum_windows_callback, windows)\n", 947 | " print(windows)\n", 948 | " return windows\n", 949 | "\n", 950 | "def enum_windows_callback(hwnd, windows):\n", 951 | " window_title = win32gui.GetWindowText(hwnd)\n", 952 | " if window_title:\n", 953 | " windows.append(window_title)\n", 954 | "\n", 955 | "if __name__ == \"__main__\":\n", 956 | " open_windows = get_open_windows()\n", 957 | "\n", 958 | " if open_windows:\n", 959 | " print(\"Open Windows:\")\n", 960 | " for window_title in open_windows:\n", 961 | " #print(window_title)\n", 962 | " pass\n", 963 | " else:\n", 964 | " print(\"No open windows found.\")\n" 965 | ] 966 | } 967 | ], 968 | "metadata": { 969 | "kernelspec": { 970 | "display_name": "Python 3", 971 | "language": "python", 972 | "name": "python3" 973 | }, 974 | "language_info": { 975 | "codemirror_mode": { 976 | "name": "ipython", 977 | "version": 3 978 | }, 979 | "file_extension": ".py", 980 | "mimetype": "text/x-python", 981 | "name": "python", 982 | "nbconvert_exporter": "python", 983 | "pygments_lexer": "ipython3", 984 | "version": "3.10.7 (tags/v3.10.7:6cc6b13, Sep 5 2022, 14:08:36) [MSC v.1933 64 bit (AMD64)]" 985 | }, 986 | "orig_nbformat": 4, 987 | "vscode": { 988 | "interpreter": { 989 | "hash": "26de051ba29f2982a8de78e945f0abaf191376122a1563185a90213a26c5da77" 990 | } 991 | } 992 | }, 993 | "nbformat": 4, 994 | "nbformat_minor": 2 995 | } 996 | -------------------------------------------------------------------------------- /data_creation.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stderr", 10 | "output_type": "stream", 11 | "text": [ 12 | "C:\\Users\\Lenovo\\AppData\\Roaming\\Python\\Python310\\site-packages\\mpl_finance.py:16: DeprecationWarning: \n", 13 | "\n", 14 | " =================================================================\n", 15 | "\n", 16 | " WARNING: `mpl_finance` is deprecated:\n", 17 | "\n", 18 | " Please use `mplfinance` instead (no hyphen, no underscore).\n", 19 | "\n", 20 | " To install: `pip install --upgrade mplfinance` \n", 21 | "\n", 22 | " For more information, see: https://pypi.org/project/mplfinance/\n", 23 | "\n", 24 | " =================================================================\n", 25 | "\n", 26 | " __warnings.warn('\\n\\n ================================================================='+\n" 27 | ] 28 | } 29 | ], 30 | "source": [ 31 | "import os\n", 32 | "import time\n", 33 | "import json\n", 34 | "import numpy as np\n", 35 | "import pandas as pd\n", 36 | "import threading\n", 37 | "\n", 38 | "import matplotlib.pyplot as plt\n", 39 | "import matplotlib\n", 40 | "from matplotlib.figure import Figure\n", 41 | "from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg\n", 42 | "\n", 43 | "from mpl_finance import candlestick_ohlc\n", 44 | "import mpl_finance as mplf\n", 45 | "\n", 46 | "import tkinter as tk\n", 47 | "from tkinter import *\n", 48 | "from tkinter import ttk\n", 49 | "\n", 50 | "\n" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 2, 56 | "metadata": {}, 57 | "outputs": [ 58 | { 59 | "name": "stderr", 60 | "output_type": "stream", 61 | "text": [ 62 | "C:\\Users\\Lenovo\\AppData\\Local\\Temp\\ipykernel_13772\\883750720.py:6: DtypeWarning: Columns (10,11) have mixed types. Specify dtype option on import or set low_memory=False.\n", 63 | " csv_data = pd.read_csv(\"D:\\\\market_train\\\\dataset\\\\data creation\\\\\"+file_name)\n" 64 | ] 65 | } 66 | ], 67 | "source": [ 68 | "file_names = os.listdir(\"D:\\\\market_train\\\\dataset\\\\nifty 1m\")\n", 69 | "\n", 70 | "\n", 71 | "#or file in file_names[0:1]:\\\n", 72 | "file_name = \"ASIANPAINT_with_indicators_.csv\"\n", 73 | "csv_data = pd.read_csv(\"D:\\\\market_train\\\\dataset\\\\data creation\\\\\"+file_name)\n", 74 | "csv_data['date'] = pd.to_datetime(csv_data['date'])\n" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 3, 80 | "metadata": {}, 81 | "outputs": [ 82 | { 83 | "name": "stdout", 84 | "output_type": "stream", 85 | "text": [ 86 | "70362 70367 70372 70375 70432 DOUBLE TOP\n", 87 | "71636 71646 71681 71715 71739 DOUBLE TOP\n", 88 | "saved changes\n", 89 | "72920 72926 72930 72939 72948 DOUBLE TOP\n", 90 | "74465 74474 74482 74486 74493 74498 74567 HEAD AND SHOULDERS\n", 91 | "saved changes\n", 92 | "74948 74958 74964 74968 74982 DOUBLE TOP\n", 93 | "76602 76621 76639 76645 76675 DOUBLE TOP\n", 94 | "78995 79008 79012 79017 79031 DOUBLE TOP\n", 95 | "saved changes\n", 96 | "81838 81841 81844 81851 81857 81866 81889 HEAD AND SHOULDERS\n", 97 | "82384 82395 82413 82436 82453 DOUBLE TOP\n", 98 | "saved changes\n", 99 | "83063 83072 83083 83086 83099 83108 83121 HEAD AND SHOULDERS\n", 100 | "83579 83586 83589 83595 83615 DOUBLE TOP\n", 101 | "84464 84494 84505 84515 84539 DOUBLE TOP\n", 102 | "saved changes\n", 103 | "85515 85520 85526 85549 85579 85586 85691 HEAD AND SHOULDERS\n", 104 | "87438 87455 87460 87467 87476 87483 87552 HEAD AND SHOULDERS\n", 105 | "88478 88506 88517 88527 88539 88548 88603 HEAD AND SHOULDERS\n", 106 | "saved changes\n", 107 | "89249 89294 89346 89417 89503 DOUBLE TOP\n", 108 | "89560 89573 89584 89593 89691 DOUBLE TOP\n", 109 | "90697 90704 90717 90743 90757 90766 90776 HEAD AND SHOULDERS\n", 110 | "saved changes\n", 111 | "95196 95208 95225 95244 95261 DOUBLE TOP\n", 112 | "saved changes\n", 113 | "100081 100095 100103 100122 100144 100159 100189 HEAD AND SHOULDERS\n", 114 | "100481 100490 100504 100518 100528 100536 100603 HEAD AND SHOULDERS\n" 115 | ] 116 | }, 117 | { 118 | "name": "stdout", 119 | "output_type": "stream", 120 | "text": [ 121 | "saved changes\n" 122 | ] 123 | } 124 | ], 125 | "source": [ 126 | "class Write_to_csv:\n", 127 | " \n", 128 | " def __init__(self) -> None:\n", 129 | " global counter\n", 130 | " self.current_pattern = None\n", 131 | " self.start_index = None\n", 132 | " self.shoulder1_index = None\n", 133 | " self.shoulder2_index = None\n", 134 | " self.neckline_index = None\n", 135 | " self.neckline1_index = None\n", 136 | " self.neckline2_index = None\n", 137 | " self.head_index = None\n", 138 | " self.top1_index = None\n", 139 | " self.top2_index = None\n", 140 | " self.target_index = None\n", 141 | " self.price_counter = 0\n", 142 | " self.changes = None\n", 143 | " self.save_data_thread = threading.Thread(target=self.save_data_to_csv)\n", 144 | " self.save_data_thread.start()\n", 145 | " self.start_time = time.time()\n", 146 | " self.current_state = {}\n", 147 | " with open('current_status.json','r') as json_status_file:\n", 148 | " self.current_state = json.load(json_status_file)\n", 149 | " counter = self.current_state['completed index']\n", 150 | " self.previous_counter = counter\n", 151 | "\n", 152 | " process_graph.update_plot(0)\n", 153 | " Label_changes.show_counter()\n", 154 | "\n", 155 | "\n", 156 | "\n", 157 | "\n", 158 | " def save_data_to_csv(self):\n", 159 | " while True:\n", 160 | " time.sleep(60)\n", 161 | " self.current_state['completed index'] = counter\n", 162 | " self.current_state['total time spent'] += time.time() - self.start_time\n", 163 | " self.current_state['total completed index'] += counter - self.previous_counter\n", 164 | " self.start_time = time.time()\n", 165 | " self.previous_counter = counter\n", 166 | "\n", 167 | "\n", 168 | " with open('current_status.json','w') as json_status_file:\n", 169 | " json.dump(self.current_state,json_status_file)\n", 170 | "\n", 171 | " if self.changes != None:\n", 172 | " csv_data.to_csv('D:\\\\market_train\\\\dataset\\\\data creation\\\\'+file_name, index=False )\n", 173 | " print(\"saved changes\")\n", 174 | " self.changes = None\n", 175 | " else:\n", 176 | " print(\"no changes saved\")\n", 177 | " \n", 178 | "\n", 179 | " def write_double_top_to_csv(self,value1,value2,value3,value4,value5):\n", 180 | " if self.current_pattern == \"DOUBLE TOP\":\n", 181 | " self.changes = 1\n", 182 | " self.start_index = value1 + counter\n", 183 | " self.top1_index = value2 + counter\n", 184 | " self.neckline_index = value3 + counter\n", 185 | " self.top2_index = value4 + counter\n", 186 | " self.target_index = value5 + counter\n", 187 | "\n", 188 | "\n", 189 | " for index in range(self.start_index,self.target_index+1,1):\n", 190 | " csv_data.at[index,'patternName_doubletop'] = 'DT'\n", 191 | "\n", 192 | " csv_data.at[self.start_index,'patternFeatures_doubletop'] = 'START'\n", 193 | " csv_data.at[self.top1_index,'patternFeatures_doubletop'] = 'TOP 1'\n", 194 | " csv_data.at[self.neckline_index,'patternFeatures_doubletop'] = 'NECKLINE'\n", 195 | " csv_data.at[self.top2_index,'patternFeatures_doubletop'] = 'TOP 2'\n", 196 | " csv_data.at[self.target_index,'patternFeatures_doubletop'] = 'TARGET'\n", 197 | "\n", 198 | " self.current_state['total pattern identified'] += 1\n", 199 | " self.current_state['total double top'] += 1\n", 200 | "\n", 201 | " #csv_data.to_csv('D:\\\\market_train\\\\dataset\\\\temp_data_creation_updated.csv')\n", 202 | "\n", 203 | "\n", 204 | " print(self.start_index,\n", 205 | " self.top1_index,\n", 206 | " self.neckline_index,\n", 207 | " self.top2_index,\n", 208 | " self.target_index,\n", 209 | " self.current_pattern)\n", 210 | " \n", 211 | " def write_head_and_shoulders_to_csv(self,value1,value2,value3,value4,value5,value6,value7):\n", 212 | " if self.current_pattern == \"HEAD AND SHOULDERS\":\n", 213 | " self.changes = 1\n", 214 | " self.start_index = value1 + counter\n", 215 | " self.shoulder1_index = value2 + counter\n", 216 | " self.neckline1_index = value3 + counter\n", 217 | " self.head_index = value4 + counter\n", 218 | " self.neckline2_index = value5 + counter\n", 219 | " self.shoulder2_index = value6 + counter\n", 220 | " self.target_index = value7 + counter\n", 221 | "\n", 222 | "\n", 223 | " for index in range(self.start_index,self.target_index+1,1):\n", 224 | " csv_data.at[index,'patternName_headandshoulders'] = 'H&S'\n", 225 | "\n", 226 | " csv_data.at[self.start_index,'patternFeatures_headandshoulders'] = 'START'\n", 227 | " csv_data.at[self.shoulder1_index,'patternFeatures_headandshoulders'] = 'SHOULDER 1'\n", 228 | " csv_data.at[self.neckline1_index,'patternFeatures_headandshoulders'] = 'NECKLINE 1'\n", 229 | " csv_data.at[self.head_index,'patternFeatures_headandshoulders'] = 'HEAD'\n", 230 | " csv_data.at[self.neckline2_index,'patternFeatures_headandshoulders'] = 'NECKLINE 2'\n", 231 | " csv_data.at[self.shoulder2_index,'patternFeatures_headandshoulders'] = 'SHOULDER 2'\n", 232 | " csv_data.at[self.target_index,'patternFeatures_headandshoulders'] = 'TARGET'\n", 233 | " \n", 234 | " self.current_state['total pattern identified'] += 1\n", 235 | " self.current_state['total head and shoulders'] += 1\n", 236 | "\n", 237 | " #csv_data.to_csv('D:\\\\market_train\\\\dataset\\\\temp_data_creation_updated.csv')\n", 238 | "\n", 239 | "\n", 240 | "\n", 241 | "\n", 242 | " print(self.start_index,\n", 243 | " self.shoulder1_index,\n", 244 | " self.neckline1_index,\n", 245 | " self.head_index,\n", 246 | " self.neckline2_index,\n", 247 | " self.shoulder2_index,\n", 248 | " self.target_index,\n", 249 | " self.current_pattern)\n", 250 | "\n", 251 | "\n", 252 | "class process_graph:\n", 253 | "\n", 254 | " def __init__(self) -> None:\n", 255 | " self.start_price = None\n", 256 | " self.shoulder1_price = None\n", 257 | " self.shoulder2_price = None\n", 258 | " self.neckline_price = None\n", 259 | " self.neckline1_price = None\n", 260 | " self.neckline2_price = None\n", 261 | " self.head_price = None\n", 262 | " self.top1_price = None\n", 263 | " self.top2_price = None\n", 264 | " self.target_price = None\n", 265 | " self.price_counter = 0\n", 266 | "\n", 267 | " def update_plot(self,counter_increment):\n", 268 | " global counter\n", 269 | " counter += counter_increment\n", 270 | " ax.clear() \n", 271 | "\n", 272 | " stock_prices = csv_data[counter:counter+400]\n", 273 | " mplf.candlestick2_ohlc(ax, stock_prices['open'], stock_prices['high'], stock_prices['low'], stock_prices['close'],\n", 274 | " width=0.7, colorup='g', colordown='r')\n", 275 | " canvas.draw()\n", 276 | "\n", 277 | " def reset(self):\n", 278 | " self.start_price = None\n", 279 | " self.shoulder1_price = None\n", 280 | " self.shoulder2_price = None\n", 281 | " self.neckline_price = None\n", 282 | " self.neckline1_price = None\n", 283 | " self.neckline2_price = None\n", 284 | " self.head_price = None\n", 285 | " self.top1_price = None\n", 286 | " self.top2_price = None\n", 287 | " self.target_price = None\n", 288 | " self.price_counter = 0\n", 289 | "\n", 290 | " def on_button_press(self,pattern):\n", 291 | " Write_to_csv.current_pattern = pattern\n", 292 | " if pattern == 'DOUBLE TOP':\n", 293 | " Label_changes.change_label_double_top(0)\n", 294 | " elif pattern == 'HEAD AND SHOULDERS':\n", 295 | " Label_changes.change_label_head_and_shoulder(0)\n", 296 | " \n", 297 | "\n", 298 | "\n", 299 | " def on_key(self,event):\n", 300 | " if event.key == 'right':\n", 301 | " self.update_plot(40)\n", 302 | " Label_changes.show_counter()\n", 303 | " if event.key == 'left':\n", 304 | " self.update_plot(-20)\n", 305 | " Label_changes.show_counter()\n", 306 | "\n", 307 | "\n", 308 | " def on_click(self,event):\n", 309 | " x = event.x\n", 310 | " y = event.y\n", 311 | "\n", 312 | " price_value = (x/4) - 25 \n", 313 | " price_value = int(price_value) \n", 314 | " \n", 315 | " Label_changes.show_price(price_value)\n", 316 | "\n", 317 | " if Write_to_csv.current_pattern == 'DOUBLE TOP':\n", 318 | " self.update_double_top_prices(price_value)\n", 319 | " Label_changes.change_label_double_top(self.price_counter)\n", 320 | " elif Write_to_csv.current_pattern == 'HEAD AND SHOULDERS':\n", 321 | " self.update_head_and_shoulder_prices(price_value)\n", 322 | " Label_changes.change_label_head_and_shoulder(self.price_counter)\n", 323 | " \n", 324 | "\n", 325 | "\n", 326 | " \n", 327 | " def update_double_top_prices(self,price):\n", 328 | "\n", 329 | " self.price_counter += 1\n", 330 | "\n", 331 | " match self.price_counter:\n", 332 | " case 1:\n", 333 | " self.start_price = price\n", 334 | " case 2:\n", 335 | " self.top1_price = price\n", 336 | " case 3:\n", 337 | " self.neckline_price = price\n", 338 | " case 4:\n", 339 | " self.top2_price = price\n", 340 | " case 5:\n", 341 | " self.target_price = price\n", 342 | "\n", 343 | " if self.price_counter == 5:\n", 344 | " Write_to_csv.write_double_top_to_csv(self.start_price,\n", 345 | " self.top1_price,\n", 346 | " self.neckline_price,\n", 347 | " self.top2_price,\n", 348 | " self.target_price)\n", 349 | " self.reset()\n", 350 | " Label_changes.reset()\n", 351 | "\n", 352 | " #print(self.start_price,self.top1_price,self.neckline_price,self.top2_price,self.target_price,self.price_counter)\n", 353 | "\n", 354 | " def update_head_and_shoulder_prices(self,price):\n", 355 | "\n", 356 | " self.price_counter += 1\n", 357 | "\n", 358 | " match self.price_counter:\n", 359 | " case 1:\n", 360 | " self.start_price = price\n", 361 | " case 2:\n", 362 | " self.shoulder1_price = price\n", 363 | " case 3:\n", 364 | " self.neckline1_price = price\n", 365 | " case 4:\n", 366 | " self.head_price = price\n", 367 | " case 5:\n", 368 | " self.neckline2_price = price\n", 369 | " case 6:\n", 370 | " self.shoulder2_price = price\n", 371 | " case 7:\n", 372 | " self.target_price = price\n", 373 | "\n", 374 | " if self.price_counter == 7:\n", 375 | " Write_to_csv.write_head_and_shoulders_to_csv(self.start_price,\n", 376 | " self.shoulder1_price,\n", 377 | " self.neckline1_price,\n", 378 | " self.head_price,\n", 379 | " self.neckline2_price,\n", 380 | " self.shoulder2_price,\n", 381 | " self.target_price)\n", 382 | " self.reset()\n", 383 | " Label_changes.reset()\n", 384 | " #print(self.start_price, self.shoulder1_price,self.neckline1_price,self.head_price,self.neckline2_price,self.shoulder2_price,self.target_price,self.price_counter)\n", 385 | "\n", 386 | "\n", 387 | " \n", 388 | "\n", 389 | "\n", 390 | "class Label_changes:\n", 391 | " def __init__(self) -> None:\n", 392 | "\n", 393 | "\n", 394 | " self.price_frame = tk.Frame(app)\n", 395 | " self.price_frame.grid(row=1,column=1,padx=10,pady=10)\n", 396 | "\n", 397 | " self.price_value_label = ttk.Label(self.price_frame,text=0)\n", 398 | " self.price_value_label.grid(row=0,column=0,padx=10,pady=10)\n", 399 | "\n", 400 | " self.current_counter_label = ttk.Label(self.price_frame,text=0)\n", 401 | " self.current_counter_label.grid(row=1,column=0,padx=10,pady=10)\n", 402 | "\n", 403 | " self.clicked_prices_status_frame = tk.Frame(app)\n", 404 | " self.clicked_prices_status_frame.grid(row=1,column=0,padx=10,pady=10)\n", 405 | "\n", 406 | "\n", 407 | "\n", 408 | " self.start = ttk.Label(self.clicked_prices_status_frame,text='START',background='red',foreground='white')\n", 409 | " self.top1 = ttk.Label(self.clicked_prices_status_frame,text='TOP 1',background='red',foreground='white')\n", 410 | " self.neckline = ttk.Label(self.clicked_prices_status_frame,text='NECKLINE',background='red',foreground='white')\n", 411 | " self.top2 = ttk.Label(self.clicked_prices_status_frame,text='TOP 2',background='red',foreground='white')\n", 412 | " self.shoulder1 = ttk.Label(self.clicked_prices_status_frame,text='SHOULDER 1',background='red',foreground='white')\n", 413 | " self.neckline1 = ttk.Label(self.clicked_prices_status_frame,text='NECKLINE 1',background='red',foreground='white')\n", 414 | " self.head = ttk.Label(self.clicked_prices_status_frame,text='HEAD',background='red',foreground='white')\n", 415 | " self.neckline2 = ttk.Label(self.clicked_prices_status_frame,text='NECKLINE 2',background='red',foreground='white')\n", 416 | " self.shoulder2 = ttk.Label(self.clicked_prices_status_frame,text='SHOULDER 2',background='red',foreground='white')\n", 417 | " self.target = ttk.Label(self.clicked_prices_status_frame,text='TARGET',background='red',foreground='white')\n", 418 | "\n", 419 | "\n", 420 | "\n", 421 | "\n", 422 | "\n", 423 | "\n", 424 | "\n", 425 | " def reset(self):\n", 426 | " self.price_counter = 0\n", 427 | "\n", 428 | " try:\n", 429 | " self.start.config(background='red')\n", 430 | " self.start.grid_forget()\n", 431 | " except:pass\n", 432 | " try:\n", 433 | " self.shoulder1.config(background='red')\n", 434 | " self.shoulder1.grid_forget() \n", 435 | " except:pass\n", 436 | " try:\n", 437 | " self.shoulder2.config(background='red')\n", 438 | " self.shoulder2.grid_forget() \n", 439 | " except:pass\n", 440 | " try:\n", 441 | " self.neckline.config(background='red')\n", 442 | " self.neckline.grid_forget()\n", 443 | " except:pass\n", 444 | " try:\n", 445 | " self.neckline1.config(background='red')\n", 446 | " self.neckline1.grid_forget()\n", 447 | " except:pass\n", 448 | " try:\n", 449 | " self.neckline2.config(background='red')\n", 450 | " self.neckline2.grid_forget()\n", 451 | " except:pass\n", 452 | " try:\n", 453 | " self.head.config(background='red')\n", 454 | " self.head.grid_forget()\n", 455 | " except:pass\n", 456 | " try:\n", 457 | " self.top1.config(background='red')\n", 458 | " self.top1.grid_forget()\n", 459 | " except:pass\n", 460 | " try:\n", 461 | " self.top2.config(background='red')\n", 462 | " self.top2.grid_forget()\n", 463 | " except:pass\n", 464 | " try:\n", 465 | " self.target.config(background='red')\n", 466 | " self.target.grid_forget()\n", 467 | " except:pass\n", 468 | "\n", 469 | "\n", 470 | "\n", 471 | " def change_label_double_top(self,value):\n", 472 | " \n", 473 | " if value == 0:\n", 474 | " self.reset()\n", 475 | " process_graph.reset()\n", 476 | " \n", 477 | " self.start.grid(row=0,column=0,padx=10,pady=10)\n", 478 | " self.top1.grid(row=0,column=1,padx=10,pady=10)\n", 479 | " self.neckline.grid(row=0,column=2,padx=10,pady=10)\n", 480 | " self.top2.grid(row=0,column=3,padx=10,pady=10)\n", 481 | " self.target.grid(row=0,column=4,padx=10,pady=10)\n", 482 | " \n", 483 | "\n", 484 | " match value:\n", 485 | " case 1:\n", 486 | " self.start.config(background='green')\n", 487 | " case 2:\n", 488 | " self.top1.config(background='green')\n", 489 | " case 3:\n", 490 | " self.neckline.config(background='green')\n", 491 | " case 4:\n", 492 | " self.top2.config(background='green')\n", 493 | " case 5:\n", 494 | " self.target.config(background='green')\n", 495 | "\n", 496 | " def change_label_head_and_shoulder(self,value):\n", 497 | "\n", 498 | " if value == 0:\n", 499 | " self.reset()\n", 500 | " process_graph.reset()\n", 501 | "\n", 502 | " self.start.grid(row=0,column=0,padx=10,pady=10)\n", 503 | " self.shoulder1.grid(row=0,column=1,padx=10,pady=10)\n", 504 | " self.neckline1.grid(row=0,column=2,padx=10,pady=10)\n", 505 | " self.head.grid(row=0,column=3,padx=10,pady=10)\n", 506 | " self.neckline2.grid(row=0,column=4,padx=10,pady=10)\n", 507 | " self.shoulder2.grid(row=0,column=5,padx=10,pady=10)\n", 508 | " self.target.grid(row=0,column=6,padx=10,pady=10)\n", 509 | " \n", 510 | "\n", 511 | " match value:\n", 512 | " case 1:\n", 513 | " self.start.config(background='green')\n", 514 | " case 2:\n", 515 | " self.shoulder1.config(background='green')\n", 516 | " case 3:\n", 517 | " self.neckline1.config(background='green')\n", 518 | " case 4:\n", 519 | " self.head.config(background='green')\n", 520 | " case 5:\n", 521 | " self.neckline2.config(background='green')\n", 522 | " case 6:\n", 523 | " self.shoulder2.config(background='green')\n", 524 | " case 7:\n", 525 | " self.target.config(background='green')\n", 526 | "\n", 527 | "\n", 528 | " def show_price(self,price_value):\n", 529 | " \n", 530 | " self.price_value_label.config(text=price_value,font=('Helvetica bold', 20))\n", 531 | " \n", 532 | " def show_counter(self):\n", 533 | " self.current_counter_label.config(text=counter,font=('Helvetica bold', 20))\n", 534 | "\n", 535 | "\n", 536 | "\n", 537 | "\n", 538 | " def temp():\n", 539 | " pass\n", 540 | "\n", 541 | "\n", 542 | "counter = 0\n", 543 | "start_time = time.time()\n", 544 | "\n", 545 | "app = tk.Tk()\n", 546 | "app.title(\"plot\")\n", 547 | "\n", 548 | "\n", 549 | "\n", 550 | "fig = Figure(figsize=(18, 8), dpi=100)\n", 551 | "fig.subplots_adjust(left=0.01, right=0.99, top=0.95, bottom=0.05) \n", 552 | "ax = fig.add_subplot(111)\n", 553 | "\n", 554 | "canvas = FigureCanvasTkAgg(fig, master=app)\n", 555 | "canvas_widget = canvas.get_tk_widget()\n", 556 | "canvas_widget.grid(row=0,column=0,padx=10,pady=10)\n", 557 | "\n", 558 | "bottons_frame = tk.Frame(app)\n", 559 | "bottons_frame.grid(row=0,column=1,padx=10,pady=10)\n", 560 | "\n", 561 | "Double_top_button = tk.Button(bottons_frame, text=\"Double top\", command=lambda: process_graph.on_button_press('DOUBLE TOP'),height=20,width=10)\n", 562 | "Double_top_button.grid(row=0,column=1,padx=10,pady=10)\n", 563 | "\n", 564 | "Head_and_shoulders_button = tk.Button(bottons_frame, text=\"Head and shoulders\", command=lambda: process_graph.on_button_press('HEAD AND SHOULDERS'),height=20,width=10)\n", 565 | "Head_and_shoulders_button.grid(row=1, column=1, padx=10, pady=10, sticky=\"w\")\n", 566 | "\n", 567 | "#process_graph.update_plot(0)\n", 568 | "\n", 569 | "Label_changes = Label_changes()\n", 570 | "process_graph = process_graph()\n", 571 | "Write_to_csv = Write_to_csv()\n", 572 | "\n", 573 | "\n", 574 | "canvas.mpl_connect('key_press_event',process_graph.on_key)\n", 575 | "canvas_widget.bind(\"\", process_graph.on_click)\n", 576 | "\n", 577 | "app.mainloop()" 578 | ] 579 | }, 580 | { 581 | "cell_type": "code", 582 | "execution_count": 2, 583 | "metadata": {}, 584 | "outputs": [ 585 | { 586 | "name": "stderr", 587 | "output_type": "stream", 588 | "text": [ 589 | "C:\\Users\\Lenovo\\AppData\\Local\\Temp\\ipykernel_16108\\306503543.py:6: DtypeWarning: Columns (15,16,17,18) have mixed types. Specify dtype option on import or set low_memory=False.\n", 590 | " csv_data = pd.read_csv(\"D:\\\\market_train\\\\dataset\\\\data creation\\\\\"+file_name)\n" 591 | ] 592 | } 593 | ], 594 | "source": [ 595 | "#file_names = os.listdir(\"D:\\\\market_train\\\\dataset\\\\nifty 1m\")\n", 596 | "\n", 597 | "\n", 598 | "#or file in file_names[0:1]:\\\n", 599 | "file_name = \"ARNC.csv\"\n", 600 | "csv_data = pd.read_csv(\"D:\\\\market_train\\\\dataset\\\\data creation\\\\\"+file_name)\n", 601 | "csv_data['date'] = pd.to_datetime(csv_data['date'])\n" 602 | ] 603 | }, 604 | { 605 | "cell_type": "code", 606 | "execution_count": 42, 607 | "metadata": {}, 608 | "outputs": [ 609 | { 610 | "name": "stdout", 611 | "output_type": "stream", 612 | "text": [ 613 | "DT\n", 614 | "DT\n", 615 | "DT\n", 616 | "DT\n", 617 | "DT\n", 618 | "DT\n", 619 | "DT\n", 620 | "DT\n", 621 | "DT\n", 622 | "DT\n", 623 | "DT\n", 624 | "DT\n", 625 | "DT\n", 626 | "DT\n", 627 | "DT\n", 628 | "DT\n", 629 | "DT\n", 630 | "DT\n", 631 | "DT\n", 632 | "DT\n", 633 | "DT\n", 634 | "DT\n", 635 | "DT\n", 636 | "DT\n", 637 | "DT\n", 638 | "DT\n", 639 | "DT\n", 640 | "DT\n", 641 | "DT\n", 642 | "DT\n", 643 | "DT\n", 644 | "DT\n", 645 | "DT\n", 646 | "DT\n", 647 | "DT\n", 648 | "DT\n", 649 | "DT\n", 650 | "DT\n", 651 | "DT\n", 652 | "DT\n", 653 | "DT\n", 654 | "DT\n", 655 | "DT\n", 656 | "DT\n", 657 | "DT\n", 658 | "DT\n", 659 | "DT\n", 660 | "DT\n", 661 | "DT\n", 662 | "DT\n", 663 | "DT\n", 664 | "DT\n", 665 | "DT\n", 666 | "DT\n", 667 | "DT\n", 668 | "DT\n", 669 | "DT\n", 670 | "DT\n", 671 | "DT\n", 672 | "DT\n", 673 | "DT\n", 674 | "DT\n", 675 | "DT\n", 676 | "DT\n", 677 | "DT\n", 678 | "DT\n", 679 | "DT\n", 680 | "DT\n", 681 | "DT\n", 682 | "DT\n", 683 | "DT\n", 684 | "DT\n", 685 | "DT\n", 686 | "DT\n", 687 | "DT\n", 688 | "DT\n", 689 | "DT\n", 690 | "DT\n", 691 | "DT\n", 692 | "DT\n", 693 | "DT\n", 694 | "DT\n", 695 | "DT\n", 696 | "DT\n", 697 | "DT\n", 698 | "DT\n", 699 | "DT\n", 700 | "DT\n", 701 | "DT\n", 702 | "DT\n", 703 | "DT\n", 704 | "DT\n", 705 | "DT\n", 706 | "DT\n", 707 | "DT\n", 708 | "DT\n", 709 | "DT\n", 710 | "DT\n", 711 | "DT\n", 712 | "DT\n", 713 | "DT\n", 714 | "DT\n", 715 | "DT\n", 716 | "DT\n", 717 | "DT\n", 718 | "DT\n", 719 | "DT\n", 720 | "DT\n", 721 | "DT\n", 722 | "DT\n", 723 | "DT\n", 724 | "DT\n", 725 | "DT\n", 726 | "DT\n", 727 | "DT\n", 728 | "DT\n", 729 | "DT\n", 730 | "DT\n", 731 | "DT\n", 732 | "DT\n", 733 | "DT\n", 734 | "DT\n", 735 | "DT\n", 736 | "DT\n", 737 | "DT\n", 738 | "DT\n", 739 | "DT\n", 740 | "DT\n", 741 | "DT\n", 742 | "DT\n", 743 | "DT\n", 744 | "DT\n", 745 | "DT\n", 746 | "DT\n", 747 | "DT\n", 748 | "DT\n", 749 | "DT\n", 750 | "DT\n", 751 | "DT\n", 752 | "DT\n", 753 | "DT\n", 754 | "DT\n", 755 | "DT\n", 756 | "DT\n", 757 | "DT\n", 758 | "DT\n", 759 | "DT\n", 760 | "DT\n", 761 | "DT\n", 762 | "DT\n", 763 | "DT\n", 764 | "DT\n", 765 | "DT\n", 766 | "DT\n", 767 | "DT\n", 768 | "DT\n", 769 | "DT\n", 770 | "DT\n", 771 | "DT\n", 772 | "DT\n", 773 | "DT\n", 774 | "DT\n", 775 | "DT\n", 776 | "DT\n", 777 | "DT\n" 778 | ] 779 | } 780 | ], 781 | "source": [ 782 | "x_data = []\n", 783 | "y_data = []\n", 784 | "\n", 785 | "counter = 0\n", 786 | "close = csv_data['open']\n", 787 | "\n", 788 | "while True:\n", 789 | " if csv_data['patternName_doubletop'][counter] == 'DT':\n", 790 | " x_temp = []\n", 791 | " print(csv_data['patternName_doubletop'][counter])\n", 792 | " for i in range(counter,len(close)):\n", 793 | " if csv_data['patternName_doubletop'][i] == 'DT':\n", 794 | " x_temp.append(close[i])\n", 795 | " else:\n", 796 | " counter = i\n", 797 | " break\n", 798 | " x_data.append(x_temp)\n", 799 | " counter += 1\n", 800 | " if counter >= len(close):\n", 801 | " break\n", 802 | " \n", 803 | "\n" 804 | ] 805 | }, 806 | { 807 | "cell_type": "code", 808 | "execution_count": 43, 809 | "metadata": {}, 810 | "outputs": [ 811 | { 812 | "data": { 813 | "text/plain": [ 814 | "[]" 815 | ] 816 | }, 817 | "execution_count": 43, 818 | "metadata": {}, 819 | "output_type": "execute_result" 820 | }, 821 | { 822 | "data": { 823 | "image/png": "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", 824 | "text/plain": [ 825 | "
" 826 | ] 827 | }, 828 | "metadata": {}, 829 | "output_type": "display_data" 830 | } 831 | ], 832 | "source": [] 833 | }, 834 | { 835 | "cell_type": "code", 836 | "execution_count": 44, 837 | "metadata": {}, 838 | "outputs": [ 839 | { 840 | "data": { 841 | "text/plain": [ 842 | "165" 843 | ] 844 | }, 845 | "execution_count": 44, 846 | "metadata": {}, 847 | "output_type": "execute_result" 848 | } 849 | ], 850 | "source": [ 851 | "len(x_data)" 852 | ] 853 | } 854 | ], 855 | "metadata": { 856 | "kernelspec": { 857 | "display_name": "Python 3", 858 | "language": "python", 859 | "name": "python3" 860 | }, 861 | "language_info": { 862 | "codemirror_mode": { 863 | "name": "ipython", 864 | "version": 3 865 | }, 866 | "file_extension": ".py", 867 | "mimetype": "text/x-python", 868 | "name": "python", 869 | "nbconvert_exporter": "python", 870 | "pygments_lexer": "ipython3", 871 | "version": "3.10.7 (tags/v3.10.7:6cc6b13, Sep 5 2022, 14:08:36) [MSC v.1933 64 bit (AMD64)]" 872 | }, 873 | "orig_nbformat": 4, 874 | "vscode": { 875 | "interpreter": { 876 | "hash": "26de051ba29f2982a8de78e945f0abaf191376122a1563185a90213a26c5da77" 877 | } 878 | } 879 | }, 880 | "nbformat": 4, 881 | "nbformat_minor": 2 882 | } 883 | --------------------------------------------------------------------------------