Example #1
0
def add_untracked_transactions():
    trans_path = os.path.join(settings.MEDIA_ROOT,
                              'untracked_shares_transactions')
    if os.path.exists(trans_path):
        trans_file = os.path.join(trans_path, 'transactions.csv')
        if os.path.exists(trans_file):
            with open(trans_file, 'r') as csv_file:
                csv_reader = csv.DictReader(csv_file)
                for row in csv_reader:
                    if row['trading_symbol'] != 'IGNORETRANS':
                        print(row)
                        #user,exchange,trade_date,trading_symbol,segment,trade_type,quantity,price,order_id,notes,broker
                        try:
                            exchange = row['exchange']
                            symbol = row['trading_symbol']
                            trans_type = row['trade_type']
                            trans_type = 'Buy' if trans_type.lower(
                            ) == 'buy' else 'Sell'
                            user = int(row['user'])
                            user_name = get_user_name_from_id(user)
                            if not user_name:
                                raise Exception('User %s doesnt exist' %
                                                str(user))
                            broker = row['broker']
                            notes = row['notes']
                            date = get_date_or_none_from_string(
                                row['trade_date'], format='%d/%m/%Y')
                            quantity = get_float_or_zero_from_string(
                                row['quantity'])
                            price = get_float_or_zero_from_string(row['price'])
                            if row['order_id'] and row['order_id'] != '':
                                if not notes or notes == '':
                                    notes = 'order id:' + row['order_id']
                                else:
                                    notes = notes + '. order id:' + row[
                                        'order_id']

                            if exchange == 'NSE' or exchange == 'BSE':
                                conversion_rate = 1
                            elif exchange == 'NASDAQ' or exchange == 'NYSE':
                                conversion_rate = get_conversion_rate(
                                    'USD', 'INR', date)
                            else:
                                raise Exception('unsupported exchange %s' %
                                                exchange)
                            insert_trans_entry(exchange, symbol, user,
                                               trans_type, quantity, price,
                                               date, notes, broker,
                                               conversion_rate)
                        except Exception as ex:
                            print(f'Exception adding transaction {ex}')
        else:
            print(f'untracked shares transactions file not present')
    else:
        print(f'untracked shares transactions folder not present')
    def get_index_val(self):
        get_response = None
        for _ in range(3):
            try:
                urlData = "https://api.nasdaq.com/api/quote/" + self.stock + "/info?assetclass=index"
                print("accessing " + urlData)
                headers = {
                    'Accept': 'application/json, text/plain, */*',
                    'DNT': "1",
                    'Origin': 'https://www.nasdaq.com/',
                    'Sec-Fetch-Mode': 'cors',
                    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0)'
                }
                get_response = requests.get(urlData,
                                            headers=headers,
                                            timeout=10)
                print(get_response)
                if get_response and get_response.status_code == 200:
                    break
            except Exception as ex:
                print(f'exception when accessing {urlData}: {ex}')
                time.sleep(3)
        if not get_response or get_response.status_code != 200:
            return None
        #print(get_response.content)
        json_data = get_response.json()
        data = dict()
        if 'data' in json_data:
            data['symbol'] = json_data['data']['symbol']
            data['name'] = json_data['data']['companyName']
            data['lastPrice'] = json_data['data']['primaryData'][
                'lastSalePrice']
            data['change'] = get_float_or_zero_from_string(
                json_data['data']['primaryData']['netChange'])
            data['pChange'] = json_data['data']['primaryData'][
                'percentageChange']
            data['pChange'] = get_float_or_zero_from_string(
                data['pChange'].replace('%', ''))
            date_str = json_data['data']['primaryData']['lastTradeTimestamp']
            date_str = date_str.replace('DATA AS OF', '')
            date_str = date_str.replace(' ET', '')
            date_obj = parse(date_str)
            from_zone = pytz.timezone('America/Cancun')
            date_obj = date_obj.replace(tzinfo=from_zone)
            to_zone = tz.tzutc()
            data['last_updated'] = date_obj.astimezone(to_zone).strftime(
                "%Y-%m-%d %H:%M:%S")

        return data
    def get_historical_value(self, start, end):
        get_response = None
        for _ in range(3):
            try:
                if self.etf:
                    urlData = "http://www.nasdaq.com/api/v1/historical/" + self.stock + "/etf/"
                else:
                    urlData = "http://www.nasdaq.com/api/v1/historical/" + self.stock + "/stocks/"
                urlData += start.strftime('%Y-%m-%d') + '/'
                urlData += end.strftime('%Y-%m-%d')
                print("accessing " + urlData)
                headers = {
                    'Content-Type': "application/x-www-form-urlencoded",
                    'User-Agent': "PostmanRuntime/7.13.0",
                    'Accept': "*/*",
                    'Cache-Control': "no-cache",
                    'Host': "www.nasdaq.com",
                    'accept-encoding': "gzip, deflate",
                    'content-length': "166",
                    'Connection': "close",
                    'cache-control': "no-cache"
                }
                get_response = requests.get(urlData,
                                            headers=headers,
                                            timeout=10)
                print(get_response)
                if get_response and get_response.status_code == 200:
                    break
            except Exception as ex:
                print(f'exception when accessing {urlData}: {ex}')
                time.sleep(3)
        if not get_response or get_response.status_code != 200:
            ret = self.get_alternate_historical_value(start, end)
            return ret
        try:
            text = get_response.iter_lines()
            reader = csv.DictReader(codecs.iterdecode(text, 'utf-8'),
                                    delimiter=',')
            response = dict()
            for row in reader:
                date = None
                latest_val = None
                for k, v in row.items():
                    if "Date" in k:
                        date = datetime.datetime.strptime(v, "%m/%d/%Y").date()
                    elif "Close/Last" in k:
                        latest_val = v.strip()

                if date and latest_val:
                    response[date] = get_float_or_zero_from_string(
                        latest_val.replace('$', ''))
            print('done with request')
            print(response)
            return response
        except Exception as ex:
            print(
                f'exception while getting historical value.  Trying alternate channel for {row} {self.stock} {ex}'
            )
            ret = self.get_alternate_historical_value(start, end)
            return ret
