示例#1
0
def await_market_open(num):
    setup_folders()
    num += 1
    if num > 4:
        print("market not opening today")
        return
    print("checking time...")
    client = build_client()
    today = datetime.date.today()
    try:
        clock = client.get_hours_for_single_market(
            market=client.Markets.EQUITY, date=today).json()["equity"]["EQ"]
    except:
        clock = client.get_hours_for_single_market(
            market=client.Markets.EQUITY,
            date=today).json()["equity"]["equity"]

    # app starts right at 9:30 est from scheduler
    # if it's a trading day, start the app
    if clock["isOpen"] == True:
        print("Beginning process.")
        scraper()  #
        assess('skip')  #
        time.sleep(
            1
        )  # This whole process (from scrape to starting watchdog) takes about 2-5 minutes
        daily_trader(
            'initial'
        )  # so there's also inherently a delay between market open and when the app
        time.sleep(1)  # starts trading
        run_watchdog(0)  #
    else:
        print("market not open today.")
        sys.exit()
示例#2
0
def kill_trade(symbol, qty, price, order_type):
    client = build_client()
    try:
        if order_type == "long":
            client.place_order(account_id=ACCOUNT_ID,
                               order_spec=equity_sell_market(symbol, qty))
            logging.info("Killed trade")
            record_trade(symbol, price)
        else:
            client.place_order(account_id=ACCOUNT_ID,
                               order_spec=equity_buy_market(symbol, qty))
            logging.info("Killed trade")
            record_trade(symbol, price)
    except:
        logging.info(f"Unexpected error killing trade: {sys.exc_info()}")
        pass
示例#3
0
def run_watchdog(count):
    # poor man's web socket
    while count < 6500:
        count += 1
        try:
            # for the first hour, rescan every 15 min
            # if count % 5 != 0 and count < 10:
            if count <= 900 and count % 225 == 0:
                rescan_stocks()
            # for the rest of the day, rescan every hour
            elif count > 900 and count % 900 == 0:
                rescan_stocks()
            # otherwise, run watchdog
            else:
                client = build_client()
                tCLT = threading.Thread(target=check_long_trades(client))
                tCLT.start()
                tCST = threading.Thread(target=check_short_trades(client))
                tCST.start()
                tCLT.join()
                tCST.join()
                tRL = threading.Thread(target=rate_limiter(
                    count))  # this function has exit conditions
                tRL.start()
                tRL.join()
        except SystemExit:
            cancel_all('all')
            sys.exit()
        except KeyboardInterrupt:
            cancel_all('all')
            sys.exit()
        except:
            logging.info(
                "something went wrong running process, probably connection timeout."
            )
            logging.info(f"Unexpected error: {sys.exc_info()}")
            pass
示例#4
0
def start_test(count):
    cancel_all('all')
    client = build_client()
    if count < 1:
        count += 1
        symbols = ['CRBP', 'QD', 'WPG', 'ANY']

        for symbol in symbols:
            ph = client.get_price_history(
                symbol=symbol,
                period_type=client.PriceHistory.PeriodType.DAY,
                period=client.PriceHistory.Period.ONE_DAY,
                frequency_type=client.PriceHistory.FrequencyType.MINUTE,
                frequency=client.PriceHistory.Frequency.EVERY_FIFTEEN_MINUTES,
                start_datetime=None,
                end_datetime=None,
                need_extended_hours_data=None).json()
            print(ph['symbol'])
            df = pd.json_normalize(ph, 'candles')
            # pprint(len(df))
            # pprint(df)
            # pprint(df['close'])
            # pprint(df['high'])
            # pprint(df['low'])
            # pprint(df['volume'])
            raw_vwap = VolumeWeightedAveragePrice(high=df['high'],
                                                  low=df['low'],
                                                  close=df['close'],
                                                  volume=df['volume'],
                                                  window=14)
            raw_ema = EMAIndicator(close=df['close'], window=9)
            print("vwap:")
            pprint(raw_vwap.vwap[len(raw_vwap.vwap) - 1])
            print("ema:")
            pprint(raw_ema._close[len(raw_ema._close) - 1])
            print("len ema:")
            print(len(raw_ema._close))
