text: from os import truncate
  from websocket import create_connection
  import json
  import random
  import string
  import re
  import csv
  import numpy as np
  from datetime import datetime
  import pandas as pd
  import matplotlib.pyplot as plt
  from pandas_datareader import data, wb
  from ichimoku import getValue
  from ichimoku import getClose
  from ichimoku import getSenkouA
  from ichimoku import getSenkouB
  
  import threading
  import schedule
  import time
  import datetime as dt
  import smtplib, ssl
  
  
  
  class ThreadWithResult(threading.Thread):
      def __init__(self, group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None):
          def function():
              self.result = target(*args, **kwargs)
          super().__init__(group=group, target=function, name=name, daemon=daemon)
  
  values = []
  threads = []
  
  
  def filter_raw_message(text):
      try:
          found = re.search('"m":"(.+?)",', text).group(1)
          found2 = re.search('"p":(.+?"}"])}', text).group(1)
      #    print(found)
      #    print(found2)
          return found1, found2
      except AttributeError:
          print("error")
  
  def isNowInTimePeriod(startTime, endTime, nowTime): 
      if startTime < endTime: 
          return nowTime >= startTime and nowTime <= endTime 
      else: 
          #Over midnight: 
          return nowTime >= startTime or nowTime <= endTime 
   
  
  def generateSession():
      stringLength=12
      letters = string.ascii_lowercase
      random_string= ''.join(random.choice(letters) for i in range(stringLength))
      return "qs_" +random_string
  
  def generateChartSession():
      stringLength=12
      letters = string.ascii_lowercase
      random_string= ''.join(random.choice(letters) for i in range(stringLength))
      return "cs_" +random_string
  
  def prependHeader(st):
      return "~m~" + str(len(st)) + "~m~" + st
  
  def constructMessage(func, paramList):
      #json_mylist = json.dumps(mylist, separators=(',', ':'))
      return json.dumps({
          "m":func,
          "p":paramList
          }, separators=(',', ':'))
  
  def createMessage(func, paramList):
      return prependHeader(constructMessage(func, paramList))
  
  def sendRawMessage(ws, message):
      ws.send(prependHeader(message))
  
  def sendMessage(ws, func, args):
      ws.send(createMessage(func, args))
  
  def generate_csv(a,id):
      out= re.search('"s":\[(.+?)\}\]', a).group(1)
      x=out.split(',{\"')
      
      with open(id+'.csv', mode='w', newline='') as data_file:
          employee_writer = csv.writer(data_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
      
          employee_writer.writerow(['index', 'date', 'open', 'high', 'low', 'close', 'volume'])
          
          for xi in x:
              xi= re.split('\[|:|,|\]', xi)
             # print(xi)
              ind= int(xi[1])
              ts= datetime.fromtimestamp(float(xi[4])).strftime("%Y/%m/%d, %H:%M:%S")
              employee_writer.writerow([ind, ts, float(xi[5]), float(xi[6]), float(xi[7]), float(xi[8]), float(xi[9])])
  
  def schedule_actions():
      
    # Every Monday task() is called at 20:
    # TODO CHANGE TO 9
    global bool_flag
    schedule.every(60).minutes.do(start_thread)
    signal_list = start_thread()
    # Checks whether a scheduled task is pending to run or no p.panthalattiyil@gmail.com
    while True:
      schedule.run_pending()
      time.sleep(1)            
  
  
  def send_mail(text):
      port = 587  # For starttls
      smtp_server = "smtp.gmail.com"
      sender_email = " "
      receiver_email = " "
      password = " "
      message = """\
      Subject: Ichimoku Sensei
  
      This message is sent from Python 
      
  
      """ + text 
  
  
      context = ssl.create_default_context()
      with smtplib.SMTP(smtp_server, port) as server:
          server.ehlo()  # Can be omitted
          server.starttls(context=context)
          server.ehlo()  # Can be omitted
          server.login(sender_email, password)
          server.sendmail(sender_email, receiver_email, message)
  
  
  def job_function(id):
      try:
          if dt.datetime.today().weekday() != 5 or dt.datetime.today().weekday() != 6:
              if True:        # Initialize the headers needed for the websocket connection
                  headers = json.dumps({
                      # 'Connection': 'upgrade',
                      # 'Host': 'data.tradingview.com',
                      'Origin': 'https://data.tradingview.com'
                      # 'Cache-Control': 'no-cache',
                      # 'Upgrade': 'websocket',
                      # 'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits',
                      # 'Sec-WebSocket-Key': '2C08Ri6FwFQw2p4198F/TA==',
                      # 'Sec-WebSocket-Version': '13',
                      # 'User-Agent': 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36 Edg/83.0.478.56',
                      # 'Pragma': 'no-cache',
                      # 'Upgrade': 'websocket'
                  })
  
                  print("schedule job started")
  
                  interval = 1
                  values = []
  
                  # TODO CHANGE TO 16
  
                  while( 16 >= interval):                    
                      val = interval * 15
  
                      print("Value at " + str(val))
                      # Then create a connection to the tunnel
                      ws = create_connection(
                          'wss://data.tradingview.com/socket.io/websocket',headers=headers)
  
                      session= generateSession()
              #     print("session generated {}".format(session))
  
                      chart_session= generateChartSession()
              #     print("chart_session generated {}".format(chart_session))
  
  
                      # Then send a message through the tunnel 
                      sendMessage(ws, "set_auth_token", ["unauthorized_user_token"])
                      sendMessage(ws, "chart_create_session", [chart_session, ""])
                      sendMessage(ws, "quote_create_session", [session])
                      sendMessage(ws,"quote_set_fields", [session,"ch","chp","current_session","description","local_description","language","exchange","fractional","is_tradable","lp","lp_time","minmov","minmove2","original_name","pricescale","pro_name","short_name","type","update_mode","volume","currency_code","rchp","rtc"])
                      sendMessage(ws, "quote_add_symbols",[session, id, {"flags":['force_permission']}])
                      sendMessage(ws, "quote_fast_symbols", [session,id])
  
                      #st='~m~140~m~{"m":"resolve_symbol","p":}'
                      #p1, p2 = filter_raw_message(st)
                      sendMessage(ws, "resolve_symbol", [chart_session,"symbol_1","={\"symbol\":\""+id+"\",\"adjustment\":\"splits\",\"session\":\"extended\"}"])
                      sendMessage(ws, "create_series", [chart_session, "s1", "s1", "symbol_1", str(val), 2000])
                      #sendMessage(ws, "create_study", [chart_session,"st4","st1","s1","ESD@tv-scripting-101!",{"text":"BNEhyMp2zcJFvntl+CdKjA==_DkJH8pNTUOoUT2BnMT6NHSuLIuKni9D9SDMm1UOm/vLtzAhPVypsvWlzDDenSfeyoFHLhX7G61HDlNHwqt/czTEwncKBDNi1b3fj26V54CkMKtrI21tXW7OQD/OSYxxd6SzPtFwiCVAoPbF2Y1lBIg/YE9nGDkr6jeDdPwF0d2bC+yN8lhBm03WYMOyrr6wFST+P/38BoSeZvMXI1Xfw84rnntV9+MDVxV8L19OE/0K/NBRvYpxgWMGCqH79/sHMrCsF6uOpIIgF8bEVQFGBKDSxbNa0nc+npqK5vPdHwvQuy5XuMnGIqsjR4sIMml2lJGi/XqzfU/L9Wj9xfuNNB2ty5PhxgzWiJU1Z1JTzsDsth2PyP29q8a91MQrmpZ9GwHnJdLjbzUv3vbOm9R4/u9K2lwhcBrqrLsj/VfVWMSBP","pineId":"TV_SPLITS","pineVersion":"8.0"}])
  
  
                      # Printing all the result
                      a=""
                      i = 0
                      while i  < 10:
                          try:
                              result = ws.recv()
                  #            print(result)
                              a=a+result+"\n"
                              i=i+1
                          except Exception as e:
                              print(e)
                              break
                          
                      generate_csv(a,id)
  
                      values = np.append(values,getValue(id))
  
                      interval = interval + 1
  
                      if interval == 5:
                          interval = 16
  
                      if interval == 3:
                          interval = 4
  
                  print(values)
  
                  check = all(x==values[0] for x in values)
  
                  check_false = True
  
                  print("schedule job finished "+id)
  
  
                  if check:
                      check_false = True
                      if values[0] == 1:
                          result_signal = ["Buy", id, "Close Price: "+ str(getClose()), "Senkou A "+ str(getSenkouA()), "Senkou B "+ str(getSenkouB())]
                          return result_signal
                          
                      else:
                          result_signal = ["Sell", id,"Close Price: "+ str(getClose()), "Senkou A "+ str(getSenkouA()), "Senkou B "+ str(getSenkouB())]
                          return result_signal
                  else:
                      result_signal = ["Nothing", id,"Close Price: "+ str(getClose()), "Senkou A "+ str(getSenkouA()), "Senkou B "+ str(getSenkouB())]
                      print("Elements are not equal")
                      return result_signal
              
              else:
                  print("BOT offline")
                  time.sleep(600)
                  print("BOT Waking up")
                  result_signal = ["Ignore State", id,"Close Price: "+ str(getClose()), "Senkou A "+ str(getSenkouA()), "Senkou B "+ str(getSenkouB())]
          else:
              time.sleep(172800)
              return job_function(id)
      except:
          result_signal = ["Server error", id,"Close Price: NA ", "Senkou A NA", "Senkou B NA"]
          print("Connection could not be established, retry soon")
          return result_signal
  
  def checkSame(list1,list2):
      for f, b in zip(list1, list2):
  
          if f is None and b is None:
              continue
          
          print(f[0] + " check both " + b[0])
          
          if f[0] != b[0] and f[0] != "Server error":
              print("Returning new value ")
              return False
      
      
      print("Returning ever True ")
  
      return True
  
  currency_list = ["FOREXCOM:EURUSD","FOREXCOM:USDCHF","FOREXCOM:EURCHF","FOREXCOM:CADCHF","FOREXCOM:EURGBP","FOREXCOM:EURCAD"]
  thread_list = []
  currentThreadListResult = []
  
  
  boot_flag = [True]
  
  def start_thread():
      print("Thread started")
      global currentThreadListResult
      currentThreadListResult = [None]
  
  
  
      if boot_flag[0]:
          global previousThreadListResult
          previousThreadListResult = [None]
          print("Boot flag set False")
          boot_flag[0] = False
  
  
      for x in range (len(currency_list)):
          thread = ThreadWithResult(target=job_function, args=(currency_list[x],))
          thread_list.append(thread)
          thread.start()
  
      message = ""        
      for x in range(len(thread_list)):
          thread_list[x].join()
  
      for x in range(len(thread_list)):
          currentThreadListResult.append(thread_list[x].result)
          message+=(str(thread_list[x].result) + " \n\n")
  
  #     thread1.start()
  #     thread2.start()
  #     thread3.start()
  #     thread4.start()
  #     thread5.start()
  #    # thread6.start()
  #    # thread7.start()
  #    # thread8.start()
      
  #     thread1.join()
  #     thread2.join()
  #     thread3.join()
  #     thread4.join()
  #     thread5.join()
  #    # thread6.join()
  #    # thread7.join()
  #    # thread8.join()
      print("current list: "+ str(currentThreadListResult))
      print("prev list: "+ str(previousThreadListResult))
  
  
  #   message = str(thread1.result) + " \n\n" + str(thread2.result) + " \n\n" + str(thread3.result)  + " \n\n" +   str(thread4.result)+ " \n\n" + str(thread5.result) 
      if isNowInTimePeriod(dt.time(8,00), dt.time(18,00), dt.datetime.now().time()) and not checkSame(previousThreadListResult, currentThreadListResult):
          
          print("Different Signal than previous")
          send_mail(message)
          
  
      print(message)
  
      message = "BOT offline"
      thread_list.clear()
      previousThreadListResult = currentThreadListResult.copy()
      currentThreadListResult.clear()
  
  schedule_actions()
  