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')
Example #2
0
    def fetch_ticker_news(self):
        if not self.soup:
            self.fetch_tiker_page()
        if not self.soup:
            print(f'failed to retrieve page')
            return
        ret = list()
        try:
            news_section = self.soup.find("div", {"id": "news"})
            #print(f'news_section {news_section}')
            anchors = news_section.findChildren(['a'])
            #print(f'anchors {anchors}')
            for anchor in anchors:
                #print(f'anchor {anchor}')
                #print(f"link: {anchor['href']} text: {anchor.text}")
                if anchor.text and anchor.text != '':
                    #print(anchor.parent)
                    spans = anchor.parent.findChildren(['span'])
                    for span in spans:
                        #print(f"{span.text}: {anchor['href']} text: {anchor.text}")
                        n = dict()
                        #'Nov 03 2020
                        n['date'] = get_date_or_none_from_string(
                            span.text[0:11], format='%b %d %Y')
                        n['link'] = anchor['href']
                        n['text'] = anchor.text
                        ret.append(n)
            return ret
            #print(self.soup)
            #self.more_anno_link = PREFIX_URL + str(self.soup.find("div", attrs={"class":"PT5 gL_11", "align":"right"}).find("a")["href"] ) # class name extracted after looking at the document
            #self.more_news_link = PREFIX_URL + str(self.soup.find("div", attrs={"class":"PT5 gL_11 FR"}).find("a")["href"])

        except requests.ConnectionError as ce:
            print(
                "There is a network problem (DNS Failure, refused connectionn etc.). Error : "
                + str(ce))
            raise Exception

        except requests.Timeout as te:
            print("Request timed out. Error : " + str(te))
            raise Exception

        except requests.TooManyRedirects as tmre:
            print(
                "The request exceeded the maximum no. of redirections. Error : "
                + str(tmre))
            raise Exception

        except requests.exceptions.RequestException as oe:
            print("Any type of request related error : " + str(oe))
            raise Exception
Example #3
0
def add_transactions_sbi_ssy(ssy_acc_num, transactions):
    for trans in transactions:
        date_obj = get_date_or_none_from_string(trans['date'], '%d-%b-%Y')
        if trans['debit'] > 0:
            entry = SsyEntry.DEBIT
            amount = trans['debit']
        else:
            entry = SsyEntry.CREDIT
            amount = trans['credit']
        if 'CREDIT INTEREST' in trans['description']:
            interest_comp = True
        else:
            interest_comp = False
        insert_ssy_trans_entry(ssy_acc_num, date_obj, entry, amount,trans['description'], '', interest_comp)
def create_epf(request):
    template_name = 'epfs/epf_create.html'
    if request.method == 'POST':
        print(request.POST)
        number = request.POST['number']
        end_date = get_date_or_none_from_string(request.POST['end_date'])
        start_date = get_date_or_none_from_string(request.POST['start_date'])
        company = request.POST['company']
        notes = request.POST['notes']
        user = request.POST['user']
        goal = request.POST.get('goal', '')
        uan = request.POST['uan']
        eps = request.POST['eps']
        if goal != '':
            goal_id = Decimal(goal)
        else:
            goal_id = None
        try:
            Epf.objects.create(number=number,
                               end_date=end_date,
                               start_date=start_date,
                               company=company,
                               user=user,
                               goal=goal_id,
                               notes=notes,
                               uan=uan,
                               eps=eps)
        except IntegrityError:
            print('EPF already exists')
    users = get_all_users()
    context = {
        'users': users,
        'operation': 'Create EPF',
        'curr_module_id': 'id_epf_module'
    }
    return render(request, template_name, context)
def add_user(request):
    template = 'users/add_user.html'
    if request.method == 'POST':
        name = request.POST['name']
        short_name = request.POST['short_name']
        dob = get_date_or_none_from_string(request.POST['dob'])
        email = request.POST['email']
        notes = request.POST['notes']
        User.objects.create(name=name,
                            dob=dob,
                            notes=notes,
                            email=email,
                            short_name=short_name)
    context = {'curr_module_id': 'id_user_module'}
    return render(request, template, context=context)