示例#5
0
def daily_trader(str_):
    list_of_files = glob.glob("./csv's/trades/*.csv")
    sorted_files = sorted(list_of_files, key=os.path.getctime)
    most_recent_file = sorted_files[-1]  # last file should be most recent one

    client = build_client()

    # cancel all open orders
    cancel_all('orders')

    print("Getting account balance...")
    account = client.get_account(
        account_id=ACCOUNT_ID).json()["securitiesAccount"]
    # print(f"account: {account}")

    # choose between account["currentBalances"][totalCash] for cash accounts,
    # or account["currentBalances"]["buyingPower"] for margin accounts
    if account["type"] == "CASH":
        # plan to use a cash account to avoid PDT rule, so need to spread the
        # trades over 3 days to allow cash to settle. Also, using this
        # number to automatically calculate qty of shares for each trade
        buying_power = account["currentBalances"]["totalCash"]
        if buying_power == 0.0:
            buying_power = account["currentBalances"][
                "cashAvailableForTrading"]
    else:
        # later, when using a margin account, this becomes
        # a part of the risk management strategy
        buying_power = account["currentBalances"]["buyingPower"]

    daily_investment = round(float(buying_power) / 3, 2)
    print(daily_investment)

    # count rows
    with open(most_recent_file, newline='') as csvfile:
        reader = csv.DictReader(csvfile)
        print("Counting trades...")
        num_of_trades = len(list(reader))
    csvfile.close()

    # create orders from most recent gap up analysis
    with open(most_recent_file, newline='') as csvfile:
        reader = csv.DictReader(csvfile)
        print("Creating orders...")
        try:
            investment_per_trade = round(daily_investment / num_of_trades, 2)
        # if number of trades == 0
        except:
            investment_per_trade = 0.0
        order_num = 0
        error_num = 0
        entries = 0
        print(f"Num of trades is {num_of_trades}")
        print(f"inv per trade is {investment_per_trade}")

        for row in reader:
            entries += 1
            symbol = row['Symbol']
            last = float(row['Last'])
            quote = client.get_quote(symbol)
            bid = quote.json()[symbol]["bidPrice"]
            ask = quote.json()[symbol]["askPrice"]
            avg_price = round((bid + ask) / 2, 2)
            trade_check = check_for_trade(symbol)

            if trade_check:
                continue
            else:
                pass
            # if the price has moved down more than 15 cents, avg + 0.15 will be lower than last, and try to short the stock
            if avg_price + 0.15 < last:
                order_type = "short"
                entry_price = round(last - 0.10, 2)
                sl_price = str(round(entry_price * 1.07, 2))
            # otherwise, price is stable or moving up, so make a long order
            else:
                order_type = "long"
                entry_price = round(last + 0.10, 2)
                sl_price = str(round(entry_price * 0.93, 2))
            qty = int(round(investment_per_trade / entry_price, 0))
            print(f"qty is {qty}")
            if entry_price == 0 or qty == 0:
                continue
            volume = row['Volume']  # to be used later
            gap_up_percent = row['Gap Up%']  # to be used later

            print(
                f"Symbol: {symbol} side: {order_type} target entry: {entry_price} Stop Loss price: {sl_price}"
            )
            print(f"Symbol: {symbol} Vol: {volume} Gap Up% {gap_up_percent}")

            try:
                create_order(client, symbol, entry_price, qty, order_type)
                order_num += 1
            except Exception as err:
                print(f"Error with {symbol}: {err}")
                error_num += 1
                pass
        print(f"{entries} Entries found.")
        print(f"{order_num} Orders created.")
        print(f"{error_num} Errors encountered.")
    csvfile.close()
示例#6
0
def cancel_all(str_):
    """ Pass 'all', 'trades', or 'orders' depending on what needs to be canceled. """
    errors = []
    client = build_client()
    # cancel all open orders
    if str_ == "all" or str_ == "orders":
        try:
            orders = client.get_orders_by_path(account_id=ACCOUNT_ID, max_results=None, from_entered_datetime=None, to_entered_datetime=None, status=client.Order.Status.QUEUED, statuses=None).json()
            print("Canceling orders...")
            # orders = orders.json()
            for order in orders:
                order_id = order["orderId"]
                print(f"Order ID: {order_id}")
                client.cancel_order(order_id=order_id, account_id=ACCOUNT_ID)

            print("Orders canceled.")
        except:
            print("Unexpected error canceling orders:", sys.exc_info())
            errors.append(sys.exc_info())
            pass

    # close all trades   
    if str_ == "all" or str_ == "trades":
        try:
            account_with_positions = client.get_account(account_id=ACCOUNT_ID, fields=client.Account.Fields.POSITIONS).json()["securitiesAccount"]
            try:
                positions = account_with_positions["positions"]
            except:
                positions = {}
            print("Closing positions...")
            if positions == {}:
                print("No positions to close.")
            else:
                for trade in positions:
                    print(positions)
                    # submit sell order for the position
                    symbol = trade["instrument"]["symbol"]
                    short_quantity = trade["shortQuantity"]
                    long_quantity = trade["longQuantity"]
                    try:
                        if long_quantity > 0:
                            client.place_order(
                                account_id=ACCOUNT_ID,
                                order_spec=equities.equity_sell_market(symbol, long_quantity)
                            )
                    # it might be a short position, so try a buy order
                        elif short_quantity > 0:
                            client.place_order(
                                account_id=ACCOUNT_ID,
                                order_spec=equities.equity_buy_market(symbol, short_quantity)
                            )
                        else:
                            print("No trades to close.")
                            return
                    except:
                        print("Unexpected error closing trades:", sys.exc_info())
                        errors.append(sys.exc_info())
                        pass
        except:
            print("Unexpected error closing trades:", sys.exc_info())
            errors.append(sys.exc_info())
            pass

    if len(errors) > 0:
        print("errors with closing orders and positions:")
        print(errors)
    else:
        print("All orders canceled and positions closed.")
