Compare commits

...

4 Commits

Author SHA1 Message Date
dave 166807e181 ignore zero value stocks 2020-04-06 13:56:13 -07:00
dave 55212a5977 correct historical buy price calculation 2020-02-14 10:31:40 -08:00
dave 998d3a5f55 tabulate top ten and format currencies 2019-10-20 14:48:34 -07:00
dave 46c1ef3562 accept stale data when building reports 2019-10-20 14:48:16 -07:00
1 changed files with 24 additions and 10 deletions

View File

@ -119,6 +119,7 @@ class StockPlay(ModuleBase):
c.execute("""CREATE TABLE `stockplay_prices` (
`symbol` varchar(12) PRIMARY KEY,
`time` integer,
`attempt_time` integer,
`data` text
);""")
if not self.sql.tableExists("stockplay_balance_history"):
@ -162,16 +163,22 @@ class StockPlay(ModuleBase):
target_count = self.get_holding(nick, symbol) # backtrack until we hit this many shares
spent = 0
count = 0
buys = 0
with closing(self.sql.getCursor()) as c:
for row in c.execute("SELECT * FROM stockplay_trades WHERE nick=? AND symbol=? ORDER BY time DESC",
(nick, symbol)).fetchall():
count += row["count"] * (1 if row["type"] == "buy" else -1)
spent += row["price"] * (1 if row["type"] == "buy" else -1)
if row["type"] == "buy":
count += row["count"]
spent += row["price"]
buys += row["count"]
else:
count -= row["count"]
if count == target_count: # at this point in history the user held 0 of the symbol, stop backtracking
break
if not count:
return Decimal(0)
return Decimal(spent) / 100 / Decimal(count)
return Decimal(spent) / 100 / Decimal(buys)
def price_updater(self):
"""
@ -184,8 +191,9 @@ class StockPlay(ModuleBase):
with closing(self.sql.getCursor()) as c:
row = c.execute("""SELECT * FROM stockplay_prices
WHERE symbol in (SELECT symbol FROM stockplay_holdings WHERE count>0)
ORDER BY time ASC LIMIT 1""").fetchone()
ORDER BY attempt_time ASC LIMIT 1""").fetchone()
updatesym = row["symbol"] if row else None
c.execute("UPDATE stockplay_prices SET attempt_time=? WHERE symbol=?;", (time(), updatesym))
if updatesym:
self.get_price(updatesym, 0)
@ -226,6 +234,7 @@ class StockPlay(ModuleBase):
Do lookup of highest valued portfolios
"""
self.log.warning("{} wants top 10 sent to {}".format(nick, replyto))
rows = []
with closing(self.sql.getCursor()) as c:
for num, row in enumerate(c.execute("""SELECT h1.nick as nick, h1.cents as cents
@ -235,8 +244,10 @@ class StockPlay(ModuleBase):
ON h1.nick = h2.nick AND h1.day = h2.MaxDate
ORDER BY cents DESC LIMIT 10""", (DUSTACCT, )).fetchall(), start=1):
total = Decimal(row["cents"]) / 100
self.bot.act_PRIVMSG(replyto,
"{}: {} with total: ~${}".format(num, row["nick"], total), priority=5)
rows.append(("#{}".format(num), row["nick"], "with total:", "~{}".format(format_decimal(total)), ))
for line in tabulate(rows, justify=[False, True, False, False]):
self.bot.act_PRIVMSG(replyto, line, priority=5)
def do_trade(self, trade):
"""
@ -261,6 +272,9 @@ class StockPlay(ModuleBase):
self.bot.act_PRIVMSG(trade.replyto,
"{}: invalid symbol '{}'".format(trade.nick, trade.symbol))
return # invalid stock
if not symprice and trade.buy:
self.bot.act_PRIVMSG(trade.replyto, "{}: trading is halted on '{}'".format(trade.nick, trade.symbol))
return
# calculate various prices needed
# symprice -= Decimal("0.0001") # for testing dust collection
@ -382,7 +396,7 @@ class StockPlay(ModuleBase):
# The background thread updates the oldest price every 5 minutes. Here, we allow even very stale quotes
# because it's simply impossible to request fresh data for every stock right now. Recommended rcachesecs
# is 86400 (1 day)
symprice = Decimal(self.get_price(row["symbol"], self.config["rcachesecs"]))
symprice = Decimal(self.get_price(row["symbol"], -1))
holding_value += symprice * row["count"]
avgbuy = self.calc_user_avgbuy(nick, row["symbol"])
symbol_count.append((row["symbol"],
@ -443,8 +457,8 @@ class StockPlay(ModuleBase):
def _set_cache_priceinfo(self, symbol, data):
with closing(self.sql.getCursor()) as c:
c.execute("REPLACE INTO stockplay_prices VALUES (?, ?, ?)",
(symbol, time(), json.dumps(data)))
c.execute("REPLACE INTO stockplay_prices (symbol, attempt_time, time, data) VALUES (?, ?, ?, ?)",
(symbol, time(), time(), json.dumps(data)))
def _get_cache_priceinfo(self, symbol, thresh):
with closing(self.sql.getCursor()) as c:
@ -452,7 +466,7 @@ class StockPlay(ModuleBase):
(symbol, )).fetchone()
if not row:
return
if time() - row["time"] > thresh:
if thresh != -1 and time() - row["time"] > thresh:
return
return json.loads(row["data"])