-
Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathGenerateProfitFigure.py
216 lines (172 loc) · 7.23 KB
/
GenerateProfitFigure.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
import sqlite3
import matplotlib.pyplot as plt
import numpy as np
import time
import sys
ignoreLokiPrime = False
if ignoreLokiPrime:
ignoredSet = set(['loki_prime_set'])
else:
ignoredSet = set([])
def getValueOfAssets(dt, ignoredSet):
# Connect to the SQLite database
conn = sqlite3.connect('inventory.db')
cursor = conn.cursor()
# Retrieve distinct names from the transactions table
cursor.execute("SELECT DISTINCT name FROM transactions where datetime <= ?", (dt, ))
names = cursor.fetchall()
value_of_assets = 0
# Check the buy-sell balance for each name
for name in names:
name = name[0] # Extract the name from the tuple
if name in ignoredSet:
continue
cursor.execute("SELECT COUNT(*) FROM transactions WHERE name = ? AND transactionType = 'sell' AND datetime <= ?", (name, dt))
sell_count = cursor.fetchone()[0]
cursor.execute("SELECT COUNT(*), avg(price) FROM transactions WHERE name = ? AND transactionType = 'buy' AND datetime <= ?", (name, dt))
buy_count, avg_price = cursor.fetchone()
num_owned = int(buy_count) - sell_count
if avg_price and (num_owned):
value_of_assets += (avg_price - 0) * num_owned
else:
#print(f"Never bought {name}")
pass
# Close the database connection
conn.close()
return value_of_assets
def getValueOfAssets2(dt, ignoredSet):
# Connect to the SQLite database
conn = sqlite3.connect('inventory.db')
cursor = conn.cursor()
# Retrieve distinct names, net count, and average price in a single query
cursor.execute("""
SELECT name, SUM(CASE WHEN transactionType = 'buy' THEN 1 ELSE -1 END), AVG(CASE WHEN transactionType = 'buy' THEN price ELSE NULL END)
FROM transactions
WHERE datetime <= ? AND transactionType IN ('buy', 'sell')
GROUP BY name
HAVING name NOT IN ({})
""".format(','.join(['?'] * len(ignoredSet))), (dt,) + tuple(ignoredSet))
rows = cursor.fetchall()
value_of_assets = 0
# Calculate the value of assets based on the retrieved data
for name, num_owned, avg_price in rows:
#print(name, num_owned, avg_price)
num_owned = int(num_owned)
if avg_price and num_owned:
value_of_assets += avg_price * num_owned
# Close the database connection
conn.close()
return value_of_assets
def extractDate(datetimeString):
return datetimeString.split(" ")[0]
#the elemtns in dateTimeList are strings, not datetime objects, this way the trades are not spaced by 18 hrs of dead time per day.
def genLabels(dateTimeList):
labels = []
lastDay = ""
for datetimeStr in dateTimeList:
date = extractDate(datetimeStr)
if lastDay != date and date > "2021":
labels.append(date)
else:
labels.append("")
lastDay = date
return labels
def getInventoryValueOverTime(startDate, endDate):
conn = sqlite3.connect('inventory.db')
cursor = conn.cursor()
# Generate the placeholders for the elements in ignoredSet
placeholders = ', '.join(['?' for _ in ignoredSet])
# Construct the SQL query with the placeholders and date range
query = f"SELECT id, datetime FROM transactions WHERE name NOT IN ({placeholders}) AND datetime BETWEEN ? AND ? ORDER BY datetime"
# Create the parameter tuple by concatenating ignoredSet and date range
params = tuple(ignoredSet) + (startDate, endDate)
# Execute the query with the parameter tuple
cursor.execute(query, params)
rows = cursor.fetchall()
conn.close()
timestamps = []
valueOverTime = []
for row in rows:
id, date = row
timestamps.append(date)
valueOverTime.append(getValueOfAssets2(date, ignoredSet))
return timestamps, valueOverTime
def getNetEarningsOverTime(startDate, endDate):
# Connect to the SQLite database
conn = sqlite3.connect('inventory.db')
cursor = conn.cursor()
# Retrieve data from the transactions table excluding specific values
# Generate the placeholders for the elements in ignoredSet
placeholders = ', '.join(['?' for _ in ignoredSet])
# Construct the SQL query with the placeholders and date range
query = f"SELECT id, name, datetime, price, transactionType FROM transactions WHERE name NOT IN ({placeholders}) AND datetime BETWEEN ? AND ? ORDER BY datetime"
# Create the parameter tuple by concatenating ignoredSet and date range
params = tuple(ignoredSet) + (startDate, endDate)
# Execute the query with the parameter tuple
cursor.execute(query, params)
rows = cursor.fetchall()
conn.close()
conn = sqlite3.connect('inventory.db')
cursor = conn.cursor()
placeholders = ', '.join(['?' for _ in ignoredSet])
# Construct the SQL query with the placeholders and date range
query = f"SELECT SUM(CASE WHEN transactionType = 'buy' THEN -1 * price ELSE price END) FROM transactions WHERE name NOT IN ({placeholders}) AND datetime < ? ORDER BY datetime"
# Create the parameter tuple by concatenating ignoredSet and date range
params = tuple(ignoredSet) + (startDate,)
# Execute the query with the parameter tuple
cursor.execute(query, params)
initial_net_earnings = cursor.fetchall()[0][0] or 0
conn.close()
# Initialize variables
net_earnings = initial_net_earnings
timestamps = []
earnings = []
# Calculate net earnings over time
for row in rows:
id, name, timestamp, price, transaction_type = row
if transaction_type == 'buy':
net_earnings -= price
elif transaction_type == 'sell':
net_earnings += price
timestamps.append(timestamp)
earnings.append(net_earnings)
return timestamps, earnings
textColor = "#808080"
def getAccountValueFig(timestamps, inventoryValueOverTime, netEarnings):
plt.rcParams['text.color'] = textColor
plt.rcParams['axes.labelcolor'] = textColor
plt.rcParams['axes.edgecolor'] = textColor
plt.rcParams['xtick.color'] = textColor
plt.rcParams['ytick.color'] = textColor
# Create a black background
plt.rcParams['figure.facecolor'] = '#0d0a10'
plt.rcParams['axes.facecolor'] = '#0A090C'
x = timestamps
#print(x)
y = np.array(netEarnings) + np.array(inventoryValueOverTime)
labels = genLabels(timestamps)
plt.plot(x,y, '#8A4FFF')
plt.xticks(x, labels, rotation=45)
plt.title("Account Value Over Time")
plt.ylabel("Liquid Platinum + Estimated Inventory Value")
plt.xlabel("Time")
plt.xticks(rotation=45)
fig = plt.gcf()
fig.autofmt_xdate()
ax = plt.gca()
for spine in ax.spines.values():
spine.set_edgecolor(textColor)
return fig
startDate = sys.argv[1]
endDate = sys.argv[2]
print(startDate, endDate)
t = time.time()
timestamps, inventoryValueOverTime = getInventoryValueOverTime(startDate, endDate)
#print(time.time() - t)
t = time.time()
timestamps, netEarningsOverTime = getNetEarningsOverTime(startDate, endDate)
#print(time.time() - t)
t = time.time()
fig = getAccountValueFig(timestamps, inventoryValueOverTime, netEarningsOverTime)
#print(time.time() - t)
fig.savefig("accValue.png", transparent=True)