StatArb / StatBot / BONUS / main_bonus.py
main_bonus.py
Raw
# 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)