Project 3: Convergent Design
Team Contacts
Team Email: 61040-project@mit.edu
Team Members
Name | GitHub | |
---|---|---|
Henry Asa | henryasa@mit.edu | @HenryAsa |
Amir Kazeminia | amirka@mit.edu | @amirika20 |
Cal Wilson | calwilsn@mit.edu | @calwilsn |
Jonatan Fontanez | jonfon01@mit.edu | @DragonStorm25 |
Team Project Mentors
Name | |
---|---|
Ashley Granquist | ashleymg@mit.edu |
Fabrizzio Orderique | porderiq@mit.edu |
Application Summary: Sharefolio
Invest exactly like Warren Buffett without being Warren Buffett.
Sharefolio is a community-powered asset trading platform. Unlike other asset marketplaces, users are able to see other users' asset holdings and public leaderboards are used to rank users' trading/investment performance on the application. With this data made public, users can make more informed decisions on what they want to invest in depending on their peer's actions and holdings. Additionally, users can choose to Copy-Invest
other users' portfolios, meaning that all trades a copied portfolio makes are automatically reflected in all copiers' portfolios. This Copy-Investing
feature allows users to "invest exactly like Warren Buffett, without being Warren Buffett."
Important Note About Privacy
Similar to how Venmo conceals the value of each transaction but publicizes the comment associated with a given transaction, users will be able to choose whether a particular transaction will be public or private. Additionally, all specific values (for example, the amount of money a particular user invested in a certain asset) are always private. Percentage distributions may be made public (depending on the user's discretion), but specific quantities are confidential.
Functional Design
Concepts
Asset
To track the current price, history, and statistics associated with an asset or share of a company.
Portfolio[Asset]
Portfolios
are a collection of stocks that make it easy to organize, track, and manage a collection of assets.
Friend[User]
To allow for a connection between users.
Money
A medium that simplifies transactions, serves as a measure of value and stores wealth.
Leaderboard[T]
To rank users based on a defined factor that describes their performance in trading.
Article[GPT]
To inform users about the news, recent trends, or developments in the market or related topics.
NewsFeed
Presents a collection of articles to the user that are relevant to that user's interests, asset holdings, and preferences.
aiAssistant[GPT]
A tool to help users assess their assumptions with the current news and help inform their trading decisions referencing current news about the market.
Dependency Diagram
Syncs
sync purchaseStock(session: WebSession, portfolioName: String, stockName: string)
u := WebSession.getUser(session)
assert u is not None
d := Date.now()
a := Asset.purchase(stockName, d)
assert Portfolio.getOwner(portfolioName) == u.username
addToPortfolio(portfolioName, a)
sync newPortfolio(session: WebSession, portfolioName: String, out p: portfolio)
u := WebSession.getUser(session)
assert u is not None
p := createPortfolio(portfolioName, u.username)
sync copyInvest(session: WebSession, userPortfolioName: String, targetPortfolioName: String)
u1 := WebSession.getUser(session)
u2 := Portfolio.getOwner(targetPortfolioName)
assert u1 is not None and u2 is not None
assert Portfolio.isPublic(targetPortfolioName) or Friend.areFriends(u1, u2)
targetStocks := Portfolio.getStocks(targetPortfolioName)
for stock in targetStocks:
purchaseStock(session, userPortfolioName, stock.assetName)
sync getPortfolioStocks(session: WebSession, portfolioName: String, out stocks: set Asset)
u1 := WebSession.getUser(session)
u2 := Portfolio.getOwner(portfolioName)
assert u1 is not None and u2 is not None
assert Portfolio.isPublic(portfolioName) or Friend.areFriends(u1, u2)
stocks := Portfolio.getStocks(portfolioName)
sync getPortfolioBeta(session: WebSession, portfolioName: String, out beta: Number)
u1 := WebSession.getUser(session)
u2 := Portfolio.getOwner(portfolioName)
assert u1 is not None and u2 is not None
assert Portfolio.isPublic(portfolioName) or Friend.areFriends(u1, u2)
beta := Portfolio.getBeta(portfolioName)
sync getPortfolioProfit(session: WebSession, portfolioName: String, out profit: Number)
u1 := WebSession.getUser(session)
u2 := Portfolio.getOwner(portfolioName)
assert u1 is not None and u2 is not None
assert Portfolio.isPublic(portfolioName) or Friend.areFriends(u1, u2)
profit := Portfolio.getProfit(portfolioName)
sync getPortfolioRelativeProfit(session: WebSession, portfolioName: String, out relativeProfit: Number)
u1 := WebSession.getUser(session)
u2 := Portfolio.getOwner(portfolioName)
assert u1 is not None and u2 is not None
assert Portfolio.isPublic(portfolioName) or Friend.areFriends(u1, u2)
relativeProfit := Portfolio.getRelativeProfit(portfolioName)
sync depositMoney(session: WebSession, quantity: Number)
u := WebSession.getUser(session)
assert u is not None
deposit(u.username, quantity)
sync withdrawMoney(session: WebSession, quantity: Number)
u := WebSession.getUser(session)
assert u is not None
withdraw(u.username, quantity)
sync purchaseStock(session: WebSession, portfolioName: String, stockName: string)
u := WebSession.getUser(session)
assert u is not None
d := Date.now()
a := Asset.purchase(stockName, d)
assert Portfolio.getOwner(portfolioName) == u.username
addToPortfolio(portfolioName, a)
sync newPortfolio(session: WebSession, portfolioName: String, out p: portfolio)
u := WebSession.getUser(session)
assert u is not None
p := createPortfolio(portfolioName, u.username)
sync copyInvest(session: WebSession, userPortfolioName: String, targetPortfolioName: String)
u1 := WebSession.getUser(session)
u2 := Portfolio.getOwner(targetPortfolioName)
assert u1 is not None and u2 is not None
assert Portfolio.isPublic(targetPortfolioName) or Friend.areFriends(u1, u2)
targetStocks := Portfolio.getStocks(targetPortfolioName)
for stock in targetStocks:
purchaseStock(session, userPortfolioName, stock.assetName)
sync getPortfolioStocks(session: WebSession, portfolioName: String, out stocks: set Asset)
u1 := WebSession.getUser(session)
u2 := Portfolio.getOwner(portfolioName)
assert u1 is not None and u2 is not None
assert Portfolio.isPublic(portfolioName) or Friend.areFriends(u1, u2)
stocks := Portfolio.getStocks(portfolioName)
sync getPortfolioBeta(session: WebSession, portfolioName: String, out beta: Number)
u1 := WebSession.getUser(session)
u2 := Portfolio.getOwner(portfolioName)
assert u1 is not None and u2 is not None
assert Portfolio.isPublic(portfolioName) or Friend.areFriends(u1, u2)
beta := Portfolio.getBeta(portfolioName)
sync getPortfolioProfit(session: WebSession, portfolioName: String, out profit: Number)
u1 := WebSession.getUser(session)
u2 := Portfolio.getOwner(portfolioName)
assert u1 is not None and u2 is not None
assert Portfolio.isPublic(portfolioName) or Friend.areFriends(u1, u2)
profit := Portfolio.getProfit(portfolioName)
sync getPortfolioRelativeProfit(session: WebSession, portfolioName: String, out relativeProfit: Number)
u1 := WebSession.getUser(session)
u2 := Portfolio.getOwner(portfolioName)
assert u1 is not None and u2 is not None
assert Portfolio.isPublic(portfolioName) or Friend.areFriends(u1, u2)
relativeProfit := Portfolio.getRelativeProfit(portfolioName)
sync depositMoney(session: WebSession, quantity: Number)
u := WebSession.getUser(session)
assert u is not None
deposit(u.username, quantity)
sync withdrawMoney(session: WebSession, quantity: Number)
u := WebSession.getUser(session)
assert u is not None
withdraw(u.username, quantity)
Wireframe
Please view the wireframe in fullscreen for better experience.
The wireframe can be viewed on Figma.
Heuristic Evaluation
Usability Criteria
Learnability
- Many of the icons are standard icons used in most other applications
- This includes a gear to represent the settings tab
- Those that are not standard show very small samples of what the icon is supposed to represent
- The portfolio icon shows a graph of increasing and decreasing value, one of the most important parts of a portfolio
- The trade icon shows two arrows in a square-shaped cycle, representing the movement of shares and money between two parties.
Pleasantness
The interface has a dark background base with yellow and pale yellow letters/icons
- The dark background and bright letters/icons increase the readability, and the color combination engenders the idea of wealth
The logo is simple and yet represents our app well, showing multiple stacks of coins to represent the wealth that can be achieved with good trading
Physical Heuristics
Fitt’s Law
The nav bar is very wide and at the top, resulting in a large Fitt’s law score
- This highlights the sections the user will likely use, as they are the main sections of our app
The split areas in the news tab each have a large Fitt’s law score
- Each individual story has a large clickable section with text, timestamps, and tags describing the story, so each story have a fairly large Fitt’s law score
Gestalt Principles
Each story in the news list has multiple pieces of information, each of with are close to each other within a story
- Different story components, such as the text one story A and the text of story B, are farther apart to differentiate them
When choosing a timespan to show the value of your portfolio in the portfolio view, the list of possible ranges are in a straight line right next to each other
- This clearly shows a progression from shortest to longest range while keeping them related
Linguistic Level
Speak a User’s Language
Every button in the navbar either uses a common icon or an icon that is closely related to what the button will show the user. There is also text directly underneath each button for even more clarification
While the leaderboard is fairly straightforward in its presentation and can easily be understood, the user may not understand why one person is higher than another. The exact metrics used are only known to the developer, but this may not be necessary to show the user
Consistency
On every page, there is a small question mark button in the bottom right that when clicked, provides helpful information to the user about the use and purpose of the page and its components
The navbar is the same on every page, containing the same text and icons in the same order
Visual Study Design
Project Plan
Project Git Repository
Our final project will be coded on this GitHub repository.
Task assignments for each week and the deadline for each task are described in the following section. If someone is not going to make it, they should reach out to other team members so that we make changes. Once the backend and frontend of a concept are done, a third person who is not involved with the implementation will test the concept and give feedback to the students who implemented the concept.
The only concept that can be dropped without interfering with the functionality of other concepts is aiAssistant. If something goes wrong, and we need more time, we will drop that concept to focus on other challenges.
Assuming that we are going to use the same implmentation for user and websession, the following concepts will be implemented over the first week:
- Asset
- Money
- Article
The reason is that for implementing other concepts, we need data from these two concepts.
Task assignments
Concept | Backend | Frontend | Thorough testing |
---|---|---|---|
User | Amir | Henry | Cal |
Websession | Jonathon | Amir | Henry |
Asset | Cal | Jonathon | Amir |
Money | Henry | Cal | Jonathon |
Article | Amir | Henry | Cal |
Backend implementation deadline: Mon Nov 27
Frontend implementation deadline: Tue Nov 28
Testing and giving feedback: Wed Nov 29