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 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
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
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
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)
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)
def get_date_from_string(self, st): dt = get_date_or_none_from_string(st[0:10]) return dt