def pull_zerodha(userid, passwd, pin):
    chrome_options = webdriver.ChromeOptions()
    #chrome_options.add_argument("--headless")
    url = "https://coin.zerodha.com/login"
    driver = webdriver.Chrome(executable_path=get_path_to_chrome_driver(),
                              chrome_options=chrome_options)
    driver.get(url)
    time.sleep(5)
    print(driver.current_url)
    try:
        user_id_elem = driver.find_element_by_id('userid')
        user_id_elem.send_keys(userid)
        passwd_elem = driver.find_element_by_id('password')
        passwd_elem.send_keys(passwd)
        submit_button = driver.find_element_by_xpath(
            '//button[text()="Login "]')
        submit_button.click()
        time.sleep(3)
        pin_element = driver.find_element_by_id('pin')
        pin_element.send_keys(pin)
        submit_button = driver.find_element_by_xpath(
            '//button[text()="Continue "]')
        submit_button.click()
        time.sleep(5)
        mf_url = "https://coin.zerodha.com/dashboard/mf/"
        driver.get(mf_url)

        time.sleep(5)
        transactions = dict()
        divs = driver.find_elements_by_xpath(
            "//div[@class='fund-name text-16']")
        for div in divs:
            folio = None
            isin = None
            div.click()
            time.sleep(5)
            header = driver.find_element_by_xpath(
                '//div[@class="fund-header"]')
            for anchor in header.find_elements_by_tag_name("a"):
                print(
                    f'text: {anchor.text} href: {anchor.get_attribute("href")}'
                )
                isin = anchor.get_attribute("href").replace(
                    'https://coin.zerodha.com/mf/fund/', '')

            footer = driver.find_element_by_xpath(
                '//div[@class="three columns left"]')
            for span in footer.find_elements_by_tag_name("span"):
                if 'folio' in span.text.lower():
                    pass
                else:
                    folio = span.text
                    if folio not in transactions:
                        transactions[folio] = dict()
                    if isin not in transactions[folio]:
                        transactions[folio][isin] = list()
            trans = driver.find_element_by_xpath(
                '//div[text()="View transactions"]')
            trans.click()
            time.sleep(5)
            trans_tbl = driver.find_element_by_xpath(
                "//table[@class='holdings-breakdown__table']")
            for row in trans_tbl.find_elements_by_tag_name("tr"):
                #print(row)
                entry = dict()
                found = False
                for index, col in enumerate(
                        row.find_elements_by_tag_name("td")):
                    found = True
                    if index == 0:
                        dt = col.text.replace('nd',
                                              '').replace('st', '').replace(
                                                  'rd', '').replace('th', '')
                        entry['date'] = get_date_or_none_from_string(
                            dt, '%d %b %Y')
                    elif index == 2:
                        entry['amount'] = get_float_or_zero_from_string(
                            col.text.replace(',', ''))
                        if entry['amount'] < 0:
                            entry['amount'] = -1 * entry['amount']
                            entry['trade_type'] = 'sell'
                        else:
                            entry['trade_type'] = 'buy'
                    elif index == 3:
                        entry['nav'] = get_float_or_zero_from_string(
                            col.text.replace(',', ''))
                    elif index == 4:
                        entry['units'] = get_float_or_zero_from_string(
                            col.text.replace(',', ''))
                        if entry['units'] < 0:
                            entry['units'] = -1 * entry['units']
                            entry['trade_type'] = 'sell'
                        else:
                            entry['trade_type'] = 'buy'
                if found:
                    print(f'folio {folio} entry {entry} isin {isin}')
                    if isin and folio:
                        transactions[folio][isin].append(entry)

            sp = driver.find_element_by_xpath(
                "//span[@class='icon feather-x']")
            sp.click()
            time.sleep(3)
            sp = driver.find_element_by_xpath(
                "//span[@class='icon feather-chevron-up']")
            sp.click()
            time.sleep(3)

        userid_elem = driver.find_element_by_xpath(
            "//span[@class='user-name']")
        userid_elem.click()
        time.sleep(5)
        logout_elem = driver.find_element_by_xpath(
            "//a[text()[contains(.,'Logout')]]")
        logout_elem.click()
        driver.close()
        time.sleep(5)
        f = write_trans_to_csv_file(transactions)
        return [f]

    except Exception as ex:
        print(f'exception getting transactions from coin/zerodha {ex}')
        driver.close()
