Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

L6 #139

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

L6 #139

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
venv
__pycache__
node_modules
13 changes: 13 additions & 0 deletions src/app/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from datetime import datetime

MARKET_1 = 'BTC'
MARKET_2 = 'USD'

START_TIME = datetime(2020, 4, 1)
END_TIME = datetime(2020, 5, 21)

PAST_DAYS_USED_TO_PREDICT = 7
DAYS_TO_PREDICT = 4

ITERATIONS = 100
MUTATION_WEIGHT = 0.6
7 changes: 7 additions & 0 deletions src/app/cryptocompare.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from app.utils import get_json_data

def get_data(timestamp_from, timestamp_to, market_1, market_2):
url = f'https://min-api.cryptocompare.com/data/v2/histoday?fsym={market_1}&tsym={market_2}&allData=true'
data = get_json_data(url)['Data']['Data']
filtered_data = [d for d in data if d['time'] >= timestamp_from and d['time'] <= timestamp_to]
return filtered_data
47 changes: 47 additions & 0 deletions src/app/plot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import pandas as pd
from datetime import datetime, timedelta
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from app.config import MARKET_1, MARKET_2, END_TIME

def plot(df):
df['time'] = df['time'].apply(lambda x: datetime.fromtimestamp(x))

fig = make_subplots(rows=2, cols=2,
subplot_titles=('Stock prices', 'Percentage change', 'Volume'))
fig.add_trace(
go.Candlestick(
name='Stock prices',
x=df['time'],
open=df['open'],
high=df['high'],
low=df['low'],
close=df['close'],
),
row=1, col=1,
)
fig.add_trace(
go.Bar(
name='Percentage change',
x=df['time'],
y=df['per_ch'],
),
row=1, col=2,
)
fig.add_trace(
go.Bar(
name='Volume',
x=df['time'],
y=df['volume'],
),
row=2, col=1,
)

# Add line separating predictions from real values
line_date = END_TIME - timedelta(hours=12)
fig.update_layout(title_text=f'{MARKET_1} {MARKET_2} predictions',
shapes = [dict(
x0=line_date, x1=line_date, y0=0, y1=1, xref='x', yref='paper', line_width=2,
)])

fig.show()
61 changes: 61 additions & 0 deletions src/app/simulator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import random
import pandas as pd
import numpy as np
from datetime import datetime, timedelta

from app import cryptocompare
from app.config import PAST_DAYS_USED_TO_PREDICT, DAYS_TO_PREDICT, ITERATIONS, MUTATION_WEIGHT, END_TIME

def decision(probability):
return random.random() < probability
def get_adjusted_data(from_date, to_date, market_1, market_2):
data = cryptocompare.get_data(
datetime.timestamp(from_date),
datetime.timestamp(to_date),
market_1,
market_2,
)

for d in data:
d['per_ch'] = (d['close'] - d['open']) / d['open'] * 100.0
d['volume'] = (d['volumeto'] - d['volumefrom']) / 2
to_remove = ['volumefrom', 'volumeto', 'conversionType', 'conversionSymbol']
for r in to_remove:
del d[r]

return data

def simulate(from_date, to_date, market_1, market_2):
data = get_adjusted_data(from_date, to_date, market_1, market_2)
df = pd.DataFrame(data)

day = END_TIME
for days in range(DAYS_TO_PREDICT):
print(f'Simulating: {day}')
analysis_data = df.tail(PAST_DAYS_USED_TO_PREDICT).drop(columns=['time'])
analysis_data_means = analysis_data.mean()

percentage_change = np.mean(np.absolute(analysis_data['per_ch']))
increase_probability = np.mean([1 if x > 0 else 0 for x in analysis_data['per_ch']])

simulation_data = analysis_data.iloc[0:0,:].copy()
for iteration in range(ITERATIONS):
should_increase = decision(increase_probability)
mutation = (1 if should_increase else -1) * random.random() * MUTATION_WEIGHT
predicted_values = analysis_data_means * (1 + percentage_change * mutation / 100)

predicted_values['per_ch'] = (predicted_values['close'] - predicted_values['open']) / predicted_values['open'] * 100.0

simulation_data = simulation_data.append(predicted_values, ignore_index = True)
print('Mean:')
print(simulation_data.mean())
print('Median:')
median = simulation_data.median()
print(median)
print('Deviation:')
print(simulation_data.std())

median['time'] = datetime.timestamp(day)
df = df.append(median, ignore_index = True)
day += timedelta(days=1)
return df
7 changes: 7 additions & 0 deletions src/app/start_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from app import plot
from app.config import START_TIME, END_TIME, MARKET_1, MARKET_2
from app import simulator

if __name__ == "__main__":
df = simulator.simulate(START_TIME, END_TIME, MARKET_1, MARKET_2)
plot.plot(df)
5 changes: 5 additions & 0 deletions src/app/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import urllib.request, json

def get_json_data(url):
with urllib.request.urlopen(url) as u:
return json.loads(u.read().decode())
3 changes: 3 additions & 0 deletions src/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pandas==1.0.3
plotly==4.8.0
numpy==1.18.3
4 changes: 4 additions & 0 deletions src/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash -e
cd "$(dirname "$0")"

python -m app.start_app
8 changes: 8 additions & 0 deletions src/setupenv.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash -e
cd "$(dirname "$0")"

python3 -m venv venv &&
source venv/bin/activate &&
pip install --upgrade pip &&
pip install -r requirements.txt &&
deactivate