timezone converting added

This commit is contained in:
Oleg Sheynin 2025-05-27 14:18:39 -04:00
parent eda31d01fd
commit 0d0dde897d

View File

@ -16,8 +16,44 @@ UNSET_INT: int = sys.maxsize
# ------------------------ Configuration ------------------------
# Default configuration
CONFIG: Dict = {
"exchange_id": "ALPACA",
CRYPTO_CONFIG: Dict = {
# --- Data retrieval
"data_directory": "./data/crypto",
"datafiles": [
"20250519.mktdata.ohlcv.db",
],
"db_table_name": "bnbspot_ohlcv_1min",
# ----- Instruments
"exchange_id": "BNBSPOT",
"instrument_id_pfx": "PAIR-",
"instruments": [
"BTC-USDT",
"ETH-USDT",
"LTC-USDT",
],
"trading_hours": {
"begin_session": "00:00:00",
"end_session": "23:59:00",
"timezone": "UTC"
},
# ----- Model Settings
"price_column": "close",
"min_required_points": 30,
"zero_threshold": 1e-10,
"equilibrium_threshold_open": 5.0,
"equilibrium_threshold_close": 1.0,
"training_minutes": 120,
# ----- Validation
"funding_per_pair": 2000.0, # USD
}
# ========================== EQUITIES
EQT_CONFIG: Dict = {
# --- Data retrieval
"data_directory": "./data/equity",
"datafiles": [
"20250508.alpaca_sim_md.db",
@ -30,6 +66,12 @@ CONFIG: Dict = {
# "20250519.alpaca_sim_md.db",
# "20250520.alpaca_sim_md.db"
],
"db_table_name": "md_1min_bars",
# ----- Instruments
"exchange_id": "ALPACA",
"instrument_id_pfx": "STOCK-",
"instruments": [
"COIN",
"GBTC",
@ -37,7 +79,14 @@ CONFIG: Dict = {
"MSTR",
"PYPL",
],
"trading_hours": {"begin_session": "14:30:00", "end_session": "21:00:00"},
"trading_hours": {
"begin_session": "9:30:00",
"end_session": "16:00:00",
"timezone": "America/New_York"
},
# ----- Model Settings
"price_column": "close",
"min_required_points": 30,
"zero_threshold": 1e-10,
@ -45,33 +94,18 @@ CONFIG: Dict = {
"equilibrium_threshold_close": 1.0,
"training_minutes": 120,
# ----- Validation
"funding_per_pair": 2000.0,
}
# ====== later ===================
# # Try to load configuration from file, fall back to defaults if not found
# CONFIG_FILE = "config.json"
# try:
# with open(CONFIG_FILE, "r") as f:
# user_config = json.load(f)
# CONFIG.update(user_config)
# print(f"Loaded configuration from {CONFIG_FILE}")
# except (FileNotFoundError, json.JSONDecodeError) as e:
# print(f"Using default configuration. Error loading {CONFIG_FILE}: {str(e)}")
# # Create a default config file if it doesn't exist
# try:
# with open(CONFIG_FILE, "w") as f:
# json.dump(CONFIG, f, indent=4)
# print(f"Created default configuration file: {CONFIG_FILE}")
# except Exception as e:
# print(f"Warning: Could not create default config file: {str(e)}")
# ------------------------ Settings ------------------------
# ==========================================================================
CONFIG = EQT_CONFIG
TRADES = {}
TOTAL_UNREALIZED_PNL = 0.0 # Global variable to track total unrealized PnL
TOTAL_REALIZED_PNL = 0.0 # Global variable to track total realized PnL
OUTSTANDING_POSITIONS = [] # Global list to track outstanding positions with share quantities
class Pair:
class TradingPair:
symbol_a_: str
symbol_b_: str
price_column_: str
@ -81,17 +115,35 @@ class Pair:
self.symbol_b_ = symbol_b
self.price_column_ = price_column
def colnames(self) -> List[str]:
return [f"{self.price_column_}_{self.symbol_a_}", f"{self.price_column_}_{self.symbol_b_}"]
def __repr__(self) ->str:
return f"{self.symbol_a_} & {self.symbol_b_}"
def convert_time_to_UTC(value: str, timezone: str):
from zoneinfo import ZoneInfo
from datetime import datetime
# Parse it to naive datetime object
local_dt = datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
zinfo = ZoneInfo(timezone)
result = local_dt.replace(tzinfo=zinfo)
result = result.astimezone(ZoneInfo('UTC'))
result = result.strftime('%Y-%m-%d %H:%M:%S')
return result
pass
def load_market_data(datafile: str) -> pd.DataFrame:
from tools.data_loader import load_sqlite_to_dataframe
instrument_ids = ["\"" + "STOCK-" + instrument + "\"" for instrument in CONFIG["instruments"]]
instrument_ids = ["\"" + CONFIG["instrument_id_pfx"] + instrument + "\"" for instrument in CONFIG["instruments"]]
exchange_id = CONFIG["exchange_id"]
query = "select tstamp"
@ -105,7 +157,7 @@ def load_market_data(datafile: str) -> pd.DataFrame:
query += ", num_trades"
query += ", vwap"
query += " from md_1min_bars"
query += f" from {CONFIG['db_table_name']}"
query += f" where exchange_id ='{exchange_id}'"
query += f" and instrument_id in ({','.join(instrument_ids)})"
@ -113,8 +165,12 @@ def load_market_data(datafile: str) -> pd.DataFrame:
# Trading Hours
date_str = df["tstamp"][0][0:10]
start_time = f"{date_str} {CONFIG['trading_hours']['begin_session']}"
end_time = f"{date_str} {CONFIG['trading_hours']['end_session']}"
trading_hours = CONFIG['trading_hours']
start_time = f"{date_str} {trading_hours['begin_session']}"
end_time = f"{date_str} {trading_hours['end_session']}"
start_time = convert_time_to_UTC(start_time, trading_hours["timezone"])
end_time = convert_time_to_UTC(end_time, trading_hours["timezone"])
# Perform boolean selection
df = df[(df["tstamp"] >= start_time) & (df["tstamp"] <= end_time)]
@ -149,7 +205,7 @@ def transform_dataframe(df: pd.DataFrame, price_column: str):
return result_df
def get_datasets(df: pd.DataFrame, training_minutes: int, pair: Pair) -> Tuple[pd.DataFrame, pd.DataFrame]:
def get_datasets(df: pd.DataFrame, training_minutes: int, pair: TradingPair) -> Tuple[pd.DataFrame, pd.DataFrame]:
# Training dataset
colname_a, colname_b = pair.colnames()
df = df[["tstamp", colname_a, colname_b]]
@ -164,7 +220,7 @@ def get_datasets(df: pd.DataFrame, training_minutes: int, pair: Pair) -> Tuple[p
return (training_df, testing_df)
def fit_VECM(training_pair_df, pair: Pair):
def fit_VECM(training_pair_df, pair: TradingPair):
vecm_model = VECM(training_pair_df[pair.colnames()].reset_index(drop=True), coint_rank=1)
vecm_fit = vecm_model.fit()
@ -174,7 +230,7 @@ def fit_VECM(training_pair_df, pair: Pair):
return vecm_fit
def create_trading_signals(vecm_fit, testing_pair_df, pair: Pair) -> pd.DataFrame:
def create_trading_signals(vecm_fit, testing_pair_df, pair: TradingPair) -> pd.DataFrame:
result_columns = [
"time",
"action",
@ -401,7 +457,7 @@ def create_trading_signals(vecm_fit, testing_pair_df, pair: Pair) -> pd.DataFram
columns=result_columns,
)
def run_single_pair(market_data: pd.DataFrame, price_column:str, pair: Pair) -> Optional[pd.DataFrame]:
def run_single_pair(market_data: pd.DataFrame, price_column:str, pair: TradingPair) -> Optional[pd.DataFrame]:
colname_a = f"{price_column}_{pair.symbol_a_}"
colname_b = f"{price_column}_{pair.symbol_b_}"
training_pair_df, testing_pair_df = get_datasets(df=market_data, training_minutes=CONFIG["training_minutes"], pair=pair)
@ -447,16 +503,15 @@ def run_single_pair(market_data: pd.DataFrame, price_column:str, pair: Pair) ->
return pair_trades
def add_trade(pair, symbol, action, price):
# Ensure we always use clean names without STOCK- prefix
pair = str(pair).replace("STOCK-", "")
symbol = symbol.replace("STOCK-", "")
def add_trade(pair_nm, symbol, action, price):
pair_nm = str(pair_nm)
if pair not in TRADES:
TRADES[pair] = {symbol: []}
if symbol not in TRADES[pair]:
TRADES[pair][symbol] = []
TRADES[pair][symbol].append((action, price))
if pair_nm not in TRADES:
TRADES[pair_nm] = {symbol: []}
if symbol not in TRADES[pair_nm]:
TRADES[pair_nm][symbol] = []
TRADES[pair_nm][symbol].append((action, price))
def collect_single_day_results(result):
if result is None:
@ -469,7 +524,7 @@ def collect_single_day_results(result):
action = row.action
symbol = row.symbol
price = row.price
add_trade(pair=row.pair, action=action, symbol=symbol, price=price)
add_trade(pair_nm=row.pair, action=action, symbol=symbol, price=price)
def print_single_day_results(result):
for pair, symbols in TRADES.items():
@ -574,10 +629,8 @@ def run_pairs(summaries_df: pd.DataFrame, price_column: str) -> None:
colname_b = stock_price_columns[b_index]
symbol_a = colname_a[len(f"{price_column}-") :]
symbol_b = colname_b[len(f"{price_column}-") :].replace(
"STOCK-", ""
)
pair = Pair(symbol_a, symbol_b, price_column)
symbol_b = colname_b[len(f"{price_column}-") :]
pair = TradingPair(symbol_a, symbol_b, price_column)
single_pair_trades = run_single_pair(market_data=result_df, price_column=price_column, pair=pair)
if len(single_pair_trades) > 0: