Browse Source

feat(mock-stock-data-server): add mock-stock-data-server to resources

pull/2132/head
nprimo 1 year ago committed by Niccolò Primo
parent
commit
565461c3a5
  1. 8
      subjects/mobile-dev/stock-market/README.md
  2. 160
      subjects/mobile-dev/stock-market/resources/mock-stock-data-server/.dockerignore
  3. 160
      subjects/mobile-dev/stock-market/resources/mock-stock-data-server/.gitignore
  4. 161
      subjects/mobile-dev/stock-market/resources/mock-stock-data-server/.gitignore.old
  5. 15
      subjects/mobile-dev/stock-market/resources/mock-stock-data-server/Dockerfile
  6. 18
      subjects/mobile-dev/stock-market/resources/mock-stock-data-server/Makefile
  7. 50
      subjects/mobile-dev/stock-market/resources/mock-stock-data-server/README.md
  8. 35
      subjects/mobile-dev/stock-market/resources/mock-stock-data-server/app.py
  9. 8
      subjects/mobile-dev/stock-market/resources/mock-stock-data-server/requirements.txt
  10. BIN
      subjects/mobile-dev/stock-market/resources/mock-stock-data-server/sample-stocks.zip
  11. 25
      subjects/mobile-dev/stock-market/resources/mock-stock-data-server/utils.py

8
subjects/mobile-dev/stock-market/README.md

