Has anyone here finished part time Larry's stock trading app tutorial?

Hello,

I am stuck on part 8 and 11. I cant get any SMA or RSI values and the opening range breakout strategy does not place any orders. Can someone please help me?

thanks

The part time larry videos are very much out of date. I did code the Opening range breakout strategy and get it running on alpaca paper. The ORB strategy I don’t recall using SMA or RSI, so I assume these are 2 different issues? If you are trying to use the REST api, I had to give up on that and use the python API and read the source code for documentation. If you are using python and the python api and I should be able to help if you have some code snippet, or error. I had that strategy running for a few months. it performs badly so I stopped it. but it was working and placing trades.
What library are you using for SMA and RSI that you are having trouble?

1 Like

I managed to fix the RSI and SMA issues! Its just my opening range breakout and breakdown wont place any orders on Alpaca even if I have a ton of stocks selected?

Heres my code

from main import strategy
import sqlite3
import config
import alpaca_trade_api as tradeapi
import datetime as date
import pandas as pd
from datetime import date
import smtplib, ssl
from timezone import is_dst

context = ssl.create_default_context()
connection = sqlite3.connect(config.DB_FILE)
connection.row_factory = sqlite3.Row

cursor = connection.cursor()

cursor.execute("""
    select id from strategy where name = 'opening_range_breakout'
""")

strategy_id = cursor.fetchone()['id']

cursor.execute("""
    select symbol, name
    from stock
    join stock_strategy on stock_strategy.stock_id = stock.id
    where stock_strategy.strategy_id = ?
    """, (strategy_id,))

stocks = cursor.fetchall()
symbols = [stock['symbol'] for stock in stocks]

api = tradeapi.REST(config.API_KEY, config.SECRET_KEY, base_url=config.APCA_API_BASE_URL)

current_date = date.today().isoformat()

if is_dst():
    start_minute_bar = f"{current_date} 09:30:00-05:00"
    end_minute_bar = f"{current_date} 09:45:00-05:00"
else:
    start_minute_bar = f"{current_date} 09:30:00-04:00"
    end_minute_bar = f"{current_date} 09:45:00-04:00"

orders = api.list_orders(status='all', after=current_date)
existing_order_symbols = [order.symbol for order in orders if order.status != 'canceled']

messages = []

for symbol in symbols:
    minute_bars = api.get_barset(symbol, '1Min', start=pd.Timestamp(current_date),end  =pd.Timestamp(current_date)).df

    opening_range_mask = (minute_bars.index>= start_minute_bar) & (minute_bars.index < end_minute_bar)
    opening_range_bars = minute_bars.loc[opening_range_mask]
    opening_range_low = opening_range_bars[symbol,'low'].min()
    opening_range_high = opening_range_bars[symbol,'high'].max()

    opening_range = opening_range_high - opening_range_low


    after_opening_range_mask = minute_bars.index >= end_minute_bar
    after_opening_range_bars = minute_bars.loc[after_opening_range_mask]
    after_opening_range_breakout = after_opening_range_bars[after_opening_range_bars[symbol]['close'] > opening_range_high]

    if not after_opening_range_breakout.empty:
        if symbol not in existing_order_symbols:
            limit_price = after_opening_range_breakout[symbol]['close'][0]

            messages.append(f"placing order for {symbol} at {limit_price}, closed_above {opening_range_high}\n\n{after_opening_range_breakout.iloc[0]}\n\n")

            print(f"placing order for {symbol} at {limit_price}, closed_above {opening_range_high} at {after_opening_range_breakout.iloc[0]}")

            api.submit_order(
                symbol=symbol,
                side='buy',
                type='limit',
                qty='100',
                time_in_force='day',
                order_class='bracket',
                limit_price=limit_price,
                take_profit=dict(
                    limit_price=limit_price + opening_range,
                ),
                stop_loss=dict(
                    stop_price=limit_price - opening_range,
                )
            )
        else:
            print(f"Already an order for {symbol}, skipping")


with smtplib.SMTP_SSL(config.EMAIL_HOST, config.EMAIL_PORT, context=context) as server:
    server.login(config.EMAIL_ADDRESS, config.EMAIL_PASSWORD)

    email_message = f"Subject: Trade Notifications for {current_date}\n\n"
    email_message += "\n\n".join(messages)

    server.sendmail(config.EMAIL_ADDRESS, config.EMAIL_ADDRESS, email_message)
    #server.sendmail(config.EMAIL_ADDRESS, config.EMAIL_SMS, email_message)

Have you looked at your stock list and confirmed manually there should have been a buy? Code looks like the Larry code, very similar to mine.
The biggest difference was this line:
minute_bars = api.get_barset(symbol,‘5Min’,limit=400).df

you might have to double check timezone, etc. I’ve had a couple of issues there, that I noticed from logging… like don’t place an order again within 30mins of an old order, and I was messing up the timezone.
I find one manually you think should have put in an order, or get an error. When placing the orders there are several orders you will start to get in production that Larry didn’t cover.