Skip to content

Instantly share code, notes, and snippets.

@jweinst1
Last active June 9, 2026 08:32
Show Gist options
  • Select an option

  • Save jweinst1/59cb8aa5c382353d1791184f3a3fba01 to your computer and use it in GitHub Desktop.

Select an option

Save jweinst1/59cb8aa5c382353d1791184f3a3fba01 to your computer and use it in GitHub Desktop.
options trading cli for alpaca
from alpaca.data.historical import StockHistoricalDataClient
from alpaca.data.requests import StockSnapshotRequest
from alpaca.data.enums import DataFeed
from alpaca.data.historical import OptionHistoricalDataClient
from alpaca.data.requests import OptionChainRequest, OptionBarsRequest
from alpaca.data.enums import OptionsFeed
from alpaca.trading.enums import ContractType, AssetClass
from alpaca.trading.enums import QueryOrderStatus, OrderSide, OrderClass, TimeInForce, OrderStatus, OrderType
from alpaca.trading.client import TradingClient
from alpaca.trading.requests import GetOrdersRequest, LimitOrderRequest, TakeProfitRequest, StopLimitOrderRequest, GetOptionContractsRequest
from alpaca.data.timeframe import TimeFrame
import argparse
import os
import statistics
from datetime import datetime
API_KEY = "****************************"
SECRET_KEY = "*******************************"
PAPER = False
def parse_arguments():
parser = argparse.ArgumentParser(description="Alpaca Ladder OTO Bot - Dynamic Grid Trading Script")
subparsers = parser.add_subparsers(
dest='command',
required=True, # Makes a subcommand mandatory
title='Commands',
metavar='COMMAND'
)
chain = subparsers.add_parser('chain', help='Get Option Quotes', description='Get quotes and symbols')
chain.add_argument('--tick', type=str, help='Underlying stock ticker', required=True)
chain.add_argument('--exp-lte', type=str, help='End date of expiry', required=True)
chain.add_argument('--exp-gte', type=str, help='Begin date of expiry', required=True)
chain.add_argument('--strike-lte', type=float, help='highest strike', required=True)
chain.add_argument('--strike-gte', type=float, help='lowest strike', required=True)
chain.add_argument('--max-ask', type=float, default=None)
bars = subparsers.add_parser('bars', help='Get Option Bars', description='Get Bars and Movement')
bars.add_argument('--sym', type=str, help='Option Symbol', required=True)
bars.add_argument('--beg-date', type=str, help='ISO date of begin bars', required=True)
bars.add_argument('--end-date', type=str, help='ISO date of end bars', required=True)
price = subparsers.add_parser('price', help='Get Quick Quote', description='Check the price')
price.add_argument('--tick', type=str, help='Underlying stock ticker', required=True)
buy_op = subparsers.add_parser('buy', help='Buy the option', description='Buy the option')
buy_op.add_argument('--sym', type=str, help='Option Symbol', required=True)
buy_op.add_argument('--price', type=float, help='Price to buy at', required=True)
sell_op = subparsers.add_parser('sell', help='Sell the option', description='Sell the option')
sell_op.add_argument('--sym', type=str, help='Option Symbol', required=True)
sell_op.add_argument('--price', type=float, help='Price to sell at', required=True)
owned = subparsers.add_parser('owned', help='current contracts', description='current contracts')
owned.add_argument('--tick', type=str, help='Underlying stock ticker')
orders = subparsers.add_parser('orders', help='current orders', description='current orders')
orders.add_argument('--type', type=str, choices=['buy', 'sell'], required=True)
orders.add_argument('--tick', type=str, help='Underlying stock ticker', required=True)
args = parser.parse_args()
# check command via arg.command
return args
def handle_chain(argobj):
client = OptionHistoricalDataClient(API_KEY, SECRET_KEY)
req = OptionChainRequest(underlying_symbol=argobj.tick,
expiration_date_gte=argobj.exp_gte, expiration_date_lte=argobj.exp_lte,
type=ContractType.CALL, strike_price_lte=argobj.strike_lte, strike_price_gte=argobj.strike_gte)
resp = client.get_option_chain(req)
for key, value in resp.items():
bprice = value.latest_quote.bid_price if value.latest_quote else 'NA'
aprice = value.latest_quote.ask_price if value.latest_quote else 0.0
bsize = value.latest_quote.bid_size if value.latest_quote else 'NA'
asize = value.latest_quote.ask_size if value.latest_quote else 'NA'
ltprice = value.latest_trade.price if value.latest_trade else 'NA'
ltsize = value.latest_trade.size if value.latest_trade else 'NA'
hgamma = value.greeks.gamma if value.greeks else 'NA'
if argobj.max_ask and argobj.max_ask < aprice:
continue
print(f"{key} | gam={hgamma} b_price={bprice} b_size={bsize} a_price={aprice} a_size={asize} t_price={ltprice} t_size={ltsize}")
def handle_bars(argobj):
client = OptionHistoricalDataClient(API_KEY, SECRET_KEY)
begin = datetime.fromisoformat(argobj.beg_date)
enddate = datetime.fromisoformat(argobj.end_date)
req = OptionBarsRequest(symbol_or_symbols=argobj.sym, timeframe=TimeFrame.Day, start=begin, end=enddate)
barresp = client.get_option_bars(req)
if argobj.sym not in barresp.data:
print(f"Data not found for {argobj.sym}")
return
bar_objs = barresp.data[argobj.sym]
vols = [bar.volume for bar in bar_objs]
vol_mean = statistics.mean(vols)
vol_std = statistics.stdev(vols)
vol_max = max(vols)
vol_min = min(vols)
day_spreads = [(bar.high - bar.low) / bar.open for bar in bar_objs]
day_moves = [(bar.close - bar.open) / bar.open for bar in bar_objs]
max_spread = max(day_spreads)
min_spread = min(day_spreads)
mean_spread = statistics.mean(day_spreads)
std_spread = statistics.stdev(day_spreads)
print(bar_objs)
print(f"VOL mean={vol_mean} std={vol_std} min={vol_min} max={vol_max}")
print(f"SPREAD mean={mean_spread} std={std_spread} min={min_spread} max={max_spread}")
for move in day_moves:
print(f"MOVE {move}")
def handle_price(argobj):
data_client = StockHistoricalDataClient(API_KEY, SECRET_KEY)
request_params = StockSnapshotRequest(
symbol_or_symbols=argobj.tick,
feed=DataFeed.IEX
)
snapshot = data_client.get_stock_snapshot(request_params)
stock_data = snapshot[argobj.tick]
latest_close_price = stock_data.minute_bar.close
latest_ask_price = stock_data.latest_quote.ask_price
latest_bid_price = stock_data.latest_quote.bid_price
latest_day_close = stock_data.daily_bar.close
prev_day_close = stock_data.previous_daily_bar.close
print(f"------{argobj.tick}-----------")
print(f"Prev Day Close: ${prev_day_close:.2f}")
print(f"Latest Day Close: ${latest_day_close:.2f}")
print(f"Latest Minute Close: ${latest_close_price:.2f}")
print(f"Current Ask Price: ${latest_ask_price:.2f}")
print(f"Current Bid Price: ${latest_bid_price:.2f}")
print(f"------{argobj.tick}-----------")
def handle_sell(argobj):
trade_client = TradingClient(api_key=API_KEY, secret_key=SECRET_KEY, paper=PAPER)
limit_order_data = LimitOrderRequest(
symbol=argobj.sym,
qty=1,
side=OrderSide.SELL,
type=OrderType.LIMIT,
time_in_force=TimeInForce.GTC,
limit_price=round(argobj.price, 2)
)
try:
submitted_order = trade_client.submit_order(order_data=limit_order_data)
print(f"Order successfully submitted! ID: {submitted_order.id}")
print(f"Status: {submitted_order.status}")
except Exception as exc:
print(f"Cannot place order due to {exc}")
def handle_buy(argobj):
trade_client = TradingClient(api_key=API_KEY, secret_key=SECRET_KEY, paper=PAPER)
limit_order_data = LimitOrderRequest(
symbol=argobj.sym,
qty=1,
side=OrderSide.BUY,
type=OrderType.LIMIT,
time_in_force=TimeInForce.DAY,
limit_price=round(argobj.price, 2)
)
try:
submitted_order = trade_client.submit_order(order_data=limit_order_data)
print(f"Order successfully submitted! ID: {submitted_order.id}")
print(f"Status: {submitted_order.status}")
except Exception as exc:
print(f"Cannot place order due to {exc}")
def handle_owned(argobj):
trade_client = TradingClient(api_key=API_KEY, secret_key=SECRET_KEY, paper=PAPER)
all_positions = trade_client.get_all_positions()
my_options_positions = [ pos for pos in all_positions if pos.asset_class == AssetClass.US_OPTION ]
print(my_options_positions)
def handle_orders(argobj):
trade_client = TradingClient(api_key=API_KEY, secret_key=SECRET_KEY, paper=PAPER)
order_filters = GetOrdersRequest(
status=QueryOrderStatus.OPEN,
asset_class=AssetClass.US_OPTION,
limit=500
)
open_orders = trade_client.get_orders(order_filters)
open_orders = [elem for elem in open_orders if elem.symbol.startswith(argobj.tick)]
if argobj.type == 'sell':
chosen_orders = [order for order in open_orders if order.side == OrderSide.SELL]
else:
chosen_orders = [order for order in open_orders if order.side == OrderSide.BUY]
print(chosen_orders)
if __name__ == '__main__':
args = parse_arguments()
if args.command == 'chain':
handle_chain(args)
elif args.command == 'bars':
handle_bars(args)
elif args.command == 'price':
handle_price(args)
elif args.command == 'buy':
handle_buy(args)
elif args.command == 'owned':
handle_owned(args)
elif args.command == 'orders':
handle_orders(args)
elif args.command == 'sell':
handle_sell(args)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment