浏览代码

Added Forecast option

Foppe Hemminga 6 年之前
父节点
当前提交
cb18c4445e
共有 4 个文件被更改,包括 76 次插入21 次删除
  1. 30 0
      main.py
  2. 21 9
      model.py
  3. 18 11
      stocks.py
  4. 7 1
      view.py

+ 30 - 0
main.py

@@ -35,6 +35,34 @@ def process_drop(this_stock):
         view.broadcast(message)
 
 
+def process_forecast(this_stock):
+    """
+    Processes FORECAST requests
+    :param this_stock:
+    :return:
+    """
+    global db
+    global timestamp_previous
+    global timestamp_latest
+    stock_id = this_stock[1]
+    data_previous = model.get_data(stock_id, timestamp_previous, db)
+    data_latest = model.get_data(stock_id, timestamp_latest, db)
+    available = this_stock[3]
+    max_price = this_stock[2]
+    forecast_previous = data_previous.forecast
+    forecast_latest = data_latest.forecast
+    is_forecast_changed = model.process_forecast(data_previous, data_latest, max_price, available)
+    current_price = float(data_latest.current_price)
+    quantity = data_latest.available_shares - data_previous.available_shares
+    stock_name = this_stock[0]
+    current_quantity = data_latest.available_shares
+    message = view.create_message(
+        stock_name, timestamp_latest, current_price, quantity, current_quantity, forecast_previous, forecast_latest)
+    print(message)
+    if is_forecast_changed:
+        view.broadcast(message)
+
+
 if __name__ == '__main__':
     db = database.db
     timestamp_latest = model.get_timestamp_latest(db)  # global
@@ -49,4 +77,6 @@ if __name__ == '__main__':
         action = stock[-1]
         if action == "DROP":
             process_drop(stock)
+        if action == "FORECAST":
+            process_forecast(stock)
     db.close()

+ 21 - 9
model.py

@@ -64,25 +64,37 @@ def get_data(stock_id, this_timestamp, this_db):
     :return:
     """
     cursor = this_db.cursor(cursor_factory=psycopg2.extras.NamedTupleCursor)
-    query = """SELECT current_price, available_shares FROM stocks WHERE stock_id = %s AND timestamp = %s"""
+    query = """SELECT current_price, available_shares, forecast FROM stocks WHERE stock_id = %s AND timestamp = %s"""
     cursor.execute(query, (stock_id, this_timestamp))
     this_data = cursor.fetchone()
     cursor.close()
     return this_data
 
 
-def process_data(this_data_previous, this_data_latest, this_price, this_threshold):
+def process_data(data_previous, data_latest, price, threshold):
     """
     Calculate if there is enough change to call it a drop
-    :param this_data_previous:
-    :param this_data_latest:
-    :param this_price:
-    :param this_threshold:
+    :param data_previous:
+    :param data_latest:
+    :param price:
+    :param threshold:
     :return boolean:
     """
     this_drop = False
-    quantity_previous = this_data_previous.available_shares * float(this_data_latest.current_price)
-    quantity_latest = this_data_latest.available_shares * float(this_data_latest.current_price)
-    if this_data_latest.current_price < this_price and quantity_latest - quantity_previous > this_threshold * 1e9:
+    quantity_previous = data_previous.available_shares * float(data_latest.current_price)
+    quantity_latest = data_latest.available_shares * float(data_latest.current_price)
+    if data_latest.current_price < price and quantity_latest - quantity_previous > threshold * 1e9:
         this_drop = True
     return this_drop
+
+
+def process_forecast(data_previous, data_latest, max_price, available):
+    forecast_changed = False
+    if data_previous.forecast in ("Very poor", "Poor", "Average"):
+        if data_latest.forecast in ("Good", "Very good"):
+            forecast_changed = True
+    if data_latest.current_price > max_price:
+        forecast_changed = False
+    if data_latest.available_shares <= available:
+        forecast_changed = False
+    return forecast_changed

+ 18 - 11
stocks.py

@@ -1,15 +1,22 @@
 # stock name, stock number, max price, min(price * drop) in B
 # So this means: stock name, stock # 15 (FHC), max price $335  and a > $10B drop
-fhg = ("FHG", 15, 335, 10, "DROP")
-yaz = ("YAZ", 8, 60, 10, "DROP")
-cnc = ("CNC", 10, 480, 10, "DROP")
-wlt = ("WLT", 30, 550, 10, "DROP")
-hrg = ("HRG", 22, 335, 10, "DROP")
-sym = ("SYM", 16, 480, 10, "DROP")
-slag = ("SLAG", 4, 190, 10, "DROP")
-grn = ("GRN", 6, 230, 10, "DROP")
-tcp = ("TCP", 13, 240, 10, "DROP")
-tcb = ("TCB", 2, 420, 10, "DROP")
+d_fhg = ("FHG", 15, 335, 10, "DROP")
+d_yaz = ("YAZ", 8, 60, 10, "DROP")
+d_cnc = ("CNC", 10, 480, 10, "DROP")
+d_wlt = ("WLT", 30, 550, 10, "DROP")
+d_hrg = ("HRG", 22, 335, 10, "DROP")
+d_sym = ("SYM", 16, 480, 10, "DROP")
+d_slag = ("SLAG", 4, 190, 10, "DROP")
+d_grn = ("GRN", 6, 230, 10, "DROP")
+d_tcp = ("TCP", 13, 240, 10, "DROP")
+d_tcb = ("TCB", 2, 420, 10, "DROP")
+
+# FORECAST
+# Forecast turns >= good from <= average
+# Name, stock_id, max price, min available
+f_fhg = ("FHG", 15, 335, 0, "FORECAST")
+f_wlt = ("WLT", 30, 555, 0, "FORECAST")
+f_sym = ("SYM", 16, 485, 0, "FORECAST")
 
 # Put all stocks in this set
-stocks = (fhg, yaz, cnc, wlt, hrg, sym, slag, grn, tcp, tcb)
+stocks = (d_fhg, d_yaz, d_cnc, d_wlt, d_hrg, d_sym, d_slag, d_grn, d_tcp, d_tcb, f_fhg, f_wlt, f_sym)

+ 7 - 1
view.py

@@ -3,19 +3,25 @@ from datetime import datetime
 import requests
 
 
-def create_message(name, timestamp, price, quantity):
+def create_message(name, timestamp, price, quantity, current_quantity=0, forecast_previous="", forecast_latest=""):
     """
     Creates the string to be broadcast
     :param name:
     :param timestamp:
     :param price:
     :param quantity:
+    :param current_quantity:
+    :param forecast_previous:
+    :param forecast_latest:
     :return:
     """
     this_time = datetime.utcfromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M')
     this_drop_decimal = quantity * price / 1e9
     this_message = "{}: {} dropped {:,} shares at ${:,.2f} for a grand total of ${:,.1f}B".format(
         this_time, name, quantity, price, this_drop_decimal)
+    if forecast_previous and forecast_latest:
+        this_message = "{}: {} changed from {} to {} with {:,} shares available at ${:,.2f}".format(
+            this_time, name, forecast_previous, forecast_latest, current_quantity, price)
     return this_message