StatArb / StatBot / Execution / func_close_positions.py
func_close_positions.py
Raw
from config_execution_api import signal_positive_ticker
from config_execution_api import signal_negative_ticker
from config_execution_api import session_private
from func_position_calls import query_existing_order
from exceptions import FailedRequestError, InvalidRequestError
from requests.exceptions import ConnectionError, Timeout, RequestException
from json.decoder import JSONDecodeError

# Get position information
def get_position_info(ticker):

    exception = True
    try:
        # Declare output variables
        side = 0
        size = ""

        # Extract position info
        position = session_private.my_position(symbol=ticker)

        print("\n")
        print('-------------------------------------------------------------------')
        print("Get Position Info")
        print(position)
        print('-------------------------------------------------------------------')
        print("\n")

        if "ret_msg" in position.keys():
            if position["ret_msg"] == "OK" and len(position["result"])>0:
                if len(position["result"]) == 2:
                    if position["result"][0]["size"] > 0:
                        size = position["result"][0]["size"]
                        side = "Buy"
                    else:
                        size = position["result"][1]["size"]
                        side = "Sell"
        exception = False
        # Return output
        return (side, size, exception)
    except (ConnectionError, Timeout, RequestException, JSONDecodeError, FailedRequestError, InvalidRequestError) as e:
        print(e)
        return ("",0,exception)

#  Place market close order
def place_market_close_order(ticker, side, size):

    exception = True
    try:
        # Close position
        order = session_private.place_active_order(
            symbol=ticker,
            side=side,
            order_type="Market",
            qty=size,
            time_in_force="GoodTillCancel",
            reduce_only=True,
            close_on_trigger=False
        )

        print("\n")
        print('-------------------------------------------------------------------')
        print("Place Market Close Order")
        print(order)
        print('-------------------------------------------------------------------')
        print("\n")

        if "result" in order.keys():
            if "order_id" in order["result"] and len(order["result"])>0:
                exception = False
                print("Close Order ID: ",order["result"]["order_id"]," Close Order time: ", order["result"]["created_time"]," Exception: ", exception)
                return (order["result"]["order_id"], order["result"]["created_time"],exception)
    except (ConnectionError, Timeout, RequestException, JSONDecodeError, FailedRequestError, InvalidRequestError) as e:
        print(e)
    # Return
    return ("","", exception)


# Close all positions for both tickers
def close_all_positions(kill_switch, long_ticker, short_ticker):

    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)

        print("\n")
        print('-------------------------------------------------------------------')
        print("Close All Positions")
        print(session_private.cancel_all_active_orders(symbol=long_ticker))
        print(session_private.cancel_all_active_orders(symbol=short_ticker))
        print('-------------------------------------------------------------------')
        print("\n")

    except (ConnectionError, Timeout, RequestException, JSONDecodeError, FailedRequestError, InvalidRequestError) as e:
        print(e)
        return (kill_switch,0,"",0,0,"",0)
    
    side_1 = ""
    size_1 = 0
    side_2 = ""
    size_2 = 0
    exception = False
    close_long_order_id = ""
    close_long_order_time = ""
    close_long_order_price = 0 
    close_short_order_id = ""
    close_short_order_time = ""
    close_short_order_price = 0

    # Get position information
    #side_1, size_1, exception = get_position_info(signal_positive_ticker)
    side_1, size_1, exception = get_position_info(long_ticker)
    if exception:
        return (kill_switch,0,"",0,0,"",0)
    #side_2, size_2, exception = get_position_info(signal_negative_ticker)
    side_2, size_2, exception = get_position_info(short_ticker)
    if exception:
        return (kill_switch,0,"",0,0,"",0)

    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
        print(f"Long ticker: {long_ticker}")
        close_long_order_id, close_long_order_time, exception = place_market_close_order(long_ticker, side_2, size_1) # use side 2
        if exception:
            return (kill_switch,0,"",0,0,"",0)
        close_long_order_price,_,_ = query_existing_order(long_ticker, close_long_order_id,"")
    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
        print(f"Short ticker: {short_ticker}")
        close_short_order_id, close_short_order_time, exception = place_market_close_order(short_ticker, side_1, size_2) # use side 1
        if exception:
            return (kill_switch,0,"",0,0,"",0)
        close_short_order_price,_,_ = query_existing_order(short_ticker, close_short_order_id,"")

    # Output results
    kill_switch = 0
    return (kill_switch, size_1, close_long_order_time, close_long_order_price, size_2, close_short_order_time, close_short_order_price)