Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

client: extract DataFrame conversion #127

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 26 additions & 53 deletions tdameritrade/client.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pandas as pd
import os

from . import convert
from .session import TDASession
from .exceptions import handle_error_response, TDAAPIError
from .urls import (
Expand Down Expand Up @@ -119,12 +120,7 @@ def accounts(self, positions=False, orders=False):

def accountsDF(self):
'''get accounts as dataframe'''
data = self.accounts()
account_dataframes = []
for accountId, value in data.items():
account_dataframes.append(pd.io.json.json_normalize(value))
account_dataframes[-1].columns = [c.replace('securitiesAccount.', '') for c in account_dataframes[-1].columns]
return pd.concat(account_dataframes)
return convert.accounts(self.accounts())

def transactions(self, accountId=None, type=None, symbol=None, startDate=None, endDate=None):
'''get transactions by account
Expand Down Expand Up @@ -158,7 +154,8 @@ def transactions(self, accountId=None, type=None, symbol=None, startDate=None, e

def transactionsDF(self, accountId=None, type=None, symbol=None, startDate=None, endDate=None):
'''get transaction information as Dataframe'''
return pd.json_normalize(self.transactions(accountId=accountId, type=type, symbol=symbol, startDate=startDate, endDate=endDate))
data = self.transactions(accountId=accountId, type=type, symbol=symbol, startDate=startDate, endDate=endDate)
return convert.transactions(data)

def search(self, symbol, projection='symbol-search'):
'''Search for a symbol
Expand All @@ -176,12 +173,7 @@ def search(self, symbol, projection='symbol-search'):

def searchDF(self, symbol, projection='symbol-search'):
'''search for symbol as a dataframe'''
ret = []
dat = self.search(symbol, projection)
for symbol in dat:
ret.append(dat[symbol])

return pd.DataFrame(ret)
return convert.search(self.search(symbol, projection))

def fundamentalSearch(self, symbol):
'''helper to search for a symbol using fundamental projection'''
Expand All @@ -201,7 +193,7 @@ def instrument(self, cusip):

def instrumentDF(self, cusip):
'''get instrument info from cusip as dataframe'''
return pd.DataFrame(self.instrument(cusip))
return convert.instrument(self.instrument(cusip))

def quote(self, symbol):
'''get quote for symbol
Expand All @@ -217,9 +209,7 @@ def quote(self, symbol):

def quoteDF(self, symbol):
'''get quote, format as dataframe'''
x = self.quote(symbol)

return pd.DataFrame(x).T.reset_index(drop=True)
return convert.quote(self.quote(symbol))

def history(self, symbol,
periodType=None, period=None,
Expand Down Expand Up @@ -262,11 +252,7 @@ def history(self, symbol,

def historyDF(self, symbol, **kwargs):
'''get history as dataframe'''
x = self.history(symbol, **kwargs)
df = pd.DataFrame(x['candles'])
df['datetime'] = pd.to_datetime(df['datetime'], unit='ms')

return df
return convert.history(self.history(symbol, **kwargs))

def options(self,
symbol,
Expand Down Expand Up @@ -389,36 +375,23 @@ def optionsDF(self,
expMonth='ALL',
optionType='ALL'):
'''return options chain as dataframe'''
ret = []
dat = self.options(symbol=symbol,
contractType=contractType,
strikeCount=strikeCount,
includeQuotes=includeQuotes,
strategy=strategy,
interval=interval,
strike=strike,
range=range,
fromDate=fromDate,
toDate=toDate,
volatility=volatility,
underlyingPrice=underlyingPrice,
interestRate=interestRate,
daysToExpiration=daysToExpiration,
expMonth=expMonth,
optionType=optionType)
for date in dat['callExpDateMap']:
for strike in dat['callExpDateMap'][date]:
ret.extend(dat['callExpDateMap'][date][strike])
for date in dat['putExpDateMap']:
for strike in dat['putExpDateMap'][date]:
ret.extend(dat['putExpDateMap'][date][strike])

df = pd.DataFrame(ret)
for col in ('tradeTimeInLong', 'quoteTimeInLong',
'expirationDate', 'lastTradingDay'):
df[col] = pd.to_datetime(df[col], unit='ms')

return df
data = self.options(symbol=symbol,
contractType=contractType,
strikeCount=strikeCount,
includeQuotes=includeQuotes,
strategy=strategy,
interval=interval,
strike=strike,
range=range,
fromDate=fromDate,
toDate=toDate,
volatility=volatility,
underlyingPrice=underlyingPrice,
interestRate=interestRate,
daysToExpiration=daysToExpiration,
expMonth=expMonth,
optionType=optionType)
return convert.options(data)

def movers(self, index, direction='up', change='percent'):
'''request market movers
Expand Down
75 changes: 75 additions & 0 deletions tdameritrade/convert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#
# Convert API responses to Pandas DataFrames
#

import pandas as pd


def accounts(data):
"""accounts as dataframe"""
account_dataframes = []
for accountId, value in data.items():
account_dataframes.append(pd.io.json.json_normalize(value))
account_dataframes[-1].columns = [
c.replace("securitiesAccount.", "")
for c in account_dataframes[-1].columns
]
return pd.concat(account_dataframes)


def transactions(data):
"""transaction information as Dataframe"""
return pd.json_normalize(data)


def search(data):
"""search for symbol as a dataframe"""
ret = []
for symbol in data:
ret.append(data[symbol])

return pd.DataFrame(ret)


def instrument(data):
"""instrument info from cusip as dataframe"""
return pd.DataFrame(data)


def quote(data):
"""quote as dataframe"""
return pd.DataFrame(data).T.reset_index(drop=True)


def history(data):
"""get history as dataframe"""
df = pd.DataFrame(data["candles"])
df["datetime"] = pd.to_datetime(df["datetime"], unit="ms")
return df


def options(data):
"""options chain as dataframe"""
ret = []
for date in data["callExpDateMap"]:
for strike in data["callExpDateMap"][date]:
ret.extend(data["callExpDateMap"][date][strike])
for date in data["putExpDateMap"]:
for strike in data["putExpDateMap"][date]:
ret.extend(data["putExpDateMap"][date][strike])

df = pd.DataFrame(ret)
for col in (
"tradeTimeInLong",
"quoteTimeInLong",
"expirationDate",
"lastTradingDay",
):
if col in df.columns:
df[col] = pd.to_datetime(df[col], unit="ms")

for col in ("delta", "gamma", "theta", "vega", "rho", "volatility"):
if col in df.columns:
df[col] = pd.to_numeric(df[col], errors="coerce")

return df