Coverage for python3/src/rh.py: 100%
67 statements
« prev ^ index » next coverage.py v7.3.2, created at 2024-01-10 02:24 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2024-01-10 02:24 +0000
1#!../bin/python
2import robin_stocks.robinhood as r
3import csv
4import collections
5import os
6from datetime import datetime
7from dotenv import load_dotenv
8from typing import List, Optional
10class CSVParser:
12 def __init__(self):
13 pass
15 def setCSVFile(self, CSVFileName: str):
16 """
17 Set the CSV file name to be used by
18 the parser.
19 """
20 self.CSVFileName = CSVFileName
22 def setIgnoreList(self, ignoreList: Optional[List[str]]):
23 if ignoreList:
24 self.ignoreList = ignoreList
25 else:
26 self.ignoreList = []
28 def setProfile(self):
29 profile = collections.defaultdict(list)
30 with open('test.csv', 'r') as csvfile:
31 csvreader = csv.DictReader(csvfile)
32 for row in reversed(list(csvreader)):
33 symbol = row["symbol"]
34 if symbol in self.ignoreList:
35 continue
36 side = row['side']
37 tranche = {"shares": int(float(row['quantity'])),
38 "dateAcquired": row['date'],
39 "avgPrice": float(row['average_price'])}
40 match side:
41 case 'buy':
42 profile[symbol].append(tranche)
43 case 'sell':
44 while tranche["shares"] > 0:
45 profile[symbol][-1]["shares"] -= 1
46 tranche["shares"] -= 1
47 if profile[symbol][-1]["shares"] == 0:
48 profile[symbol].pop()
50 return profile
53class Tranche:
55 def __init__(self, tranche):
56 self.shares = tranche["shares"]
57 self.dateAcquired = tranche["dateAcquired"]
58 self.avgPrice = tranche["avgPrice"]
61class Stock:
63 def __init__(self, symbol):
64 self.symbol = symbol
65 self.tranches = []
67 def createTranche(self, tranche):
68 """Adds a tranche object to the running list of tranche objects."""
69 self.tranches.append(Tranche(tranche))
71 def getLongTermCapitalGainsTranche(self): # pragma: no cover
72 """
73 Prints out all stock tranches tranches
74 that are older the 365 days (one year).
75 """
76 for tranche in self.tranches:
77 if "." in tranche.dateAcquired:
78 dateFormat = "%Y-%m-%dT%H:%M:%S.%fZ"
79 else:
80 dateFormat = "%Y-%m-%dT%H:%M:%SZ"
81 dateObject = datetime.strptime(tranche.dateAcquired, dateFormat)
82 currentDate = datetime.now()
83 timeDifference = currentDate - dateObject
84 oneYear = 365
85 if timeDifference.days >= oneYear:
86 print(f"\n\tShares: {tranche.shares}\n\t",
87 f"Date Acquired: {tranche.dateAcquired}\n\t",
88 f"Avg Price: {tranche.avgPrice}",
89 sep="",
90 end="\n")
91 print("")
93 def getAllTranches(self): # pragma: no cover
94 """
95 Prints out all tranches in this stock.
96 """
97 for tranche in self.tranches:
98 print(f"\n\tShares: {tranche.shares}\n\t",
99 f"Date Acquired: {tranche.dateAcquired}\n\t",
100 f"Avg Price: {tranche.avgPrice}",
101 sep="",
102 end="\n")
105class Portfolio:
107 def __init__(self):
108 self.positions = {}
110 def createStock(self, symbol: str) -> None:
111 """
112 Creates a stock when given a symbol to identify it by
113 """
114 self.positions[symbol] = Stock(symbol)
116 def getStock(self, symbol: str) -> Stock:
117 """
118 Get a stock object given a valid symbol
119 """
120 return self.positions[symbol]
122 def setCSVObj(self, csvFile: str, ignoreList: Optional[List[str]] = None):
123 self.csvParser = CSVParser()
124 self.csvParser.setCSVFile(csvFile)
125 self.csvParser.setIgnoreList(ignoreList)
127 def getProfile(self):
128 profile = self.csvParser.setProfile()
130 for symbol, tranches in profile.items():
131 if not tranches:
132 continue
133 self.createStock(symbol)
134 stock = self.getStock(symbol)
135 for tranche in tranches:
136 stock.createTranche(tranche)
138if __name__ == "__main__": # pragma: no cover
139 load_dotenv()
140 user = os.getenv('username')
141 password = os.getenv('password')
142 mfaCode = input("enter the MFA code")
143 CSVFILE = 'test.csv'
144 IGNORELIST = ['GRPN', 'FIT', 'ATVI']
145 login = r.login(user, password, mfa_code=mfaCode)
146 r.export_completed_stock_orders(".", "test.csv")
148 portfolio = Portfolio()
149 portfolio.setCSVObj(CSVFILE, IGNORELIST)
150 portfolio.getProfile()
152 for symbol, stockObj in portfolio.positions.items():
153 print(f'\nSymbol: {symbol}')
154 stockObj.getAllTranches()