def main(): """Compute various vol estimates.""" logging.basicConfig(level=logging.INFO, format='%(levelname)-8s: %(message)s') parser = argparse.ArgumentParser(description=__doc__.strip()) ameritrade.add_args(parser) parser.add_argument('-s', '--symbol', action='store', default='SPY', help="Symbol to compute on") args = parser.parse_args() config = ameritrade.config_from_args(args) api = ameritrade.open(config) # Fetch call chain for underlying. hist = api.GetPriceHistory(symbol=args.symbol, frequency=1, frequencyType='daily', period=2, periodType='year') candle = price_history_to_arrays(hist) # Compute historical volatility estimates and centile of vol distribution of # underlying over various time periods. header = ['windays', 'annual_vol', 'iv_percentile', 'mean', 'std'] rows = [header] for days in [7, 15, 20, 30, 60, 90, 120, 180, 365, None]: centiles = True if days is None: centiles = False days = candle.datetime.shape[0] vol = historical_volatility(candle.datetime[-days:], candle.close[-days:]) if centiles: _, vols = historical_volatility_dist(candle.datetime, candle.close, days) assert len(vols) > 0 meanvol = numpy.mean(vols) stdvol = numpy.std(vols) centile = norm.cdf(vol, meanvol, stdvol) rows.append([days, vol, centile, meanvol, stdvol]) # print("Vol over {:3} days: {:8.2f}" # " (IVpct: {:5.1%}; mean/std: {:.1f}~{:.1f})".format( # days, vol, centile, meanvol, stdvol)) else: #print("Vol over {:3} days: {:8.2f}".format(days, vol)) rows.append([days, vol, '', '', '']) convert = lambda v: Decimal(v).quantize(Q) if v else '' table = (petl.wrap(rows).convert('annual_vol', convert).convert( 'iv_percentile', convert).convert('mean', convert).convert('std', convert).cut('windays', 'mean', 'std', 'annual_vol', 'iv_percentile')) print(table.lookallstr())
def main(): parser = argparse.ArgumentParser() ameritrade.add_args(parser) args = parser.parse_args() config = ameritrade.config_from_args(args) api = ameritrade.open(config) # Success! print(api)
def main(): logging.basicConfig(level=logging.INFO, format='%(levelname)-8s: %(message)s') parser = argparse.ArgumentParser(description=__doc__.strip()) ameritrade.add_args(parser) args = parser.parse_args() config = ameritrade.config_from_args(args) api = ameritrade.open(config) accountId = utils.GetMainAccount(api)
def main(): parser = argparse.ArgumentParser(description=__doc__.strip()) parser.add_argument('--betasym', default='SPY', help='Symbol to use as reference for beta') ameritrade.add_args(parser) args = parser.parse_args() config = ameritrade.config_from_args(args) api = ameritrade.open(config) accountId = utils.GetMainAccount(api) # Get the account's portfolio stock positions. all_positions = utils.GetPositions(api, accountId) positions = [(pos.instrument.symbol, pos.longQuantity - pos.shortQuantity) for pos in all_positions if pos.instrument.assetType == 'EQUITY'] positions.append(('$SPX.X', Decimal('1'))) positions.append(('SPY', Decimal('1'))) positions = [list(x) for x in sorted(positions)] # Get betas from the API. for row in positions: symbol = row[0] api_beta = GetBeta(api, symbol) row.append(api_beta.quantize(Q)) # Get time series for the benchmark. for periodType in PERIOD_TYPES: # Get benchmark returns for that period type. time, bench_returns = GetReturns(api, args.betasym, periodType) # Get price time series for all symbols. for row in positions: symbol = row[0] ptime, returns = GetReturns(api, symbol, periodType) if time.shape != ptime.shape: print((time.shape, ptime.shape, row)) pyplot.plot(time, bench_returns) pyplot.plot(ptime, returns) pyplot.show() computed_beta = Decimal('-100') else: assert list(time) == list(ptime) cov = numpy.cov(returns, bench_returns) computed_beta = cov[0, 1] / cov[1, 1] row.append(Decimal(computed_beta).quantize(Q)) header = ['symbol', 'quantity', 'api_beta'] + PERIOD_TYPES positions.insert(0, header) table = (petl.wrap(positions).cutout('quantity')) print(table.lookallstr())
def main(): """Compute various vol estimates.""" logging.basicConfig(level=logging.INFO, format='%(levelname)-8s: %(message)s') parser = argparse.ArgumentParser(description=__doc__.strip()) ameritrade.add_args(parser) args = parser.parse_args() config = ameritrade.config_from_args(args) api = ameritrade.open(config) # Fetch account information. # # This does appear not suffer time to settlement or delays, so could be used # to build monitoring UI. accounts = api.GetAccounts(fields='positions') dfpos = GetPositions(accounts) print(dfpos.to_string())
def main(): """Compute various vol estimates.""" logging.basicConfig(level=logging.INFO, format='%(levelname)-8s: %(message)s') parser = argparse.ArgumentParser(description=__doc__.strip()) ameritrade.add_args(parser) parser.add_argument('-s', '--symbol', action='store', default='SPY', help="Symbol to compute on") args = parser.parse_args() config = ameritrade.config_from_args(args) api = ameritrade.open(config) # Fetch call chain for underlying. tz = tzlocal.get_localzone() get_ts = lambda *args: int( datetime.datetime(*args, tzinfo=tz).timestamp()) * 1000 # start = get_ts(2021, 8, 20, 9, 30, 0) # end = start + 2 * 60 * 60 * 1000 start = None end = get_ts(2021, 4, 20, 15, 00, 0) # hist = api.GetPriceHistory(symbol=args.symbol, # period=1, periodType='day', # frequency=1, frequencyType='minute', # startDate=start, endDate=end) hist = api.GetPriceHistory(symbol=args.symbol, period=1, periodType='day', frequency=5, frequencyType='minute', startDate=start, endDate=end) if 'error' in hist: logging.error(f"Error: {hist}") return if hist.get('empty', False): logging.error(f"Error: {hist}") return candle = price_history_to_arrays(hist) print(len(candle))
def main(): """Compute various vol estimates.""" logging.basicConfig(level=logging.INFO, format='%(levelname)-8s: %(message)s') parser = argparse.ArgumentParser(description=__doc__.strip()) ameritrade.add_args(parser) args = parser.parse_args() config = ameritrade.config_from_args(args) api = ameritrade.open(config) # Fetch call chain for underlying. hist = api.GetPriceHistory(symbol='SPY', frequency=1, frequencyType='daily', period=2, periodType='year') candle = price_history_to_arrays(hist) # Compute historical volatility estimates and centile of vol distribution of # underlying over various time periods. for days in [7, 15, 30, 60, 90, 120, 180, 365, None]: centiles = True if days is None: centiles = False days = candle.datetime.shape[0] vol = historical_volatility(candle.datetime[-days:], candle.close[-days:]) if centiles: _, vols = historical_volatility_dist(candle.datetime, candle.close, days) assert len(vols) > 0 meanvol = numpy.mean(vols) stdvol = numpy.std(vols) centile = norm.cdf(vol, meanvol, stdvol) print("Vol over {:3} days: {:8.2f}" " (centile: {:5.1%} - {:.1f}~{:.1f})".format( days, vol, centile, meanvol, stdvol)) else: print("Vol over {:3} days: {:8.2f}".format(days, vol))
def main(): logging.basicConfig(level=logging.INFO, format='%(levelname)-8s: %(message)s') parser = argparse.ArgumentParser(description=__doc__.strip()) ameritrade.add_args(parser) args = parser.parse_args() config = ameritrade.config_from_args(args) api = ameritrade.open(config) accountId = get_first_account_api(api) # prefs = api.GetPreferences(accountId=accountId) # pprint(prefs) # keys = api.GetStreamerSubscriptionKeys(accountIds=accountId) # pprint(keys) # prin = api.GetUserPrincipals(fields='surrogateIds') # pprint(prin) # txns = api.GetTransactions(accountId=accountId) # pprint(txns) # instruments = api.SearchInstruments(symbol='SPY', projection='symbol-search') # hours = api.GetHoursMultipleMarkets() # hours = api.GetHoursMultipleMarkets() # pprint.pprint(hours) # for o in get_options_values(api): # print(o) quotes = api.GetQuotes(symbol='VTI') pprint(quotes) hist = api.GetPriceHistory(symbol='VTI') pprint(hist)
def main(): """Cancel all orders.""" parser = argparse.ArgumentParser(description=__doc__.strip()) ameritrade.add_args(parser) args = parser.parse_args() config = ameritrade.config_from_args(args, readonly=False) api = ameritrade.open(config) orders = api.GetOrdersByQuery() cancel_orders = [] for order in orders: if order['status'] != 'QUEUED': continue cancel_orders.append(order) print(order_str(order)) print("Cancel all orders [y/n]?") response = input() if response != 'y': print("Exiting without canceling.") return for order in cancel_orders: print("Canceling order {}".format(order['orderId'])) status = api.CancelOrder(**keep(order, {'accountId', 'orderId'})) pprint.pprint(status)
def main(): logging.basicConfig(level=logging.INFO, format='%(levelname)-8s: %(message)s') parser = argparse.ArgumentParser(description=__doc__.strip()) ameritrade.add_args(parser) parser.add_argument( '-s', '--underlying', '--stock', action='store', default='$XSP.X', # E-mini S&P 500 Futures help="Name of the underlying to use.") parser.add_argument( '-v', '--volatility', '--vol', action='store', type=float, help=("Volatility assumption (if not present, use single estimate " "of implied vol).")) parser.add_argument( '-p', '--pvalue', action='store', type=float, default=2.0, # 95% help="Minimum p-value to use.") parser.add_argument( '-m', '--near-margin', action='store', type=float, help=("Fixed (over time) minimum margin (in pct) away from " "the underlying.")) parser.add_argument( '-f', '--filter', action='store', help="Filter on the description field (for Weekly or Monthly)") args = parser.parse_args() config = ameritrade.config_from_args(args) api = ameritrade.open(config) # Fetch call chain. fromDate = datetime.date.today() + datetime.timedelta(days=5) toDate = datetime.date.today() + datetime.timedelta(days=45) chain = api.GetOptionChain(symbol=args.underlying, strategy='SINGLE', contractType='CALL', range='SAK', fromDate=fromDate, toDate=toDate) if chain['status'] != 'SUCCESS': logging.error(chain) return tbl = get_candidates(chain, args) if args.filter: tbl = tbl.filter(lambda row: re.search(args.filter, row.description)) print('Options for {}: {}'.format(chain['symbol'], chain['underlyingPrice'])) print(tbl)
def main(): argparser = argparse.ArgumentParser() ameritrade.add_args(argparser) argparser.add_argument('-i', '--ignore-errors', dest='raise_error', action='store_false', default=True, help="Raise an error on unhandled messages") argparser.add_argument( '-J', '--debug-file', '--json', action='store', help="Debug filename where to strore al the raw JSON") argparser.add_argument( '-j', '--debug-transaction', action='store', type=int, help="Process a single transaction and print debugging data about it.") argparser.add_argument('-e', '--end-date', action='store', help="Period of end date minus one year.") argparser.add_argument('-B', '--no-booking', dest='booking', action='store_false', default=True, help="Do booking to resolve lots.") argparser.add_argument('-l', '--ledger', action='store', help=("Beancount ledger to remove already imported " "transactions (optional).")) argparser.add_argument( '-g', '--group-by-underlying', action='store_true', help=("Group the transaction output by corresponding " "underlying. This is great for options.")) args = argparser.parse_args() # Open a connection and figure out the main account. api = ameritrade.open(ameritrade.config_from_args(args)) accountId = utils.GetMainAccount(api) positions = utils.GetPositions(api, accountId) # Fetch transactions. # Note that the following arguments are also honored: # endDate=datetime.date.today().isoformat()) # startDate='2014-01-01', # endDate='2015-01-01') if args.end_date: end_date = parser.parse(args.end_date).date() start_date = end_date - datetime.timedelta(days=364) start = start_date.isoformat() end = end_date.isoformat() else: start = end = None txns = api.GetTransactions(accountId=accountId, startDate=start, endDate=end) if isinstance(txns, dict): pprint(txns, sys.stderr) return txns.reverse() # Optionally write out the raw original content downloaded to a file. if args.debug_file: with open(args.debug, 'w') as ofile: ofile.write(pformat(txns)) # Process each of the transactions. entries = [] balances = collections.defaultdict(inventory.Inventory) commodities = {} for txn in txns: if args.debug_transaction and txn[ 'transactionId'] != args.debug_transaction: continue else: pprint.pprint(txn) # print('{:30} {}'.format(txn['type'], txn['description'])); continue dispatch_entries = RunDispatch(txn, balances, commodities, args.raise_error) if dispatch_entries: entries.extend(dispatch_entries) # Update a balance account of just the units. # # This is only here so that the options removal can figure out which # side is the reduction side and what sign to use on the position # change. Ideally the API would provide a side indication and we # wouldn't have to maintain any state at alll. {492fa5292636} for entry in data.filter_txns(dispatch_entries): for posting in entry.postings: balance = balances[posting.account] if posting.units is not None: balance.add_amount(posting.units) # Add a final balance entry. balance_entry = CreateBalance(api, accountId) if balance_entry: entries.append(balance_entry) if args.booking: # Book the entries. entries, balance_errors = booking.book(entries, OPTIONS_DEFAULTS.copy()) if balance_errors: printer.print_errors(balance_errors) # Remove dates on reductions when they have no prices. This is an # artifact of not being able to pass in prior balance state to the # booking code, which we will fix in v3. entries = RemoveDateReductions(entries) # Match up the trades we can in this subset of the history and pair them up # with a common random id. entries, balances = MatchTrades(entries) # Add zero prices for expired options for which we still have non-zero # positions. entries.extend(GetExpiredOptionsPrices(positions, balances)) # If a Beancount ledger has been specified, open it, read it in, and remove # all the transactions up to the latest one with the transaction id (as a # link) that's present in the ledger. if args.ledger: ledger_entries, _, __ = loader.load_file(args.ledger) # Find the date of the last transaction in the ledger with a TD # transaction id, and the full set of links to remove. links = set() last_date = None for entry in data.filter_txns(ledger_entries): for link in (entry.links or {}): if re.match(r"td-\d{9,}", link): links.add(link) last_date = entry.date # Remove all the transactions already present in the ledger. # # Also remove all the non-transactions with a date before that of the # last linked one that was found. This allows us to remove Price and # Commodity directives. (In v3, when links are available on every # directive, we can just use the links.) entries = [ entry for entry in entries if ((isinstance(entry, data.Transaction) and not entry.links & links) or (not isinstance(entry, data.Transaction) and entry.date >= last_date)) ] if args.group_by_underlying: # Group the transactions by their underlying, with org-mode separators. groups = GroupByUnderlying(entries) for (has_option, currency), group_entries in sorted(groups.items()): header = currency or "General" if has_option: header = "Options: {}".format(header) print("** {}".format(header)) print() printer.print_entries(data.sorted(group_entries), file=sys.stdout) print() print() else: # Render all the entries chronologically (the default). sentries = SortCommodityFirst(entries) printer.print_entries(sentries, file=sys.stdout)