Skip to content

Commit

Permalink
feat(stock-market): add hist endpoint to mock-data server
Browse files Browse the repository at this point in the history
  • Loading branch information
nprimo committed May 13, 2024
1 parent 33deab1 commit 38491e6
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ 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.
- `/hist/<symbol>?start_date="YYYY-MM-DD"&end_date"YYYY-MM-DD"`: retrieve data for the specified symbol between the two selected dates.

Below an example on how to use it (remember that the server needs to be running
locally).
Expand All @@ -42,9 +43,20 @@ $ curl -s localhost:5001/stocks_list | jq | head
"UMBF",
"MTRN",
"UNT",
$ curl localhost:5001/exchange_rate/WRB
{"rate":0.12680993974208832,"symbol":"USD","timestamp":1691667858.912409}
$ curl localhost:5001/exchange_rate/BRID
{"rate":0.38091352581977844,"symbol":"USD","timestamp":1691667862.3328483}
$ curl 'localhost:5001/exchange_rate/AAME'
{"currency":"USD","datetime":"Thu, 02 May 2024 14:38:58 GMT","rate":2.4804475372724473}
$ curl -s 'localhost:5001/hist/AAME?start_date=2024-04-01&end_date=2024-05-03' | jq | head
{
"currency": "USD",
"values": [
{
"close": 2.609999895095825,
"date": "Tue, 02 Apr 2024 00:00:00 GMT"
},
{
"close": 2.569999933242798,
"date": "Wed, 03 Apr 2024 00:00:00 GMT"
$
```
> Remember that this are mock data! The date of the historical data will vary depending on the starting date of the server.
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import time
from datetime import datetime
from random import uniform

from flask import Flask, jsonify, request
from flask_cors import CORS

from random import uniform
import time
from utils import load_data
from utils import get_historical_data, load_data

app = Flask(__name__)
CORS(app)
Expand All @@ -16,18 +18,55 @@
@app.route('/exchange_rate/<symbol>')
def get_stock_data(symbol):
if symbol not in list(historical_data.keys()):
return jsonify("Invalid symbol")
response = jsonify({"error": "Invalid symbol"})
response.status_code = 404
return response
current_time = time.time()
last_value = historical_data[symbol].Close[-1]
last_value = historical_data[symbol].iloc[-1].Close
step = (int(current_time * 10) - int(start_time * 10)
) % len(historical_data[symbol])
return jsonify({
'symbol': 'USD',
'currency': 'USD',
'rate': last_value * (1 + uniform(0.05, -0.05) + step * 0.0005),
'timestamp': current_time
'datetime': datetime.fromtimestamp(current_time)
})


@app.route('/hist/<symbol>')
def get_hist_data(symbol):
if symbol not in list(historical_data.keys()):
response = jsonify({"error": "Invalid symbol"})
response.status_code = 404
return response

df = historical_data[symbol]
args = request.args
start_date = args.get("start_date")
end_date = args.get("end_date")
if not start_date or not end_date:
response = jsonify({"error": "start_date and end_date required"})
response.status_code = 400
return response

try:
filtered = get_historical_data(df, start_date, end_date, start_time)
data = filtered[['datetime', 'Close']].to_dict(orient="list")

values = [
{"date": dt.date(), "close": close}
for dt, close in zip(data["datetime"], data["Close"])]
response = jsonify({
"currency": 'USD',
"values": values,
})
return response

except Exception as e:
response = jsonify({'error': str(e)})
response.status_code = 400
return response


@app.route('/stocks_list')
def list_symbols():
return jsonify(list(historical_data.keys()))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,47 @@
import os
import csv
from datetime import datetime

import pandas as pd


def load_historical_data(directory_path='./sample-stocks/'):
def load_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:
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]

historical_data[symbol] = pd.read_csv(file_path, parse_dates=[0])
return historical_data


def load_data(directory_path='./sample-stocks/'):
historical_data = {}
def get_historical_data(df, start, end, start_time):
today = datetime.fromtimestamp(start_time).date()
last_entry = df.sort_values(by="Date").iloc[-1]
delta_today_last_entry = today - last_entry.Date.date()

file_list = [filename for filename in os.listdir(
directory_path) if filename.endswith(".csv")]
for filename in file_list:
symbol = filename.replace(".csv", "")
file_path = os.path.join(directory_path, filename)
historical_data[symbol] = pd.read_csv(
file_path, index_col=0, parse_dates=True)
try:
query_start_dt = datetime.fromisoformat(start)
query_end_dt = datetime.fromisoformat(end)
if query_end_dt < query_start_dt:
raise Exception("end_date must come after start_date")
if query_end_dt.date() > today:
query_end_dt = datetime.fromtimestamp(start_time)

return historical_data
df['datetime'] = df.Date + delta_today_last_entry
return (df.loc[
(df.datetime >= query_start_dt) &
(df.datetime <= query_end_dt)])
except Exception as e:
raise Exception(str(e))


if __name__ == "__main__":

result = load_data()
print(f'keys: {result.keys()}')
print(result["AE"].Close[-1])
now = datetime.now()

df = result["AE"]
print(df.info())

0 comments on commit 38491e6

Please sign in to comment.