A demo backend application to create portfolio tracker
To install, simply clone this repository & run the following command yarn install
, this will install all the dependencies for you.
To run this project locally, run the following command yarn start
, this will start a local instance of the application & you will be able to send API requests.
Alternatively, an easier way is to run this the postman collection, no setups, no hassles.
This project is addtionally deployed on Heroku
Current implementation has 6 routes namely:
- Add Trade
- Update Trade
- Delete Trade
- Get User Portfolio
- Get User Holdings
- Get User Returns Data
Note: In case you get errors while making API requests, there is requestId present in response headers with header value x-sm-requestId
. Kindly raise a ticket with that requestId for faster resolution of the query.
The above mentioned routes are explained below:
This API endpoint extends the functionality of adding a trade associated with an user account.
This endpoint expects the following attributes passed as a JSON body along the request:
- orderType: A string type value that can either be buy or sell.
- quantity: A number type value that should be greater than zero.
- price: A number type value that should be greater than zero.
- symbol: A string type value that represents the share symbol.
- userId: A string type value that represents the user id.
On successful completion, the response will contain a JSON with the following attributes:
- tradeId: An unique identifier for the trade.
- orderType: A string type value that can either be buy or sell.
- quantity: A number type value that should be greater than zero.
- price: A number type value that should be greater than zero.
- symbol: A string type value that represents the share symbol.
- userId: A string type value that represents the user id.
- timestamp: A timestamp to denote the execution time of the trade.
On failure, API responses & appropriate messages will be passed due to one of the following cases:
-
Status Code: 400
- If any of the values is missing or is invalid.
- If no associated user account is found ( sell order type case only )
- If sell quantity is greater than or equal to that of quantity present in user account ( sell order type case only )
-
Status Code: 500
- Internal server error
Request
curl --location --request POST '<BASE API ENDPOINT>/trade' \
--header 'Content-Type: application/json' \
--data-raw '{
"orderType": "buy",
"symbol": "MSFT",
"quantity": 100,
"price": 10,
"userId": "1"
}'
Response
{
"userId": "userId",
"quantity": 100,
"symbol": "MSFT",
"price": 10,
"orderType": "BUY",
"tradeId": "tradeId",
"timestamp": "2020-01-01T080:00:00.000Z"
}
Postman Implementation
This API endpoint extends the functionality of updating a trade associated with an user account.
This endpoint expects the following attributes passed as a:
-
Path params
- userId: The value that represents the user id.
- tradeId: The value that represents associated trade.
-
JSON body along the request
- price: A number type value that should be greater than zero. ( optional )
- quantity: A number type value that should be greater than zero. ( optional )
On successful completion, the response will contain a 204, indicating that the update was successful.
On failure, API responses & appropriate messages will be passed due to one of the following cases:
-
Status Code: 400
- If any of the values is missing or is invalid.
- If no matching trade is found.
-
Status Code: 500
- Internal server error
Request
curl --location --request PUT '<BASE API ENDPOINT>/trade/userId/tradeId' \
--header 'Content-Type: application/json' \
--data-raw '{
"price": 10,
"quantity": 5
}'
Response
API response status code is 204.
Postman Implementation
This API endpoint extends the functionality of deleting a trade associated with an user account.
This endpoint expects the following attributes passed as a path params:
- userId: The value that represents the user id.
- tradeId: The value that represents associated trade.
On successful completion, the response will contain a JSON with the following attributes:
- tradeId: An unique identifier for the trade.
- orderType: A string type value that can either be buy or sell.
- quantity: A number type value that should be greater than zero.
- price: A number type value that should be greater than zero.
- symbol: A string type value that represents the share symbol.
- userId: A string type value that represents the user id.
- timestamp: A timestamp to denote the execution time of the trade.
On failure, API responses & appropriate messages will be passed due to one of the following cases:
-
Status Code: 400
- If any of the values is missing or is invalid.
- If no matching trade is found.
-
Status Code: 500
- Internal server error
Request
curl --location --request DELETE '<BASE API ENDPOINT>/trade/userId/tradeId'
Response
{
"userId": "userId",
"quantity": 100,
"symbol": "MSFT",
"price": 10,
"orderType": "BUY",
"tradeId": "tradeId",
"timestamp": "2020-01-01T080:00:00.000Z"
}
Postman Implementation
This API endpoint extends the functionality of fetching the user portfolio
This endpoint expects the following attributes passed as a path params:
- userId: The value that represents the user id.
On successful completion, the response will contain a JSON object structured as array of objects with the following attributes:
- symbol: The value that represents the share symbol.
- quantity: The value that represents the cumulative quantity of share.
- price: The value that represents the average price of share.
- currentPrice: the value that represents the current price of the share.
- returns: An object containing gains / losses in terms of value & percentage
- trades: An array of objects containing each trade's information.
On failure, API responses & appropriate messages will be passed due to one of the following cases:
-
Status Code: 400
- If no matching portfolio is found.
-
Status Code: 500
- Internal server error
Request
curl --location --request GET '<BASE API ENDPOINT>/portfolio/userId'
Response
[
{
"symbol": "ABCDEF",
"quantity": 0,
"price": 10,
"currentPrice": 100,
"returns": {
"value": 18000,
"percentage": 900
},
"trades": [
{
"quantity": 100,
"price": 10,
"orderType": "BUY",
"tradeId": "A1B1C1",
"timestamp": "2020-00-01T00:00:00.000Z"
},
{
"quantity": 100,
"price": 10,
"orderType": "BUY",
"tradeId": "D1E1F1",
"timestamp": "2020-00-01T00:00:00.000Z"
}
]
}
]
Postman Implementation
This API endpoint extends the functionality of fetching the user current holdings.
This endpoint expects the following attributes passed as a path params:
- userId: The value that represents the user id.
On successful completion, the response will contain a JSON object structured as array of objects with the following attributes:
- symbol: The value that represents the share symbol.
- quantity: The value that represents the cumulative quantity of share.
- price: The value that represents the average price of share.
On failure, API responses & appropriate messages will be passed due to one of the following cases:
-
Status Code: 400
- If no matching stock holdings are found.
-
Status Code: 500
- Internal server error
Request
curl --location --request GET '<BASE API ENDPOINT>/portfolio/holdings/userId'
Response
[
{
"symbol": "ABCDEF",
"quantity": 300,
"price": 10
},
{
"symbol": "EFGHIJ",
"quantity": 200,
"price": 10
}
]
Postman Implementation
This API endpoint extends the functionality of fetching the user returns data.
This endpoint expects the following attributes passed as a path params:
- userId: The value that represents the user id.
On successful completion, the response will contain a JSON object structured as array of objects with the following attributes:
- symbol: The value that represents the share symbol.
- quantity: The value that represents the cumulative quantity of share.
- price: The value that represents the average price of share.
- currentPrice: the value that represents the current price of the share.
- returns: An object containing gains / losses in terms of value & percentage
On failure, API responses & appropriate messages will be passed due to one of the following cases:
-
Status Code: 400
- If no matching data is found.
-
Status Code: 500
- Internal server error
Request
curl --location --request GET '<BASE API ENDPOINT>/portfolio/returns/userId'
Response
[
{
"symbol": "ABCDEF",
"quantity": 100,
"price": 10,
"currentPrice": 100,
"returns": {
"value": 9000,
"percentage": 900
}
},
{
"symbol": "EFGHIJ",
"quantity": 200,
"price": 10,
"currentPrice": 100,
"returns": {
"value": 18000,
"percentage": 900
}
}
]
Postman Implementation
- Add test cases for all the API endpoints ( Unit & E2E tests )
- Add soft delete feature ( basically revert if accidently deleted security )
- Create a transaction rollback mechanism
Made with ❤️ by AssaultKoder95