def calculator(request):
    template = 'calculator/calculator.html'
    context = {}
    fd_prin = 0
    fd_time = 0
    fd_roi = 0
    fd_final_val = 0
    fd_compound = 'fd_compound_yr'
    rd_prin = 0
    rd_time = 0
    rd_roi = 0
    rd_final_val = 0
    rd_compound = 'rd_compound_yr'
    if request.method == 'POST':
        fd_prin = get_float_or_zero_from_string(request.POST['fd_prin'])
        fd_time = get_float_or_zero_from_string(request.POST['fd_time'])
        fd_roi = get_float_or_zero_from_string(request.POST['fd_int'])
        fd_final_val = get_float_or_zero_from_string(
            request.POST['fd_final_val'])
        fd_compound = request.POST.get('fdcompounding', 'fd_compound_yr')
        rd_prin = get_float_or_zero_from_string(request.POST['rd_prin'])
        rd_time = get_float_or_zero_from_string(request.POST['rd_time'])
        rd_roi = get_float_or_zero_from_string(request.POST['rd_int'])
        rd_final_val = get_float_or_zero_from_string(
            request.POST['rd_final_val'])
        rd_compound = request.POST.get('rdcompounding', 'rd_compound_yr')
        print(request.POST)
        if "calculatefdprin" in request.POST:
            fd_prin = round(
                float(
                    fd_calc_prin_val(fd_final_val, fd_time, fd_roi,
                                     fd_compound)), 2)

        if "calculatefdtime" in request.POST:
            fd_time = fd_calc_time(fd_prin, fd_final_val, fd_roi, fd_compound)

        if "calculatefdint" in request.POST:
            fd_roi = round(
                float(fd_calc_roi(fd_prin, fd_time, fd_final_val,
                                  fd_compound)), 2)

        if "calculatefdfinalval" in request.POST:
            fd_final_val = round(
                float(fd_calc_final_val(fd_prin, fd_time, fd_roi,
                                        fd_compound)), 2)

        if "calculaterdfinalval" in request.POST:
            rd_final_val = round(
                float(rd_calc_final_val(rd_prin, rd_time, rd_roi,
                                        rd_compound)), 2)

    context = {
        'fd_prin': fd_prin,
        'fd_time': fd_time,
        'fd_int': fd_roi,
        'fd_final_val': fd_final_val,
        'rd_final_val': rd_final_val,
        'fd_compound': fd_compound,
        'rd_prin': rd_prin,
        'rd_time': rd_time,
        'rd_int': rd_roi,
        'rd_compound': rd_compound,
        'curr_module_id': 'id_calculator_module'
    }
    print('context', context)
    #if request.is_ajax():
    #    print('request is ajax')
    #    return HttpResponseRedirect('/calculator/',context)
    #else:
    #    print('request is not ajax')
    return render(request, template, context=context)
    def get_latest_val(self):
        get_response = None
        for _ in range(3):
            try:
                urlData = "https://api.nasdaq.com/api/quote/" + self.stock + "/info?assetclass=stocks"
                print("accessing " + urlData)
                '''
                headers = {
                    'Content-Type': "application/x-www-form-urlencoded",
                    'User-Agent': "PostmanRuntime/7.13.0",
                    'Accept': "*/*",
                    'Cache-Control': "no-cache",
                    'Host': "www.nasdaq.com",
                    'accept-encoding': "gzip, deflate",
                    'content-length': "166",
                    'Connection': "close",
                    'cache-control': "no-cache"
                }
                '''
                headers = {
                    'Accept': 'application/json, text/plain, */*',
                    'DNT': "1",
                    'Origin': 'https://www.nasdaq.com/',
                    'Sec-Fetch-Mode': 'cors',
                    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0)'
                }
                get_response = requests.get(urlData,
                                            headers=headers,
                                            timeout=10)
                #print(get_response)
                if get_response and get_response.status_code == 200:
                    break
            except Exception as ex:
                print(f'exception when accessing {urlData}: {ex}')
                time.sleep(3)
        if not get_response or get_response.status_code != 200:
            print(get_response)
            return None
        json_data = get_response.json()
        #print(json_data)
        data = dict()
        if 'data' in json_data:
            if not json_data['data']:
                print(f'returning none since json_data[data] is None')
                return None
            if 'secondaryData' in json_data['data'] and json_data['data'][
                    'secondaryData']:
                timestamp = json_data['data']['secondaryData'][
                    'lastTradeTimestamp']
                if 'ON' in timestamp:
                    pos = timestamp.find('ON')
                    timestamp = timestamp[pos + 3:]
                    #print(timestamp)
                    date = datetime.datetime.strptime(timestamp,
                                                      "%b %d, %Y").date()
                    data[date] = json_data['data']['secondaryData'][
                        'lastSalePrice']

            try:
                if 'primaryData' in json_data['data'] and json_data['data'][
                        'primaryData']:
                    timestamp = json_data['data']['primaryData'][
                        'lastTradeTimestamp']
                    if 'ON' in timestamp:
                        pos = timestamp.find('ON')
                        timestamp = timestamp[pos + 3:]
                    if 'OF' in timestamp:
                        pos = timestamp.find('OF')
                        timestamp = timestamp[pos + 3:]
                        timestamp = timestamp.replace(' ET', '')
                        timestamp = timestamp.replace(' - AFTER HOURS', '')
                    #print(timestamp)
                    #date = datetime.datetime.strptime(timestamp, "%b %d, %Y").date()
                    date_obj = parse(timestamp).date()
                    latest_val = json_data['data']['primaryData'][
                        'lastSalePrice']
                    data[date_obj] = get_float_or_zero_from_string(
                        latest_val.replace('$', ''))
            except Exception as ex:
                print(f'error getting value for {self.stock}: {ex}')
        #print('done with request')
        #print(data)
        print(f'returning {data} from get_latest_val')
        return data
 def get_all_index(self):
     get_response = None
     for _ in range(3):
         try:
             urlData = "https://api.nasdaq.com/api/quote/watchlist?symbol=comp%7cindex&symbol=ndx%7cindex&symbol=indu%7cindex&symbol=rui%7cindex&symbol=omxs30%7cindex&symbol=omxn40%7cindex&symbol=omxb10%7cindex&symbol=cac40%7cindex&symbol=nik%25sl%25o%7cindex"
             print("accessing " + urlData)
             headers = {
                 'Accept': 'application/json, text/plain, */*',
                 'DNT': "1",
                 'Origin': 'https://www.nasdaq.com/',
                 'Sec-Fetch-Mode': 'cors',
                 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0)'
             }
             get_response = requests.get(urlData,
                                         headers=headers,
                                         timeout=10)
             #print(get_response)
             if get_response and get_response.status_code == 200:
                 break
         except Exception as ex:
             print(f'exception when accessing {urlData}: {ex}')
             time.sleep(3)
     if not get_response or get_response.status_code != 200:
         return None
     #print(get_response.content)
     json_data = get_response.json()
     #print(f"json_data {json_data}")
     data = dict()
     if 'data' in json_data:
         for ind in json_data['data']:
             try:
                 #print(f"ind {ind}")
                 symbol = ind['symbol']
                 data[symbol] = dict()
                 data[symbol]['name'] = ind['companyName']
                 data[symbol]['lastPrice'] = ind['lastSalePrice']
                 data[symbol]['change'] = get_float_or_zero_from_string(
                     ind['netChange'])
                 data[symbol]['pChange'] = ind['percentageChange']
                 if data[symbol]['pChange']:
                     data[symbol][
                         'pChange'] = get_float_or_zero_from_string(
                             data[symbol]['pChange'].replace('%', ''))
                 try:
                     date_str = ind['lastTradeTimestamp']
                     if 'Market Closed' not in date_str:
                         if date_str.startswith('DATA AS OF'):
                             date_str = date_str.replace('DATA AS OF', '')
                         elif date_str.startswith('AS OF'):
                             date_str = date_str.replace('AS OF', '')
                         if date_str.endswith('CET'):
                             date_str = date_str.replace(' CET', '')
                             date_obj = parse(date_str)
                             from_zone = tz.gettz('CET')
                             date_obj = date_obj.replace(tzinfo=from_zone)
                             to_zone = tz.tzutc()
                             data[symbol][
                                 'last_updated'] = date_obj.astimezone(
                                     to_zone
                                 )  #.strftime("%Y-%m-%d %H:%M:%S")
                         else:
                             date_str = date_str.replace(' ET', '')
                             date_obj = parse(date_str)
                             from_zone = tz.gettz('America/Cancun')
                             date_obj = date_obj.replace(tzinfo=from_zone)
                             to_zone = tz.tzutc()
                             data[symbol][
                                 'last_updated'] = date_obj.astimezone(
                                     to_zone
                                 )  #.strftime("%Y-%m-%d %H:%M:%S")
                     else:
                         data[symbol]['last_updated'] = None
                 except Exception as ex:
                     print("exception converting timestamp")
                     print(ex)
                     data[symbol]['last_updated'] = timezone.now()
             except Exception as ex:
                 print(f'Exception getting details {ex}: {ind}')
     return data
