-
Notifications
You must be signed in to change notification settings - Fork 0
/
poc.py
142 lines (122 loc) · 4.02 KB
/
poc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import matplotlib
from numpy.lib.function_base import average
from api.binanceApi import Client, client
import numpy as np
from utils.plots import plot_klines
from utils.indicators import rsi
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np
from datetime import datetime
# Constants
START_FIAT_BALANCE = 100
RSI_SIZE = 5
# Prepare data
klines1m = client.get_klines(symbol="ETHBUSD", interval=Client.KLINE_INTERVAL_3MINUTE)
klines = np.array(klines1m).astype(float)
# Prepare RSI
rsis = []
for i in range(RSI_SIZE):
rsis.append(0)
for i in range(RSI_SIZE, 500):
rsis.append(rsi(klines[0:i, 4], 5))
rsi_low = 10
rsi_high = 90
# prepare times
times = mdates.date2num([datetime.fromtimestamp(int(t) // 1000) for t in klines[:, 0]])
# Prepare buys sells
marker_offset = 2
buys = []
sells = []
profit_percentages = []
buy_costs = []
bought = False
buy_prices = []
balance_crypto = 0
balance_fiat = START_FIAT_BALANCE
for i, indicator in enumerate(rsis):
if indicator > rsi_high:
if balance_crypto > 0:
price = klines[:, 4][i]
sells.append([times[i], price + marker_offset])
balance_fiat = balance_crypto * price
wallet = average(buy_prices) * balance_crypto
profit = balance_fiat - wallet
profit_percentage = round(profit / wallet * 100, 2)
profit_percentages.append(
{
"time": times[i],
"price": price,
"profit_percentage": str(profit_percentage) + "%",
}
)
balance_crypto = 0
buy_prices = []
elif indicator < rsi_low:
if balance_fiat > 0:
price = klines[:, 4][i]
buys.append([times[i], price - marker_offset])
buy_prices.append(price)
buy_costs.append(
{
"time": times[i],
"price": klines[:, 4].min(),
"buy_cost": "$" + str(round(balance_fiat, 2)),
}
)
balance_crypto += balance_fiat / price
balance_fiat = 0
# Convert the rest crypto to fiat
if balance_crypto > 0:
balance_fiat = balance_crypto * price
balance_crypto = 0
profit_sum = round(balance_fiat - START_FIAT_BALANCE, 2)
buys = np.array(buys)
sells = np.array(sells)
# Prepare plot
fig, (dax, iax) = plt.subplots(
2, 1, figsize=(20, 10), gridspec_kw={"height_ratios": [3, 1]}
)
dax.set_title(f"Overall strategy profit: ${profit_sum}")
dax.xaxis.set_major_formatter(mdates.DateFormatter("%H:%M"))
dax.xaxis.set_major_locator(mdates.MinuteLocator(interval=len(times) // 10))
iax.xaxis.set_major_formatter(mdates.DateFormatter("%H:%M"))
iax.xaxis.set_major_locator(mdates.MinuteLocator(interval=len(times) // 10))
# plot data
dax.plot(times, klines[:, 4], color="blue")
dax.legend(["ETHBUSD"])
# plot rsi
iax.plot(times, rsis, color="red")
iax.set_title(f"RSI with window size: {RSI_SIZE}")
iax.fill_between(times, 0, rsi_low, color="C0", alpha=0.3)
iax.fill_between(times, rsi_high, 100, color="C0", alpha=0.3)
# plot markers
buy_marker_style = matplotlib.markers.MarkerStyle(marker="^")
sell_marker_style = matplotlib.markers.MarkerStyle(marker="v")
dax.scatter(buys[:, 0], buys[:, 1], marker=buy_marker_style, color="green")
dax.scatter(sells[:, 0], sells[:, 1], marker=sell_marker_style, color="red")
for annotation in buy_costs:
dax.annotate(
annotation["buy_cost"],
(annotation["time"], annotation["price"]),
color="black",
fontsize="medium",
)
for annotation in profit_percentages:
if annotation["profit_percentage"][0] == "-":
color = "red"
else:
color = "green"
coords = (annotation["time"], annotation["price"])
dax.annotate(
annotation["profit_percentage"],
coords,
xytext=(4, 4),
textcoords="offset points",
color=color,
fontsize="large",
fontweight="bold",
backgroundcolor="#FFFFFF60",
)
plt.ion()
plt.show(block=False)