示例#7
0
def assess(str):
    if str == "prompt":
        scrape_first = input("Scrape first, y/n?   ")
    else:
        scrape_first = "n"

    if scrape_first == "y" or scrape_first == "Y" or scrape_first == "yes" or scrape_first == "Yes":
        scraper()
        time.sleep(10)
    else:
        pass

    # get 2 latest csv's from csv's directory
    list_of_files = glob.glob(
        "./csv's/raw/*.csv")  # * means all if need specific format then *.csv
    sorted_files = sorted(list_of_files, key=os.path.getctime)
    recent_gap_down = sorted_files[
        -1]  # last file is gap downs, due to order in which they are scraped
    recent_gap_up = sorted_files[-2]  # second to last will be gap ups

    gap_ups = []
    gap_downs = []
    client = build_client()
    account = client.get_account(
        account_id=ACCOUNT_ID).json()["securitiesAccount"]
    # choose between account["currentBalances"][totalCash] for cash accounts,
    # or account["currentBalances"]["buyingPower"]
    if account["type"] == "CASH":
        # plan to use a cash account to avoid PDT rule, so need to spread the
        # trades over 3 days to allow cash to settle. Also, using this
        # number to automatically calculate qty of shares for each trade
        buying_power = account["currentBalances"]["totalCash"]
    else:
        # later, when using a margin account, this becomes
        # a part of the risk management strategy
        buying_power = account["currentBalances"]["buyingPower"]

    if buying_power < 250:
        bottom_limit = 0.01
        upper_limit = 10.0
    else:
        bottom_limit = 1.0
        upper_limit = 11.0

    # analyze gap ups first
    # trade these, as they have something working favorably for them
    # which others will also bank on
    # looking for gap up over 4%, volume over 300k, and last daily closing price under $20
    with open(recent_gap_up, newline='') as csvfile:
        stockreader = csv.DictReader(csvfile, delimiter=',', quotechar='"')
        print("===== Gap Ups: =====")
        for row in stockreader:
            try:
                # grab variables
                symbol = row['Symbol']
                last = float(row['Last'])
                volume = int(float(row['Volume'].replace(",", "")))
                gap_up_percent = float(row['Gap Up%'].replace("%", ""))
                # check for criteria above
                if volume >= 300000 and last >= bottom_limit and last <= upper_limit and gap_up_percent >= 4.0:
                    print(
                        f"{symbol}: Last - {last}, Gap Up% - {gap_up_percent}, Volume - {volume}"
                    )
                    gap_ups.append([symbol, last, volume, gap_up_percent])
                else:
                    # don't fit criteria
                    print(f"Skipped {symbol}: Outside parameters.")
            except:
                # quick fix for random rows in csv
                print("Error")
                continue
    csvfile.close()

    location = get_date_and_time("trades")

    with open(location, 'w', newline='') as csvfile:
        fieldnames = ['Symbol', 'Last', 'Volume', 'Gap Up%']
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

        writer.writeheader()
        for stock in gap_ups:
            writer.writerow({
                "Symbol": stock[0],
                "Last": stock[1],
                "Volume": stock[2],
                "Gap Up%": stock[3],
            })
    csvfile.close()

    #anazlyze gap downs
    # looking for something that had a high price and has fallen due to recent news
    # add to a watchlist to profit off of recovery, or short the stock and profit off price drop
    with open(recent_gap_down, newline='') as csvfile:
        stockreader = csv.DictReader(csvfile, delimiter=',', quotechar='"')
        print("===== Gap Downs: =====")
        for row in stockreader:
            try:
                symbol = row['Symbol']
                last = float(row['Last'])
                volume = int(float(row['Volume'].replace(",", "")))
                gap_down_percent = float(row['Gap Down%'].replace("%", ""))
                if volume >= 300000 and last >= bottom_limit and last <= upper_limit and gap_down_percent < -4.5:
                    print(
                        f"{symbol}: Last - {last}, Gap Down% - {gap_down_percent}, Volume - {volume}"
                    )
                    gap_downs.append([symbol, last, volume, gap_down_percent])
                else:
                    print(f"Skipped {symbol}: Outside parameters.")
            except:
                print("Error")
                continue
    csvfile.close()

    location = get_date_and_time("watches")

    with open(location, 'w', newline='') as csvfile:
        fieldnames = ['Symbol', 'Last', 'Volume', 'Gap Down%']
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

        writer.writeheader()
        for stock in gap_downs:
            writer.writerow({
                "Symbol": stock[0],
                "Last": stock[1],
                "Volume": stock[2],
                "Gap Down%": stock[3],
            })
    csvfile.close()