def get_historical_price(dt, buy_type, purity):
    st_dt = dt+relativedelta(days=-5)
    hgp = HistoricalGoldPrice.objects.filter(purity=purity, buy_type=buy_type, date__lte=dt, date__gte=st_dt).order_by('-date')
    if len(hgp) > 0:
        return float(hgp[0].price)
    else:
        print(f'no historical price for gold found in db for buy_type:{buy_type} purity:{purity} between {st_dt} and {dt}')

    url = f'https://raw.githubusercontent.com/krishnakuruvadi/portfoliomanager-data/main/India/gold/{dt.year}.json'
    print(f'fetching from url {url}')
    r = requests.get(url, timeout=15)
    val = None
    if r.status_code == 200:
        print(r.text)
        print(r.json())
        for dt_str, entry in r.json()['prices'].items():
            tempdt = get_date_or_none_from_string(dt_str, '%d/%m/%Y')
            if '24K' in entry:
                try:
                    HistoricalGoldPrice.objects.create(date=tempdt, purity='24K', buy_type='Physical', price=entry['24K'])
                except IntegrityError:
                    pass
                except Exception as ex:
                    print(f'{ex} when adding to HistoricalGoldPrice')
            if '22K' in entry:
                try:
                    HistoricalGoldPrice.objects.create(date=tempdt, purity='22K', buy_type='Physical', price=entry['22K'])
                except IntegrityError:
                    pass
                except Exception as ex:
                    print(f'{ex} when adding to HistoricalGoldPrice')
            if 'digital' in entry:
                try:
                    HistoricalGoldPrice.objects.create(date=tempdt, purity='24K', buy_type='Digital', price=entry['digital'])
                except IntegrityError:
                    pass
                except Exception as ex:
                    print(f'{ex} when adding to HistoricalGoldPrice')
            if tempdt and tempdt == dt:
                if buy_type == 'Digital':
                    val = entry.get('digital', None)
                else:
                    val = entry.get(purity, None)
    else:
        print(f'failed to get url {url} {r.status_code}')
    return val
Example #7
0
 def fetch_splits(self):
     splits = list()
     if not self.soup:
         self.fetch_tiker_page()
     if not self.soup:
         print(f'failed to get ticker page')
         return
     url_splits = self.ticker_url.split('/')
     url_part_1 = url_splits[len(url_splits) - 2]
     url_part_2 = url_splits[len(url_splits) - 1]
     #https://www.moneycontrol.com/india/stockpricequote/banks-private-sector/yesbank/YB
     splits_url = f'https://www.moneycontrol.com/company-facts/{url_part_1}/splits/{url_part_2}#{url_part_2}'
     r = requests.get(splits_url, timeout=15)
     if r.status_code == 200:
         print(f'found page')
         self.soup = bs4.BeautifulSoup(r.content, 'html.parser')
         table = self.soup.find("table", {"class": "mctable1"})
         tbody = table.find("tbody")
         rows = tbody.findChildren("tr")
         ret_dict = dict()
         for row in rows:
             print(f'row {row}')
             cols = row.findChildren("td")
             if cols and len(cols) >= 3:
                 ret_dict[cols[0]] = {
                     'old_fv':
                     int(cols[1].text),
                     'new_fv':
                     int(cols[2].text),
                     'effective_date':
                     get_date_or_none_from_string(cols[3].text, '%d-%m-%Y')
                 }
         for _, v in ret_dict.items():
             splits.append({
                 'old_fv': v['old_fv'],
                 'new_fv': v['new_fv'],
                 'effective_date': v['effective_date']
             })
         return splits
     elif r.status_code == 404:
         print(f"Page not found url: {r.url}")
     else:
         print(
             f"A different status code received : {str(r.status_code)} for url: {r.url}"
         )
