text: # written in python 3.*
  #-*- coding: utf-8 -*-
  
  #pip install coolsms_python_sdk
  from sdk.api.message import Message
  from sdk.exceptions import CoolsmsException
  
  from threading import Timer
  from time import sleep
  import time
  import string
  import re
  import sys
  import urllib.request, urllib.error, urllib.parse  
  import copy
  import logging  
  
  #pip install git+https://github.com/ericsomdahl/python-bittrex.git
  from API import bittrex_api
  
  #pip install BeautifulSoup4
  #pip install lxml
  from bs4 import BeautifulSoup  
  
  #pip install selenium
  from selenium import webdriver
  from selenium.webdriver.common.keys import Keys
  from selenium.webdriver.chrome.options import Options
  from selenium.common.exceptions import NoSuchElementException
  from selenium.common.exceptions import NoAlertPresentException
  from selenium.webdriver.common.by import By
  from selenium.webdriver.support.ui import WebDriverWait
  from selenium.webdriver.support import expected_conditions as EC
  from selenium.common.exceptions import TimeoutException
  import ssl
  
  logging.basicConfig(filename="log.txt", format='%(asctime)s %(message)s', level=logging.DEBUG)
  # create logger
  logger = logging.getLogger('simple_example')
  
  # pip install python-telegram-bot
  import telegram
  
  import Config
  
  TELE_BOT = telegram.Bot(token= Config.TELEGRAM_CLIENT_TOKEN)
  TELE_CHAT_ID = TELE_BOT.getUpdates()[-1].message.chat.id
  
  
  ssl._create_default_https_context = ssl._create_unverified_context
  reload(sys)
  sys.setdefaultencoding('utf-8')
  
  # set api key, api secret for sending sms
  api_key = Config.COOLSMS_API_KEY
  api_secret =  Config.COOLSMS_API_SECRET
  
  #TEXT_MEMORY_FILE = "MEMORY.txt"
  LAST_TOTAL_COIN_COUNT = 0
  LAST_UNDER_READY_COIN_COUNT = 0
  LAST_LIST = []
  CURR_LIST = []
  
  # TRACKING(0), TRADING(1)
  E_MODE = 0
  PURCHARSED_COIN_NAME = ""
  PARSING_COUNT = 0
  
  def checkwhetherThereIsNewCoin():
      global CURR_LIST
      global LAST_LIST
  
      #print "checkwhetherThereIsNewCoin() -> len(LAST_LIST) : " + str(len(LAST_LIST))
  
      if len(LAST_LIST) == 0 or len(CURR_LIST) == 0:
          return "nothing"
  
      print(("len(LAST_LIST) : " + str(len(LAST_LIST))))
      print(("len(CURR_LIST) : " + str(len(CURR_LIST))))
      
      if(len(LAST_LIST) == len(CURR_LIST)):
          return "nothing"
  
      newCoinSet= set(LAST_LIST) - set(CURR_LIST)
      #print newCoinSet
      if len(list(newCoinSet)) >= 1: # 
          #print list(newCoinSet)[0]
          return list(newCoinSet)[0] # return the new released coin name
  
      return "nothing"
  
  def recordToFile(arrPriceList):
      global LAST_UNDER_READY_COIN_COUNT
      global LAST_TOTAL_COIN_COUNT
      global CURR_LIST
      global LAST_LIST
      print("recordToFile()")
      # init list val
  
      logger.error("test")
      filePath= "Output_"+time.strftime("%d_%m_%Y")+".txt"
      # spliter between tasks
      text_file = open(filePath, "a")
      text_file.write(">>>time : " + time.strftime("%a, %d %b %Y %H:%M:%S") + "\n")
      text_file.write("전체 코인 개수 : " + str(LAST_TOTAL_COIN_COUNT)+ " 개\n")
      text_file.write("준비중인 코인 : " + str(LAST_UNDER_READY_COIN_COUNT) + "개\n")
  
      for coin in arrPriceList:
          # trim useless
          context= coin.replace("즐겨찾기", "")
          coin_name= context.split("/")[0]
  
          if "준비중" in coin:
              CURR_LIST.append(coin_name)
  
          #text_file.write(context)
          #text_file.write('\n')
      text_file.write('\n\n')
      text_file.close()
      #print CURR_LIST
  
  def sendTelegramMsg(msg):
      global TELE_CHAT_ID
      global TELE_BOT
  
      print("sendTelegramMsg()")
      TELE_BOT.sendMessage(chat_id=TELE_CHAT_ID, text=msg)
  
  def sendSMS(msg):
      print("sendSMS()")
      ## 4 params(to, from, type, text) are mandatory. must be filled
      params = dict()
      params['type'] = 'sms' # Message type ( sms, lms, mms, ata )
      params['to'] = '' # Recipients Number '01000000000,01000000001'
      params['from'] = '' # Sender number
      params['text'] = msg # Message
  
      cool = Message(api_key, api_secret)
      try:
          response = cool.send(params)
          print(("Success Count : %s" % response['success_count']))
          print(("Error Count : %s" % response['error_count']))
          print(("Group ID : %s" % response['group_id']))
  
          if "error_list" in response:
              print(("Error List : %s" % response['error_list']))
  
      except CoolsmsException as e:
          print(("Error Code : %s" % e.code))
          print(("Error Message : %s" % e.msg))
  
  
  def SellAgain():
      global E_MODE
      global PURCHARSED_COIN_NAME
  
      print("SellAgain()")
      targetCoinName, Quantity_request= SellTargetCoinWhichIHave("BTC", PURCHARSED_COIN_NAME, 1)
      sendTelegramMsg("타이머가 지나서 매수했던 코인 전량 매도를 시도했음. [" + targetCoinName + "]" + str(Quantity_request) + "개 --> [BTC]")
      E_MODE = 0      # change mode into TRACKING
  
  # important!
  def FoundANewCoinEvent(newCoin):    
      global E_MODE
      global PURCHARSED_COIN_NAME
  
      print("FoundANewCoinEvent(newCoin)")
      E_MODE = 1    # change mode into TRADING
  
      onlyEngCoinName = re.sub(r"[^A-Za-z]+", '', newCoin)
      sendTelegramMsg("새로운 코인 상장 발견 : " + newCoin +", [" + onlyEngCoinName +"]로 비트렉스 시장 검색시작.")
      
      # buy 95% of current balance at bittrex
      affordable, savedRate= HowManyCoinYouCanBuyWithMyBalance("BTC", onlyEngCoinName)
      targetCoinName, Quantity_request= BuyLimit_PercentageOfMyBalance("BTC", onlyEngCoinName, affordable, savedRate, 0.95)
  
      PURCHARSED_COIN_NAME = targetCoinName # save purchased name of coin
      sendTelegramMsg("[" + targetCoinName +"]코인을 " + str(Quantity_request) +"만큼 매수 시도했음.")
      
      t = Timer(600, SellAgain)
      t.start() # after x seconds, sell again
  
  
  def TryToParse(TESTorREAL):
      global LAST_UNDER_READY_COIN_COUNT
      global LAST_TOTAL_COIN_COUNT
      global CURR_LIST
      global LAST_LIST
      global PARSING_COUNT
  
      PARSING_COUNT = PARSING_COUNT + 1 # add count
  
      # target url
      print("TryToParse()")
  
      try:
          url = "https://upbit.com/exchange"
  
          if TESTorREAL == "TEST":
              url = "http://softinus.com/upbit_tracker/upbit_tdd1.html"
          
          browser = webdriver.Chrome()
          #browser.implicitly_wait(11) # seconds
          browser.get(url)
  
          delay = 10 # seconds
          while True:
              try:
                  myElem = WebDriverWait(browser, delay).until(EC.presence_of_element_located((By.LINK_TEXT, "로그인")))
                  print("Page is ready!")
                  break # it will break from the loop once the specific element will be present. 
              except TimeoutException:
                  print("Loading took too much time!")
                  browser.quit()
                  return
  
          #wait = WebDriverWait(driver, 10)
          #element = wait.until(EC.element_to_be_clickable((By.ID, 'someid')))
  
          soup = BeautifulSoup(browser.page_source, "lxml")
          #page = urllib2.urlopen(url)
          #soup = BeautifulSoup(page, "lxml")
  
          ul_top = soup.find("ul", { "class":"ty05" })
          div_scrollB= ul_top.findNext('div').find("div", { "class":"scrollB" })
          strPriceList= div_scrollB.div.div.table.tbody.text.strip()
          arrPriceList= strPriceList.split('--')
          #print arrPriceList
          #str_count_caption= "총 " +str(len(arrPriceList)) +" 개 코인\n" 
          LAST_TOTAL_COIN_COUNT= len(arrPriceList) -1   # save last total coin count here except 1st row
          print(str(LAST_TOTAL_COIN_COUNT))
  
          LAST_UNDER_READY_COIN_COUNT = 0
          for coin in arrPriceList:
              if "준비중" in coin:
                  LAST_UNDER_READY_COIN_COUNT= LAST_UNDER_READY_COIN_COUNT +1
              
          #LAST_UNDER_READY_COIN_COUNT = LAST_UNDER_READY_COIN_COUNT -1 # except the 1st col
  
          CURR_LIST= []
          recordToFile(arrPriceList)
          newCoin= checkwhetherThereIsNewCoin()
  
          # found a new coin!
          if newCoin != "nothing":
              print(newCoin)
              FoundANewCoinEvent(newCoin)
  
          LAST_LIST= copy.deepcopy(CURR_LIST) #deep copy to 
  
          browser.quit()
      except Exception as e:
          logging.exception(e)
          sendTelegramMsg("TryToParse()에서 Exception 발생 : " + str(e))
          pass
      finally:
          pass
      
  def SendStatusRegularlly():
      global E_MODE
      global PARSING_COUNT
  
      currTime = time.strftime("%H:%M:%S")
      #print str(currTime)
      if str(currTime) == "06:35:00" or str(currTime) == "11:35:00" or str(currTime) == "14:35:00" or str(currTime) == "16:30:00":
          if E_MODE == 0:
              sendTelegramMsg("현재서버시각 : " + str(currTime) + " / 서버 정상 동작 중... / 현재 트래킹모드 상태. / COUNT : " + str(PARSING_COUNT))
          elif E_MODE == 1:
              sendTelegramMsg("현재서버시각 : " + str(currTime) + " / 서버 정상 동작 중... / 현재 거래모드 상태. / COUNT : " + str(PARSING_COUNT))
  
  sendTelegramMsg("price tracking bot을 시작합니다.")
  #global E_MODE
  #time.strftime("%H:%M:%S")
  while True:
      hourT = time.strftime("%H")
      minT = int(time.strftime("%M"))
      secT = int(time.strftime("%S"))
      #print minT + " : " +  secT
      sleep(1) # every sec
      SendStatusRegularlly()
  
      if E_MODE == 0: # TRACKING mode
          #if hourT >= 6 and hourT < 18:
              if (minT >= 50 or minT < 5) or (minT >= 20 and minT < 35):
                  if secT == 15 or secT == 45:
                      TryToParse("REAL")
      #elif E_MODE == 1: # TRADING mode
  
  
  #browser.quit()
  #print "총 " +str(len(arrPriceList)) +" 개" 
  # for coin in arrPriceList:
  #     print ">>> "+coin
  #print table_contents.tbody.findAll('tr')
  
  #print soup
  
  