# Remove Pandas Future Warnings from tracemalloc import start import warnings # from sklearn import exceptions warnings.simplefilter(action='ignore', category=FutureWarning) from config_bonus_api import max_loss_usdt_total from config_bonus_api import session_private from config_bonus_api import signal_trigger_thresh from config_bonus_api import tradeable_capital_usdt from config_bonus_api import max_trades_per_signal from func_get_zscore import get_latest_z_score from config_bonus_api import signal_positive_ticker from config_bonus_api import signal_negative_ticker from func_position_info import get_position_info from func_position_info import place_market_close_order from func_position_info import get_closed_pnl_info from func_position_info import query_existing_order from func_execution_calls import set_leverage from func_execution_calls import initialise_order_execution import datetime from func_get_time import convert_time from config_bonus_api import n_step from config_bonus_api import n_interval from config_bonus_api import timeframe from config_ws_connect import ws_public from config_ws_connect import subs_public from config_ws_connect import ws_private from config_ws_connect import subs_private import time import requests from tabulate import tabulate import pandas as pd import os.path import os close_time = 0 """ RUN STATBOT II """ if __name__ == "__main__": # Set leverage in case forgotten to do so on platform set_leverage(signal_positive_ticker) set_leverage(signal_negative_ticker) start_time = 0 # Commence bot print("Seeking trades...") while True: # Set variables halt_trading = False close_check_1 = False close_check_2 = False # Pause - protect API time.sleep(3) # 10 times in minute -> 1 time per 6s # Keep alive try: trade = ws_private.fetch(subs_private[0]) except requests.exceptions.ConnectionError as errc: print("Connection error ",errc) pass except requests.exceptions.ReadTimeout as errr: print("Read timeout",errr) pass except requests.exceptions.RequestException as err: print("other errors ",err) pass # Get zscore and check if hot zscore, signal_sign_positive, exception = get_latest_z_score() # print(exception) if exception: continue if abs(zscore) > signal_trigger_thresh: hot = True zscore_entry = zscore else: hot = False zscore_exit = zscore # Get and print datetime now = datetime.datetime.now() current_time = now.strftime("%Y-%m-%d %H:%M") print(f"Datetime: {current_time},", f"Z-score: {round(zscore,2)}") # Get P&L information closed_pnl_1, exception = get_closed_pnl_info(signal_positive_ticker, start_time) if exception: continue closed_pnl_2, exception = get_closed_pnl_info(signal_negative_ticker, start_time) if exception: continue # Get position information side_1, size_1, pnl_un_1, pos_value_1, exception = get_position_info(signal_positive_ticker) if exception: continue side_2, size_2, pnl_un_2, pos_value_2, exception = get_position_info(signal_negative_ticker) if exception: continue # Check combined P&L position close_check_1 = (closed_pnl_1 + closed_pnl_2 + pnl_un_1 + pnl_un_2) <= max_loss_usdt_total if not hot: if size_1 > 0 or size_2 > 0: close_check_2 = True # Open new positions position_capital_allowance_total = tradeable_capital_usdt / 2 trade_check_1 = pos_value_1 < position_capital_allowance_total and pos_value_2 < position_capital_allowance_total trade_check_2 = hot start_time = 0 # close_time = 0 if trade_check_1 and trade_check_2: # Handle messaging print("Placing trades...", zscore) # Determine Long ticker and short ticker if signal_sign_positive: long_ticker = signal_positive_ticker short_ticker = signal_negative_ticker else: long_ticker = signal_negative_ticker short_ticker = signal_positive_ticker # Place market orders long_order_time = "" short_order_time = "" position_capital = position_capital_allowance_total / max_trades_per_signal long_order_id, long_order_time, exception = initialise_order_execution(long_ticker, "Long", position_capital) # print(exception) # time.sleep(0.5) long_order_price,_,_ = query_existing_order(long_ticker, long_order_id) # print("long order price: ",long_order_price) if exception: continue short_order_id, short_order_time, exception = initialise_order_execution(short_ticker, "Short", position_capital) # print(exception) # time.sleep(0.5) short_order_price,_,_ = query_existing_order(short_ticker, short_order_id) # print("short order price: ",short_order_price) if exception: continue start_time = min(convert_time(long_order_time),convert_time(short_order_time)) #choose the earliest trade time if timeframe == 60: close_time = start_time + 60 * timeframe * n_interval if timeframe == "D": close_time = start_time + 24 * 60 * 60 * n_interval if close_time==0: continue # Close open positions if n_step: close_n_step = (datetime.datetime.now().timestamp() >= close_time) print(f"close_time: {close_time},", f"close_n_step: {close_n_step}") else: close_n_step = True if (close_check_1 or (close_check_2 and close_n_step)): #if ((close_check_2 and close_n_step)): # Handle messaging print("Closing trades...", round(zscore,2)) # Halt trading halt_trading = True exception = True try: # Cancel all active orders session_private.cancel_all_active_orders(symbol=signal_positive_ticker) session_private.cancel_all_active_orders(symbol=signal_negative_ticker) exception = False except requests.exceptions.ConnectionError as errc: print("Connection error ",errc) pass except requests.exceptions.ReadTimeout as errr: print("Read timeout",errr) pass except requests.exceptions.RequestException as err: print("other errors ",err) pass if exception: continue time.sleep(3) # 10 times in minute -> 1 time per 6s # Close all positions if size_1 > 0: close_long_order_id, close_long_order_time, exception = place_market_close_order(signal_positive_ticker, side_2, size_1) # use side 2 close_long_order_price,_,_ = query_existing_order(signal_positive_ticker, close_long_order_id) if exception: continue if size_2 > 0: close_short_order_id, close_short_order_time, exception = place_market_close_order(signal_negative_ticker, side_1, size_2) # use side 1 close_short_order_price,_,_ = query_existing_order(signal_negative_ticker, close_short_order_id) if exception: continue negative_ticker_pnl,_ = get_closed_pnl_info(signal_negative_ticker,start_time) positive_ticker_pnl,_ = get_closed_pnl_info(signal_positive_ticker,start_time) if size_1 > 0 or size_2 > 0: print("-------------") print("Trade Summary") print("-------------") df = pd.DataFrame({'Negative ticker' : [signal_negative_ticker], 'Open Short qty' : [size_2], 'Open Short time' : [short_order_time], 'Open Short price' : [short_order_price], 'Close Short time' : [close_short_order_time], 'Close Short price' : [close_short_order_price], 'PnL' : [round(negative_ticker_pnl,2)], 'Positive ticker' : [signal_positive_ticker], 'Open Long qty' : [size_1], 'Open Long time' : [long_order_time], 'Open Long price' : [long_order_price], 'Close Long time' : [close_long_order_time], 'Close Long price' : [close_long_order_price], 'PnL' : [round(positive_ticker_pnl,2)], 'Net' : [round((positive_ticker_pnl+negative_ticker_pnl),2)], 'Z score thld' : [signal_trigger_thresh], 'Z score entry' : [round(zscore_entry,2)], 'Z score exit' : [round(zscore_exit,2)]}) print(tabulate(df, headers='keys', tablefmt='psql', showindex=False)) if(os.path.isfile("4_trade_summary.csv")): df.to_csv("4_trade_summary.csv", mode='a', index= False,header=False) else: df.to_csv("4_trade_summary.csv", index= False) print("File for trade summary saved.") if close_check_1: print("Progam is terminated.") os._exit(1)