def add_sell_trans(request, id):
    template = "espps/add_sell_transaction.html"
    context = dict()
    context['espp_id'] = id
    context['curr_module_id'] = 'id_espp_module'
    try:
        espp_obj = Espp.objects.get(id=id)
        if request.method == 'POST':
            trans_date = get_date_or_none_from_string(
                request.POST['trans_date'])
            price = get_float_or_none_from_string(request.POST['price'])
            units = get_float_or_none_from_string(request.POST['units'])
            conversion_rate = get_float_or_none_from_string(
                request.POST['conversion_rate'])
            trans_price = get_float_or_none_from_string(
                request.POST['trans_price'])
            realised_gain = trans_price - (
                float(espp_obj.purchase_price) *
                float(espp_obj.purchase_conversion_rate) * float(units))
            notes = request.POST['notes']
            try:
                EsppSellTransactions.objects.create(
                    espp=espp_obj,
                    trans_date=trans_date,
                    price=price,
                    units=units,
                    conversion_rate=conversion_rate,
                    trans_price=trans_price,
                    realised_gain=realised_gain,
                    notes=notes)
                update_latest_vals(espp_obj)
            except IntegrityError:
                print('transaction already exists')
    except Espp.DoesNotExist:
        print(f"ESPP with id {id} does not exist")
        return HttpResponseRedirect(reverse('espps:espp-list'))
    return render(request, template, context)
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 pull_category_returns():
    url = decode(
        b'\x03\x11\r\x07\x1cHKD\x07\n\x12\x06\x1c\x00\x02\x04W\x1a\x00\x00\n\x02\x0b\x1e\x04\x1b\x13\x16E\x0c\x17X\t\x07\n\x0f\x16V\x14\x0e\x06\x01\x0c\n\x0b\x0e\x1f\x17\x16\r\n\x0b\x1a\x0e\x1c\x07\x0eK\x18\x04\x1f\n'
    )
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument("--headless")
    driver = webdriver.Chrome(executable_path=get_path_to_chrome_driver(),
                              options=chrome_options)
    driver.get(url)
    timeout = 30

    opt_element_id = decode(
        b"\x08\x11\x15G_-'\x04\x0b\r\x12\x01\x064\x07\x04\x1a\x12'\x1d\x08\x0f\x00\x0bF0\x16\x08;\x00\x0b\x1e\x00\x16"
    )
    WebDriverWait(driver, timeout).until(
        EC.visibility_of_element_located((By.ID, opt_element_id)))
    ret = dict()
    val_opts = [
        '1D', '1W', '1M', '3M', '6M', '1Y', '2Y', '3Y', '4Y', '5Y', '6Y', '7Y',
        '8Y', '9Y', '10Y', 'YTD', 'Inception'
    ]
    as_on = None
    for i, opt in enumerate([
            '1 Day', '1 Week', '1 Month', '3 Months', '6 Months', '1 Year',
            '2 Years', '3 Years', '4 Years', '5 Years', '6 Years', '7 Years',
            '8 Years', '9 Years', '10 Years', 'YTD', 'Since Inception'
    ]):
        for j in range(3):
            try:
                sel_choice = driver.find_element_by_xpath(
                    "//select/option[@value='" + opt + "']")
                sel_choice.click()
                time.sleep(5)
                WebDriverWait(driver, timeout).until(
                    EC.visibility_of_element_located((By.ID, opt_element_id)))
                rows = driver.find_elements_by_xpath("//table/tbody/tr")
                if not as_on:
                    try:
                        span_id = driver.find_element_by_id(
                            'ctl00_ContentPlaceHolder1_lblDate')
                        as_on = get_date_or_none_from_string(
                            span_id.text.replace('As on ', ''), '%Y-%m-%d')
                    except NoSuchElementException:
                        print(
                            f'couldnt find element by id ctl00_ContentPlaceHolder1_lblDate'
                        )

                for row in rows:
                    #print(row.text)
                    cols = row.find_elements_by_tag_name("td")
                    '''
                    for col in cols:
                        print('col text', col.text)
                        if 'As on' in col.text:
                            as_on = col.text
                    '''
                    if len(cols) == 4 and 'h3' in cols[0].get_attribute(
                            'innerHTML'):
                        #print('------------------------------------------------------------------')
                        #print(cols[0].text,'\t', cols[1].text, '\t', cols[2].text, '\t', cols[3].text)
                        #print('------------------------------------------------------------------')
                        if cols[0].text not in ret.keys():
                            ret[cols[0].text] = dict()
                        ret[cols[0].text][val_opts[i]] = dict()
                        ret[cols[0].text][val_opts[i]]['avg'] = cols[1].text
                        ret[cols[0].text][val_opts[i]]['top'] = cols[2].text
                        ret[cols[0].text][val_opts[i]]['bottom'] = cols[3].text
                break
            except Exception as ex:
                print(
                    f'attempt {j} exception {ex} when retrieving returns for {opt}'
                )
    ret['as_on'] = as_on
    driver.close()
    driver.quit()
    return ret
