add state
This commit is contained in:
3
bot.py
3
bot.py
@@ -11,6 +11,8 @@ import time
|
||||
import socket
|
||||
import json
|
||||
|
||||
from state import StateManager
|
||||
|
||||
# ~~~~~============== CONFIGURATION ==============~~~~~
|
||||
# Replace "REPLACEME" with your team name!
|
||||
team_name = "HanyangFloorFunction"
|
||||
@@ -29,6 +31,7 @@ team_name = "HanyangFloorFunction"
|
||||
|
||||
def main():
|
||||
args = parse_arguments()
|
||||
state = StateManager()
|
||||
|
||||
exchange = ExchangeConnection(args=args)
|
||||
|
||||
|
||||
120
state.py
Normal file
120
state.py
Normal file
@@ -0,0 +1,120 @@
|
||||
from collections import deque
|
||||
|
||||
|
||||
CONVERSION_FEE = 5
|
||||
|
||||
class StateManager:
|
||||
def __init__(self, tick_size=20):
|
||||
symbols = ["BOND", "VALBZ", "VALE", "GS", "MS", "WFC", "XLF"]
|
||||
self.positions = {s: 0 for s in symbols}
|
||||
self.orders = {s: {} for s in symbols}
|
||||
self.bid_prices = {s: None for s in symbols}
|
||||
self.ask_prices = {s: None for s in symbols}
|
||||
self.bid_depths = {s: 0 for s in symbols}
|
||||
self.ask_depths = {s: 0 for s in symbols}
|
||||
self.tick_size = tick_size
|
||||
self.price_ticks = {s: deque(maxlen=tick_size) for s in symbols}
|
||||
self.last_prices = {s: None for s in symbols}
|
||||
self.fair_values = {
|
||||
"BOND": 1000,
|
||||
"VALBZ": None,
|
||||
"VALE": None,
|
||||
"GS": None,
|
||||
"MS": None,
|
||||
"WFC": None,
|
||||
"XLF": None,
|
||||
}
|
||||
self.last_prices = {}
|
||||
self.etf_components = {
|
||||
"XLF": {"BOND": 3, "GS": 2, "MS": 3, "WFC": 2}
|
||||
}
|
||||
self.etf_shares = {"XLF": 10}
|
||||
|
||||
def add_price_tick(self, symbol: str, price: int):
|
||||
self.price_ticks[symbol].append(price)
|
||||
self.last_prices[symbol] = price
|
||||
|
||||
def get_price_ticks(self, symbol: str):
|
||||
return list(self.price_ticks.get(symbol, []))
|
||||
|
||||
def get_last_price(self, symbol: str):
|
||||
return self.last_prices.get(symbol)
|
||||
|
||||
def get_avg_price(self, symbol: str):
|
||||
ticks = self.get_price_ticks(symbol)
|
||||
if ticks:
|
||||
return sum(ticks) / len(ticks)
|
||||
return None
|
||||
|
||||
def get_ma(self, symbol: str, period: int):
|
||||
ticks = self.get_price_ticks(symbol)
|
||||
if len(ticks) >= period:
|
||||
return sum(list(ticks)[-period:]) / period
|
||||
return None
|
||||
|
||||
def update_position(self, symbol: str, quantity: int):
|
||||
self.positions[symbol] = self.positions.get(symbol, 0) + quantity
|
||||
|
||||
def update_bid_price(self, symbol: str, price: int):
|
||||
self.bid_prices[symbol] = price
|
||||
|
||||
def update_ask_price(self, symbol: str, price: int):
|
||||
self.ask_prices[symbol] = price
|
||||
|
||||
def get_position(self, symbol: str) -> int:
|
||||
return self.positions.get(symbol, 0)
|
||||
|
||||
def get_spread(self, symbol: str) -> int:
|
||||
bid = self.bid_prices.get(symbol)
|
||||
ask = self.ask_prices.get(symbol)
|
||||
if bid is not None and ask is not None:
|
||||
return ask - bid
|
||||
return None
|
||||
|
||||
def update_last_price(self, symbol: str, price: int):
|
||||
self.last_prices[symbol] = price
|
||||
|
||||
def get_mid_price(self, symbol: str):
|
||||
bid = self.bid_prices[symbol]
|
||||
ask = self.ask_prices[symbol]
|
||||
if bid is not None and ask is not None:
|
||||
return (bid + ask) // 2
|
||||
return self.last_prices.get(symbol)
|
||||
|
||||
def update_depth(self, symbol: str, bid_depth: int, ask_depth: int):
|
||||
self.bid_depths[symbol] = bid_depth
|
||||
self.ask_depths[symbol] = ask_depth
|
||||
|
||||
def get_imbalance(self, symbol: str) -> int:
|
||||
bid_depth = self.bid_depths[symbol]
|
||||
ask_depth = self.ask_depths[symbol]
|
||||
return bid_depth - ask_depth
|
||||
|
||||
def get_predicted_price(self, symbol: str) -> int:
|
||||
mid_price = self.get_mid_price(symbol)
|
||||
imbalance = self.get_imbalance(symbol)
|
||||
if mid_price is not None:
|
||||
return self.get_last_price(symbol)
|
||||
|
||||
|
||||
def update_fair_value(self):
|
||||
valbz_price = self.get_mid_price("VALBZ")
|
||||
if valbz_price is not None:
|
||||
self.fair_values["VALBZ"] = valbz_price
|
||||
self.fair_values["VALE"] = valbz_price - self.conversion_fee
|
||||
|
||||
bond_price = self.get_mid_price("BOND")
|
||||
gs_price = self.get_mid_price("GS")
|
||||
ms_price = self.get_mid_price("MS")
|
||||
wfc_price = self.get_mid_price("WFC")
|
||||
if all(p is not None for p in [bond_price, gs_price, ms_price, wfc_price]):
|
||||
component_value = (
|
||||
bond_price * self.etf_components["XLF"]["BOND"]
|
||||
+ gs_price * self.etf_components["XLF"]["GS"]
|
||||
+ ms_price * self.etf_components["XLF"]["MS"]
|
||||
+ wfc_price * self.etf_components["XLF"]["WFC"]
|
||||
) / self.etf_shares["XLF"]
|
||||
self.fair_values["XLF"] = component_value
|
||||
|
||||
def get_fair_value(self, symbol: str) -> int:
|
||||
return self.fair_values.get(symbol)
|
||||
Reference in New Issue
Block a user