@ -2,8 +2,8 @@
### Instructions
Develop an app that will simulate a `real-time` stock market. You may use [Yahoo](https://algotrading101.com/learn/yahoo-finance-api-guide/#:~:text=Why%20should%20I%20use%20the%20Yahoo%20Finance%20API%3F,-Free&text=One%20good%20reason%20is%20because%20it%20can%20be%20completely%20free.) API for data retrieval.
You should fetch all the data in real-time and choose 10 stocks to monitor. The objectives of this exercise are to practice fetching data in real-time, visualizing custom widgets in real-time, and implementing authentication and authorization services.
Develop an app that will simulate a `real-time` stock market. For developing purpose, we provided you with a server providing you mock stock data in the [resources](resources/mock-stock-data-server/).
You should fetch all the data in real-time and choose 20 stocks to monitor. The objectives of this exercise are to practice fetching data in real-time, visualizing custom widgets in real-time, and implementing authentication and authorization services.
Upon signing up, users must be given `1 000 000` fake dollars to use within the app for buying and holding stocks. The app should have the following features:
@ -12,9 +12,9 @@ Upon signing up, users must be given `1 000 000` fake dollars to use within the
- `Historical Data`: Create a page that displays historical data for a chosen stock. This feature will allow users to view and analyze the past performance of a particular stock.
- `Stock Trading`: Implement the ability to buy, sell, and hold stocks. Users should be able to use their simulated funds (starting balance: 1 000 000 fake dollars) to buy and sell stocks. The app should keep track of the user's stock holdings and balance.
- `Historical Charts`: Provide historical charts of stock prices to help users visualize the stock performance over time. Implement a page that displays charts for the selected stock's price history.
- `Real-Time Data`: Ensure that the stock data is updated in real-time. The data should be updated at least one time per second, providing users with the latest stock information.
- `Real-Time Data`: Ensure that the stock data is updated in real-time. The data should be updated at least five times per second, providing users with the latest stock information.
- Retrieval of data for a particular stock for the last year or since the company went public.
- Choose 10 stocks to monitor and display their data within the application.
- Choose 20 stocks to monitor and display their data within the application.
Make sure to manage states using one of the following patterns:

160
subjects/mobile-dev/stock-market/resources/mock-stock-data-server/.dockerignore

@ -0,0 +1,160 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

160
subjects/mobile-dev/stock-market/resources/mock-stock-data-server/.gitignore diff.vendored

@ -0,0 +1,160 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

161
subjects/mobile-dev/stock-market/resources/mock-stock-data-server/.gitignore.old

@ -0,0 +1,161 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
stocks

15
subjects/mobile-dev/stock-market/resources/mock-stock-data-server/Dockerfile

@ -0,0 +1,15 @@
# Use the ubuntu
FROM python:3.10-slim
# Set the working directory to /app
WORKDIR /app
COPY sample-stocks/ ./sample-stocks/
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY ["app.py", "utils.py", "./"]
CMD ["python3", "app.py"]

18
subjects/mobile-dev/stock-market/resources/mock-stock-data-server/Makefile

@ -0,0 +1,18 @@
IMAGE_NAME="stock-server"
SERVER_PORT=5000
PUBLIC_PORT=5000
sample-stocks:
tar xf sample-stocks.zip
build-image:
docker rmi ${IMAGE_NAME} || echo "Clean"
docker build -t ${IMAGE_NAME} .
run: sample-stocks build-image
docker run -d -p ${PUBLIC_PORT}:${SERVER_PORT} --name ${IMAGE_NAME} --rm ${IMAGE_NAME}
stop:
docker stop ${IMAGE_NAME}
.PHONY: run stop unzip-sample-stock build-image

50
subjects/mobile-dev/stock-market/resources/mock-stock-data-server/README.md

@ -0,0 +1,50 @@
# Mock stock data server
A simple API to provide fake real time exchange data. The used database is a
sample of [this Kaggle
database](https://www.kaggle.com/datasets/jacksoncrow/stock-market-dataset).
## How to run it locally
It is recommended to use the following command to run the server locally:
```shell
$ make run
```
And to stop the server:
```shell
$ make stop
```
## Endpoints available
You can fetch the server with HTTP GET requests at the following endpoints:
- `/stocks_list`: display a list of available stock symbol.
- `/exchange_rate/<symbol>`: retrieve current data for the specified symbol.
Below an example on how to use it (remember that the server needs to be running
locally).
```shell
$ curl -s localhost:5000/stocks_list | jq | head
[
"BRID",
"WRB",
"GCO",
"ITW",
"USAU",
"AXR",
"UMBF",
"MTRN",
"UNT",
$ curl localhost:5000/exchange_rate/WRB
{"rate":0.12680993974208832,"symbol":"USD","timestamp":1691667858.912409}
$ curl localhost:5000/exchange_rate/BRID
{"rate":0.38091352581977844,"symbol":"USD","timestamp":1691667862.3328483}
$
```

35
subjects/mobile-dev/stock-market/resources/mock-stock-data-server/app.py

@ -0,0 +1,35 @@
from flask import Flask, jsonify
from flask_cors import CORS
import time
from utils import load_historical_data
app = Flask(__name__)
CORS(app)
start_time = time.time()
historical_data = load_historical_data() # Dictionary to store historical data
@app.route('/exchange_rate/<symbol>')
def get_stock_data(symbol):
if symbol not in list(historical_data.keys()):
return jsonify("Invalid symbol")
current_time = time.time()
step = (int(current_time * 10) - int(start_time * 10)) % len(historical_data[symbol])
try:
return jsonify({
'symbol': 'USD',
'rate': float(historical_data[symbol][step]),
'timestamp': current_time
})
except:
return "Server Error"
@app.route('/stocks_list')
def list_symbols():
return jsonify(list(historical_data.keys()))
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)

8
subjects/mobile-dev/stock-market/resources/mock-stock-data-server/requirements.txt

@ -0,0 +1,8 @@
blinker==1.6.2
click==8.1.6
Flask==2.3.2
Flask-Cors==4.0.0
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.3
Werkzeug==2.3.6

BIN
subjects/mobile-dev/stock-market/resources/mock-stock-data-server/sample-stocks.zip

diff.bin_not_shown

25
subjects/mobile-dev/stock-market/resources/mock-stock-data-server/utils.py

@ -0,0 +1,25 @@
import os
import csv
def load_historical_data(directory_path='./sample-stocks/'):
historical_data = {}
file_list = [filename for filename in os.listdir(directory_path) if filename.endswith(".csv")]
for filename in file_list:
if filename.endswith(".csv"):
symbol = filename.replace(".csv", "")
historical_data[symbol] = {}
file_path = os.path.join(directory_path, filename)
with open(file_path, 'r') as csv_file:
csv_reader = csv.DictReader(csv_file)
historical_data[symbol] = [row['Close'] for row in csv_reader]
return historical_data
if __name__ == "__main__":
result = load_historical_data()
print(f'keys: {result.keys()}')
Loading…
Cancel
Save