Example #11
0
def show_contributions(request, id, year=None):
    template = 'epfs/epf_show_contrib.html'
    epf_obj = get_object_or_404(Epf, id=id)
    epf_start_year = epf_obj.start_date.year
    if epf_obj.start_date.month < 4:
        epf_start_year -= 1
    this_year = datetime.date.today().year if datetime.date.today(
    ).month < 4 else datetime.date.today().year + 1

    print(epf_start_year)
    if not year:
        year = epf_start_year
    else:
        year = epf_start_year + int(year)
        if year > this_year:
            year = this_year
    start_date = str(year) + "-04-01"
    end_date = str(year + 1) + "-03-31"
    fy = str(year) + '-' + str(year + 1)[2:]
    # inclusive. SQL equivalent: SELECT ... WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';
    contribs = EpfEntry.objects.filter(
        epf_id=epf_obj, trans_date__range=[start_date, end_date])
    fy_trans = list()
    for contrib in contribs:
        entry = dict()
        entry['period'] = contrib.trans_date
        entry['em_contrib'] = contrib.employee_contribution
        entry['er_contrib'] = contrib.employer_contribution
        entry['interest'] = contrib.interest_contribution
        entry['withdrawl'] = contrib.withdrawl
        fy_trans.append(entry)
    summ = get_summary_for_range(epf_obj,
                                 get_date_or_none_from_string(start_date),
                                 get_date_or_none_from_string(end_date))
    context = {
        'fy_trans': fy_trans,
        'object': {
            'number': epf_obj.number,
            'id': epf_obj.id,
            'company': epf_obj.company,
            'fy': fy
        },
        'start_amount': summ['start_amt'],
        'end_amount': summ['end_amount'],
        'employee_contribution': summ['employee_contrib'],
        'employer_contribution': summ['employer_contrib'],
        'interest_contribution': summ['interest_contrib'],
        'curr_module_id': 'id_epf_module'
    }
    if epf_start_year < year:
        context['prev_link'] = '../transactions/' + str(year - epf_start_year -
                                                        1)
    else:
        context['prev_link'] = 'disabled'
    context['curr_link'] = '../transactions/' + str(year - epf_start_year)
    if year < this_year - 1:
        context['next_link'] = '../transactions/' + str(year - epf_start_year +
                                                        1)
    else:
        context['next_link'] = 'disabled'
    return render(request, template, context)
Example #12
0
def update_epf(request, id):
    template_name = 'epfs/epf_create.html'

    try:
        epf_obj = Epf.objects.get(id=id)
        if request.method == 'POST':
            print(request.POST)
            number = request.POST['number']
            end_date = get_date_or_none_from_string(request.POST['end_date'])
            start_date = get_date_or_none_from_string(
                request.POST['start_date'])
            company = request.POST['company']
            notes = request.POST['notes']
            user = request.POST['user']
            goal = request.POST.get('goal', '')
            uan = request.POST['uan']
            eps = request.POST['eps']
            if goal != '':
                goal_id = Decimal(goal)
            else:
                goal_id = None
            epf_obj.number = number
            epf_obj.end_date = end_date
            epf_obj.start_date = start_date
            epf_obj.company = company
            epf_obj.user = user
            epf_obj.goal = goal_id
            epf_obj.notes = notes
            epf_obj.uan = uan
            epf_obj.eps = eps
            epf_obj.save()
            return HttpResponseRedirect("../")
        else:
            users = get_all_users()
            goals = get_goal_id_name_mapping_for_user(epf_obj.user)
            context = {
                'goals':
                goals,
                'users':
                users,
                'user':
                epf_obj.user,
                'number':
                epf_obj.number,
                'start_date':
                epf_obj.start_date.strftime("%Y-%m-%d"),
                'notes':
                epf_obj.notes,
                'goal':
                epf_obj.goal,
                'end_date':
                epf_obj.end_date.strftime("%Y-%m-%d")
                if epf_obj.end_date else None,
                'operation':
                'Edit EPF',
                'company':
                epf_obj.company,
                'curr_module_id':
                'id_epf_module',
                'uan':
                epf_obj.uan if epf_obj.uan else '',
                'eps':
                epf_obj.eps if epf_obj.eps else ''
            }

    except Epf.DoesNotExist:
        return HttpResponseRedirect("../")

    return render(request, template_name, context)
Example #13
0
 def get_date_from_string(self, st):
     dt = get_date_or_none_from_string(st[0:10])
     return dt