-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTradeStocks.py
288 lines (272 loc) · 12 KB
/
TradeStocks.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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# this file is responsible for all buying and selling actions and their logging
# the stock data is read out of the sqlite3 database
class Stock:
def __init__(self, symbol, start_acc=1000, fee=0.01, check_if_exists=False):
# this function is the init
self.symbol = symbol
self.table_name = symbol.upper() + '_Account'
self.path_database = '/home/niklas/Desktop/TradingBot/Transactions/Transactions-{}.db'.format(self.symbol)
# checking if possible to read from older version
if check_if_exists:
# this function will check if there is old data that can be used
# loading the needed modules
import os
import sqlite3
import pandas as pd
# creating path
file = '/home/niklas/Desktop/TradingBot/Transactions/Transactions-{}.db'.format(self.symbol)
# checking if database already exists
if os.path.isfile(self.path_database):
# already existing, establishing connection
conn = sqlite3.connect(self.path_database)
c = conn.cursor()
# now the database is connected through
# next we are going to check if the table already exists
table_check = "SELECT name FROM sqlite_master WHERE type='table' AND name='{}';".format(self.table_name)
c.execute(table_check)
result = c.fetchone()
if result:
# table found
# read data which is already in database
df = pd.read_sql_query("SELECT * FROM {}".format(self.table_name), conn)
# setting vars
self.account = float(df.tail(1)['account'])
self.start_acc = float(df.tail(1)['account'])
self.broker_fee = float(df.tail(1)['fee'])
self.units = int(df.tail(1)['units'])
else:
self.account = start_acc
self.start_acc = start_acc
self.broker_fee = fee
self.units = 0
else:
self.account = start_acc
self.start_acc = start_acc
self.broker_fee = fee
self.units = 0
def _log_to_database(self, action, last_price=0, units=0, date_sim=0, savingtoCsv=True):
# this function will write the log for transactions
# loading the needed modules
import os
import sqlite3
import pandas as pd
from pytz import timezone
from datetime import datetime
# checking for database
# creating path
file = '/home/niklas/Desktop/TradingBot/Transactions/Transactions-{}.db'.format(self.symbol)
# checking if sim is running and then replacing timestamp with sim data
if date_sim != 0:
dt=datetime.strptime(date_sim, "%Y-%m-%d")
datetime_obj_utc = dt.replace(tzinfo=timezone('UTC'))
timestamp = str(float(datetime_obj_utc.timestamp()))
else:
# getting current time
now = datetime.now()
timestamp = datetime.timestamp(now)
# checking if already exists
if not os.path.isfile(self.path_database):
# creating file and table
conn = sqlite3.connect(self.path_database)
c = conn.cursor()
c.execute(
'CREATE TABLE {} (Time TEXT, ID_Function TEXT, ID TEXT, symbol TEXT, price_each REAL, units REAL, '
'price_total REAL, profit REAL, fee REAL, account REAL)'.format(self.table_name))
else:
# already existing, establishing connection
conn = sqlite3.connect(self.path_database)
c = conn.cursor()
# now the database is connected through
# next we are going to check if the table already exists
table_check = "SELECT name FROM sqlite_master WHERE type='table' AND name='{}';".format(self.table_name)
c.execute(table_check)
result = c.fetchone()
if result:
# table found
None
else:
# table not found
c.execute(
'CREATE TABLE {} (Time TEXT, ID_Function TEXT, ID TEXT, symbol TEXT, price_each REAL, units REAL, '
'price_total REAL, profit REAL, fee REAL, account REAL)'.format(self.table_name))
# read data which is already in database
df = pd.read_sql_query("SELECT * FROM {}".format(self.table_name), conn)
# calculating profit
if 'BUY' in action:
profit = -1 * float(units * float(last_price)) / float(
float(self.account) + float(units * float(last_price)))
elif 'SELL' in action:
profit = float(units * float(last_price)) / float(float(self.account) + float(units * float(last_price)))
else:
profit = 0
# counting rows
index = df.index
count = len(index)
# creating row with data
# starting with dictionary
row_dict = {
'Time': [timestamp],
'ID_Function': [action],
'ID': [count],
'symbol': [self.symbol],
'price_each': [last_price],
'units': [units],
'price_total': [float(units * float(last_price))],
'profit': [profit],
'fee': [self.broker_fee],
'account': [self.account]
}
df_row = pd.DataFrame(row_dict)
# new row added to new dataframe
new_df = pd.concat([df, df_row], ignore_index=True)
# check if need to save to CSV-File
if savingtoCsv:
# saved data csv-file data
new_df.to_csv('/home/niklas/Desktop/TradingBot/Transactions/Transactions-{}.csv'.format(self.symbol),
sep=';')
# write data to database
new_df.to_sql(self.table_name, conn, if_exists='replace', index=False)
# committing the saves
conn.commit()
# closing the connection
conn.close()
def _read_stock_price(self):
# read the stock price latest
import GetStockData
data_latest = GetStockData.get_data_latest(self.symbol)
return data_latest
def change(self, value):
# manually recharging the account
self.account += value
self._log_to_database('CHANGE')
def buy(self, units_to_buy, price=0, date_sim=0):
if units_to_buy > 0:
# buying stocks
# check for simulation
if price == 0:
# no simulation uses real
latest = self._read_stock_price()
last_price = latest[0]['05. price'][0]
# use normal state
state = 'BUY'
else:
# simulation use given price
last_price = price
# set different state
state = 'S-BUY'
self.units += units_to_buy
self.account -= units_to_buy * (float(last_price) + units_to_buy * self.broker_fee)
self._log_to_database(state, last_price=last_price, units=units_to_buy, savingtoCsv=True, date_sim=date_sim)
def sell(self, units_to_sell, price=0, date_sim=0):
if units_to_sell > 0:
# selling stocks
if self.units >= units_to_sell:
if price == 0:
# no simulation uses real
latest = self._read_stock_price()
last_price = latest[0]['05. price'][0]
# use normal state
state = 'SELL'
else:
# simulation use given price
last_price = price
# set different state
state = 'S-SELL'
self.units -= units_to_sell
self.account += units_to_sell * (float(last_price) - units_to_sell * self.broker_fee)
self._log_to_database(state, last_price=last_price, units=units_to_sell, date_sim=date_sim, savingtoCsv=True)
def get_transaction_count(self):
# this function will count how many buys or sells there where
# this function will write the log for transactions
# loading the needed modules
import os
import sqlite3
import pandas as pd
# checking if already exists
if os.path.isfile(self.path_database):
# already existing, establishing connection
conn = sqlite3.connect(self.path_database)
c = conn.cursor()
# now the database is connected through
# next we are going to check if the table already exists
table_check = "SELECT name FROM sqlite_master WHERE type='table' AND name='{}';".format(self.table_name)
c.execute(table_check)
result = c.fetchone()
if result:
# table found
# read data which is already in database
df = pd.read_sql_query("SELECT * FROM {}".format(self.table_name), conn)
# counting buys and sells
buys = len(df[df['ID_Function'] == 'S-BUY'])
sells = len(df[df['ID_Function'] == 'S-SELL'])
# closing the connection
conn.close()
# returning vales
return buys, sells
def get_last_log(self, lines=1):
# loading the needed modules
import sqlite3
import pandas as pd
# setting file path
file = '/home/niklas/Desktop/TradingBot/Transactions/Transactions-{}.db'.format(self.symbol)
# establishing connection to database
conn = sqlite3.connect(self.path_database)
# read data which is already in database
df = pd.read_sql_query("SELECT * FROM {}".format(self.table_name), conn)
# closing connection
conn.close()
# returning head(1)
return df.tail(lines)
def get_transaction_df(self):
# loading the needed modules
import sqlite3
import pandas as pd
# setting file path
file = '/home/niklas/Desktop/TradingBot/Transactions/Transactions-{}.db'.format(self.symbol)
# establishing connection to database
conn = sqlite3.connect(self.path_database)
# read data which is already in database
df = pd.read_sql_query("SELECT * FROM {}".format(self.table_name), conn)
# closing connection
conn.close()
# returning head(1)
return df
def get_possible_buy(self, price=0, fraction=1):
# this function will find out how many units can be bought
if price == 0:
# no simulation uses real
latest = self._read_stock_price()
# reading price from dantaframe
price = latest[0]['05. price'][0]
# setting starting point
units = 1
# iterating and checking how much possible
while self.account / (units * price) > 1:
units += 1
# calculating with fraction
possible_buys = int((units - 1) * fraction)
# retuning value
return possible_buys
def get_possible_sell(self, price=0, fraction=1):
# this function will find out how many units can be sold
if price == 0:
# no simulation uses real
latest = self._read_stock_price()
# reading price from dantaframe
price = latest[0]['05. price'][0]
# checking how many sells
possible_sells = int(self.units * fraction)
# calculating profits
profit_abs = (possible_sells * self.broker_fee) * self.units
# retuning vales
return profit_abs, possible_sells
def __repr__(self):
return self
def __str__(self):
return 'Symbol: ' + self.symbol + ' Balance: ' + str(self.account) + ' Units: ' + str(
self.units) + ' Tabel name: ' + self.table_name
if __name__ == "__main__":
ibm = Stock('IBM', check_if_exists=True)
ibm.buy(4, price=100)
print(ibm.get_last_log())
print(ibm.get_possible_buy(price=100))