def pe_view(request):
    template = 'markets/pe_view.html'
    if request.method == 'POST':
        display_type = request.POST['pe_type']
    else:
        display_type = 'pe_avg'
    pref_obj = Preferences.get_solo()
    sel_indexes = list()
    if pref_obj.indexes_to_scroll:
        for index in pref_obj.indexes_to_scroll.split('|'):
            sel_indexes.append(index)
    pe_vals = dict()
    pb_vals = dict()
    for index in sel_indexes:
        vals = PEMonthy.objects.filter(index_name=index).order_by(
            'year', 'month')
        if vals and len(vals) > 0:
            if not index in pe_vals:
                pe_vals[index] = list()
            for val in vals:
                #if not val.year in pe_vals[index]:
                #    pe_vals[index][val.year] = [0] * 12
                dt = str(val.year) + '/' + str(val.month)
                if display_type == 'pe_min':
                    pe_vals[index].append({
                        'x':
                        dt,
                        'y':
                        get_float_or_zero_from_string(val.pe_min)
                    })
                elif display_type == 'pe_max':
                    pe_vals[index].append({
                        'x':
                        dt,
                        'y':
                        get_float_or_zero_from_string(val.pe_max)
                    })
                else:
                    pe_vals[index].append({
                        'x':
                        dt,
                        'y':
                        get_float_or_zero_from_string(val.pe_avg)
                    })

        vals = PBMonthy.objects.filter(index_name=index).order_by(
            'year', 'month')
        if vals and len(vals) > 0:
            if not index in pb_vals:
                pb_vals[index] = list()
            for val in vals:
                #if not val.year in pb_vals[index]:
                #    pb_vals[index][val.year] = [0] * 12
                dt = str(val.year) + '/' + str(val.month)
                if display_type == 'pb_min':
                    pb_vals[index].append({
                        'x':
                        dt,
                        'y':
                        get_float_or_zero_from_string(val.pb_min)
                    })
                elif display_type == 'pb_max':
                    pb_vals[index].append({
                        'x':
                        dt,
                        'y':
                        get_float_or_zero_from_string(val.pb_max)
                    })
                else:
                    pb_vals[index].append({
                        'x':
                        dt,
                        'y':
                        get_float_or_zero_from_string(val.pb_avg)
                    })

    context = {}
    if len(pe_vals.keys()) > 0:
        context['pe_vals'] = pe_vals
    if len(pb_vals.keys()) > 0:
        context['pb_vals'] = pb_vals
    context['curr_module_id'] = 'id_markets_module'
    print(context)
    return render(request, template, context)