diff --git a/DiscordAlertsTrader/calc_strat.py b/DiscordAlertsTrader/calc_strat.py index 7464693..bfb6279 100644 --- a/DiscordAlertsTrader/calc_strat.py +++ b/DiscordAlertsTrader/calc_strat.py @@ -37,7 +37,7 @@ def calc_returns(fname_port= cfg['portfolio_names']['tracker_portfolio_name'], pts_ratio = [1], TS=0, SL=45, - TS_buy= 10, + TS_buy= 0, TS_buy_type= 'inverse', avg_down=None, sl_update = None, @@ -83,7 +83,7 @@ def calc_returns(fname_port= cfg['portfolio_names']['tracker_portfolio_name'], invert_contracts : bool, optional Truns a put in to a call and viceversa, by default False initial_price : str, optional - 'ask', 'bid', "price_actual", "ask_+10" == ask +10, by default 'ask' + 'ask', 'bid', "price_actual", "mid", "ask_+10" == ask +10, by default 'ask' PT : list of int, optional Profit target percent, by default [80] pts_ratio : list of int, optional @@ -243,7 +243,7 @@ def calc_returns(fname_port= cfg['portfolio_names']['tracker_portfolio_name'], margin = 0 # Iterate over the trades for idx, row in port.iterrows(): - # idx = 1032 + # idx = 225 # row = port.loc[idx] if pd.isna(row['Price-actual']) and not with_theta and not with_poly: if verbose: @@ -323,6 +323,8 @@ def calc_returns(fname_port= cfg['portfolio_names']['tracker_portfolio_name'], price_curr = quotes['bid'].iloc[0] elif 'price_actual' in initial_price: price_curr = row['Price-actual'] + elif 'mid' in initial_price: + price_curr = (quotes['ask'].iloc[0] + quotes['bid'].iloc[0])/2 offset = None if "_" in initial_price: @@ -690,41 +692,42 @@ def grid_search(params_dict, PT=[60], TS=[0], SL=[45], TS_buy=[5,10,15,20,25]): params = { # 'fname_port': '../algoalerter/data\HHscanner_port_delta0.4_179feats_ssnorm_ML_65conf.csv', 'fname_port': 'data/algoAi_port.csv', + # 'fname_port': 'data/vader_port.csv', # 'fname_port':'../algoalerter\data\HHscanner_port_delta0.4_179feats_buy_ML_preds_0.6conf.csv', # 'fname_port':'../algoalerter\data\HH2k_port2_delta0.3_179feats_lastyear_ML_preds_0.6conf.csv', # 'fname_port':'../algoalerter\data/HH2k_port2_delta0.4_179feats_lastyear_nofeb_ML_preds.csv_0.6conf.csv', # 'fname_port': 'data/EM_port.csv', # 'fname_port':'../algoalerter/data/HH2k_port2_delta0.4_179feats_lastyear_ask_preds.csv', 'trade_type': 'STO', - 'last_days': None, + 'last_days':100, 'filt_date_frm': "", 'filt_date_to': "", 'stc_date':'eod', #'stc alert', #,'exp',# , # # 'eod' or 'max_underlying_price': "", # 'min_price': 60, - 'max_dte': 10, + 'max_dte': 4, 'min_dte': 0, 'filt_hour_frm': "", - 'filt_hour_to': "", - 'include_authors': "", + 'filt_hour_to':"" , + 'include_authors':"", # 'exclude_symbols': ["SPY", "QQQ"], - 'initial_price' : 'bid', #'bid_+5', #'ask', # 'ask_+10', - 'PT': [50], #[20,25,35,45,55,65,95,],# [90],# + 'initial_price' : 'mid', #'bid_+5', #'ask', # 'ask_+10', + 'PT': [125], #[20,25,35,45,55,65,95,],# [90],# 'pts_ratio' :[1],#[0.2,0.2,0.2,0.1,0.1,0.1,0.1,],# [0.4, 0.3, 0.3], # # 'sl_update' : [ [1.8, 1.3], [2, 1.5]], # [[1.20, 1.05], [1.5, 1.3]], # # "pt_update" : [ [.3,0.7], [.3,0.7]], # None, # # 'avg_down':[[1.5, 1]], # [[1.1, .1],[1.2, .1],[1.3, .1],[1.4, .2],[1.5, .2],[1.6, .2]], # - 'SL': 50, + 'SL': 70, 'TS': 0, 'TS_buy': 0, 'TS_buy_type':'inverse', - 'max_margin': 600000, - 'short_under_amnt' : None, + 'max_margin': 57000, + 'short_under_amnt' : 1000, 'min_trade_val': 500, 'verbose': True, - 'trade_amount': 1, - # "sell_bto": True, - "max_short_val": 4000, + 'trade_amount': 1000, + "sell_bto": False, + "max_short_val": 1800, "invert_contracts": False, "do_plot": False } @@ -737,7 +740,7 @@ def grid_search(params_dict, PT=[60], TS=[0], SL=[45], TS_buy=[5,10,15,20,25]): sport = port[['Date','Symbol','Trader', 'Price', 'strategy-PnL', 'strategy-PnL$','strategy-entry','strategy-exit', 'strategy-close_date','reason_skip']] # - + sport[['Symbol', 'strategy-entry', 'strategy-PnL', 'strategy-PnL$']] result_td = generate_report(port, param, None, verbose=True) if 1: @@ -800,7 +803,7 @@ def grid_search(params_dict, PT=[60], TS=[0], SL=[45], TS_buy=[5,10,15,20,25]): res = np.stack(res) sorted_indices = np.argsort(res[:, 4]) sorted_array = res[sorted_indices].astype(int) - print(sorted_array[-20:]) + print(sorted_array[:20]) hdr = ['PT', 'SL', 'TS_buy', 'TS', 'pnl', 'pnl$', 'trade count', 'win rate'] df = pd.DataFrame(sorted_array, columns=hdr) diff --git a/DiscordAlertsTrader/marketdata/load_chn_hist.py b/DiscordAlertsTrader/marketdata/load_chn_hist.py index 25de32c..81b539f 100644 --- a/DiscordAlertsTrader/marketdata/load_chn_hist.py +++ b/DiscordAlertsTrader/marketdata/load_chn_hist.py @@ -29,6 +29,40 @@ author = "algoAi" +chan_ids = { + "mbag1": 1187162844362448896, + "mbag2": 1189180874265210961, + "theta_warrior_elite": 897625103020490773, + "demon": 1167160585511776357, + "eclipse": 1213995695237763145, + "moneymotive": 1012144319282556928, + "moneymotiveA+": 1214378575554150440, + "bishop": 1195073059770605568, + "makeplays": 1164747583638491156, + "kingmaker": 1152082112032292896, + "oculus": 1222679083155193867, + 'diesel': 1107395495460081754, + 'ddking': 1225020986953437305, + "crimson": 1102753361566122064, + "HH": 1197849899627184149, + "HH2k": 867390497115209728, + "vader": 1235324287703973998, + "gianni": 1209992523083415603, + "og-alerts": 1207717868716826645, + "EM": 1126325195301462117, + "vader-swings":1235324289222443008, + "rough": 989674163331534929, + 'opccpro': 1125655265312776274, + "bear": 1221951478621540384, + 'prophi': 1216951944933933137, + "stb": 959672267929956413, + "sti": 1175048558639058985, + "gandalf": 910228981536653342, + "psa": 1199936454797824010, + "algoAi": 1237566888062750791, + "jpm": 1221952610987147284, + } + def get_timestamp(row): date_time = row[DataType.DATE] + timedelta(milliseconds=row[DataType.MS_OF_DAY]) return date_time.timestamp() @@ -69,39 +103,6 @@ def save_or_append_quote(quotes, symbol, path_quotes, overwrite=False): df.to_csv(fname, index=False) -chan_ids = { - "mbag1": 1187162844362448896, - "mbag2": 1189180874265210961, - "theta_warrior_elite": 897625103020490773, - "demon": 1167160585511776357, - "eclipse": 1213995695237763145, - "moneymotive": 1012144319282556928, - "moneymotiveA+": 1214378575554150440, - "bishop": 1195073059770605568, - "makeplays": 1164747583638491156, - "kingmaker": 1152082112032292896, - "oculus": 1222679083155193867, - 'diesel': 1107395495460081754, - 'ddking': 1225020986953437305, - "crimson": 1102753361566122064, - "HH": 1197849899627184149, - "HH2k": 867390497115209728, - "vader": 1235324287703973998, - "gianni": 1209992523083415603, - "og-alerts": 1207717868716826645, - "EM": 1126325195301462117, - "vader-swings":1235324289222443008, - "rough": 989674163331534929, - 'opccpro': 1125655265312776274, - "bear": 1221951478621540384, - 'prophi': 1216951944933933137, - "stb": 959672267929956413, - "sti": 1175048558639058985, - "gandalf": 910228981536653342, - "psa": 1199936454797824010, - "algoAi": 1237566888062750791, - "jpm": 1221952610987147284, - } chan_id = chan_ids[author] if not use_theta_rest_api: client = ThetaClient(username=cfg["thetadata"]["username"], diff --git a/DiscordAlertsTrader/marketdata/thetadata_api.py b/DiscordAlertsTrader/marketdata/thetadata_api.py index 42667c3..2cfc329 100644 --- a/DiscordAlertsTrader/marketdata/thetadata_api.py +++ b/DiscordAlertsTrader/marketdata/thetadata_api.py @@ -156,12 +156,18 @@ def get_geeks(self, symbol: str, date_range: List[date], interval_size: int=1000 return data + def get_exps(self, symbol: str): + url = 'http://127.0.0.1:25510/v2/list/expirations?root=' + symbol + header ={'Accept': 'application/json'} + response = requests.get(url, headers=header, timeout=10) + return response.json()['response'] + def get_currentgeeks(self, symbol: str, date_range: List[date]): expdate, root, right, strike, date_s, date_e = self.info_option(symbol, date_range) url = f'http://127.0.0.1:25510/v2/bulk_snapshot/option/greeks?exp={expdate}&right={right}&strike={strike}&start_date={date_s}&end_date={date_e}&use_csv=true&root={root}&rth=true' header ={'Accept': 'application/json'} - response_quotes = requests.get(url, headers=header) + response_quotes = requests.get(url, headers=header, timeout=10) df_q = pd.read_csv(io.StringIO(response_quotes.content.decode('utf-8'))) df_q['timestamp'] = df_q.apply(get_timestamp_, axis=1) if not len(df_q): @@ -301,6 +307,7 @@ def get_delta_strike(self, ticker: str, exp_date: str, delta:float, right:str, t ms_of_day = (dt.hour*3600 + dt.minute*60 + dt.second)* 1000 ix_g = np.argmin(abs(df_q['ms_of_day'] - ms_of_day)) this_delta = df_q.iloc[ix_g]['delta'] + this_df = df_q.iloc[ix_g] print("delta", this_delta, strike) if abs(this_delta) - abs(delta) < 0.1: @@ -323,7 +330,7 @@ def get_delta_strike(self, ticker: str, exp_date: str, delta:float, right:str, t st_info.append((strike, this_delta)) exp_date_f = datetime.strptime(exp_date, "%Y%m%d").strftime("%m%d%y") - return f"{ticker}_{exp_date_f}{right}{strike/1000}".replace(".0", ""), this_delta + return f"{ticker}_{exp_date_f}{right}{strike/1000}".replace(".0", ""), this_delta, this_df def get_open_interest(self, symbol: str, date_range: List[date]): @@ -332,7 +339,7 @@ def get_open_interest(self, symbol: str, date_range: List[date]): # date to ny time url = f'http://127.0.0.1:25510/v2/hist/option/open_interest?exp={expdate}&right={right}&strike={strike}&start_date={date_s}&end_date={date_e}&use_csv=true&root={root}' header ={'Accept': 'application/json'} - response = requests.get(url, headers=header) + response = requests.get(url, headers=header, timeout=10) if response.content.startswith(b'No data for'): return None # get quotes and trades to merge the with second level quotes diff --git a/DiscordAlertsTrader/server_alert_formatting.py b/DiscordAlertsTrader/server_alert_formatting.py index b47348d..7b714b3 100644 --- a/DiscordAlertsTrader/server_alert_formatting.py +++ b/DiscordAlertsTrader/server_alert_formatting.py @@ -65,6 +65,8 @@ def server_formatting(message): message = wolfwebull_formatting(message) elif message.channel.id in [1187162844362448896, 1189180874265210961]: message = nvstly_alerts(message) + elif message.channel.id in [1244040902582865937]: + message = cblast_alerts(message) elif message.guild.id in [826258453391081524, 1093339706260979822,1072553858053701793, 898981804478980166, 682259216861626378]: message = aurora_trading_formatting(message) else: @@ -741,6 +743,25 @@ def oculus_alerts(message_): message.content = alert return message + +def cblast_alerts(message_): + """ + Reformat Discord message from cblast to content message + """ + message = MessageCopy(message_) + alert = message.content + if not alert: + return message + + # format: $AI 29c 10/18 at 0.16 + pattern = r'\$([A-Z]+)\s+(\d+)([c|p|C|P])\s+(\d{1,2}\/\d{1,2})\s+at\s+([\d.]+)' + match = re.search(pattern, alert, re.IGNORECASE) + if match: + ticker, strike, otype, expDate, price = match.groups() + alert = f"BTO {ticker} {strike.upper()}{otype[0]} {expDate} @{price}" + message.content = alert + return message + def eclipse_alerts(message_): """ Reformat Discord message from eclipse to content message