Skip to content

Add method mpf.kwarg_help() to print kwargs information. #416

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

Merged
merged 15 commits into from
Jan 11, 2022
Merged
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ __pycache__
.tox/
.cache/
*.code-workspace
examples/.ipynb_checkpoints/
examples/scratch_pad/.ipynb_checkpoints/
3 changes: 2 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
- documentation (replace old `https://matplotlib.org/api/finance_api.html`)
- make code more efficient (ex: tlines reconstructing data frame).
- **daily plot slower than intraday ???**
- add 'description' to valid kwargs table, and kwarg to print all kwargs information (kwarg and short description).
- add kwarg to print all kwargs information (kwarg and short description).
- fill the 'Description' fields in the kwarg dicts of these functions: `egrep -i 'def .*valid.*kwarg' *.py`

116 changes: 116 additions & 0 deletions examples/scratch_pad/fmtr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
####################################################################
#
# https://stackoverflow.com/questions/25777037/how-can-i-left-justify-text-in-a-pandas-dataframe-column-in-an-ipython-notebook
#
####################################################################

import mplfinance as mpf
import pandas as pd
import textwrap

vk = mpf.plotting._valid_plot_kwargs()

df = (pd.DataFrame(vk).T.head(18)).drop('Validator',axis=1)

df['Kwarg'] = df.index.values
df['Default'] = ["'"+d+"'" if isinstance(d,str) else str(d) for d in df['Default']]

df = df[['Kwarg','Default','Description']]
df = df.head(5).append(df.tail(7))

# df.sort_index(inplace=True)

df

print('===========================')

print(df)

print('===========================')

def make_left_formatter(maxwidth):
wm3 = maxwidth-3
w = maxwidth
def left_formatter(value):
if not isinstance(value,str):
return f'{value:<}'
elif value[0:maxwidth] == '-'*maxwidth:
return f'{value:<{w}.{w}s}'
#elif len(value) > maxwidth and value[0:maxwidth] != '-'*maxwidth:
elif len(value) > maxwidth:
return f'{value:<{wm3}.{wm3}s}...'
else:
return f'{value:<{w}.{w}s}'
return left_formatter

def df_wrapcols(df,wrap_columns=None):

if wrap_columns is None: return df
if not isinstance(wrap_columns,dict):
raise TypeError('wrap_columns must be a dict of column_names and wrap_lengths')

for col in wrap_columns:
if col not in df.columns:
raise ValueError('column "'+str(col)+'" not found in df.columns')

index = []
column_data = {}
for col in df.columns:
column_data[col] = []

for ix in df.index:
row = df.loc[ix,]

row_data = {}
for col in row.index:
cstr = str(row[col])
if col in wrap_columns:
wlen = wrap_columns[col]
tw = textwrap.wrap(cstr,wlen) if not cstr.isspace() else [' ']
else:
tw = [cstr]
row_data[col] = tw

cmax = max(row_data,key=lambda k: len(row_data[k]))
rlen = len(row_data[cmax])
for r in range(rlen):
for col in row.index:
extension = [' ']*(rlen - len(row_data[col]))
row_data[col].extend(extension)
column_data[col].append(row_data[col][r])
ixstr = str(ix)+'.'+str(r) if r > 0 else str(ix)
index.append(ixstr)

return pd.DataFrame(column_data,index=index)

WRAPLEN = 55

df = df_wrapcols(df,wrap_columns={'Description':WRAPLEN})
print('===========================')
print('dfnew1=',df)


# print('===========================')
# df.columns = [ ' '+col for col in df.columns ]

dividers = []
for col in df.columns:
dividers.append('-'*int(df[col].str.len().max()))
dfd = pd.DataFrame(dividers).T
dfd.columns = df.columns
dfd.index = pd.Index(['---'])

print('===========================')

df = dfd.append(df)

fmts = {'Kwarg': make_left_formatter(df['Kwarg'].str.len().max()+1),
'Description': make_left_formatter(WRAPLEN),
'Default': make_left_formatter(8),
}
s = df.to_string(formatters=fmts,index=False,justify='left')

print('\n ',s.replace('\n','\n '))

print('===========================')

11 changes: 6 additions & 5 deletions src/mplfinance/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import mplfinance._mpf_warnings
from mplfinance.plotting import plot, make_addplot
from mplfinance._styles import make_mpf_style, make_marketcolors
from mplfinance._styles import available_styles, write_style_file
from mplfinance._version import __version__
from mplfinance._mplwraps import figure, show
from mplfinance.plotting import plot, make_addplot
from mplfinance._styles import make_mpf_style, make_marketcolors
from mplfinance._styles import available_styles, write_style_file
from mplfinance._version import __version__
from mplfinance._mplwraps import figure, show
from mplfinance._kwarg_help import kwarg_help
15 changes: 11 additions & 4 deletions src/mplfinance/_arg_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,13 +274,20 @@ def _kwarg_not_implemented(value):
raise NotImplementedError('kwarg NOT implemented.')

def _validate_vkwargs_dict(vkwargs):
# Check that we didn't make a typo in any of the things
# that should be the same for all vkwargs dict items:
"""
Check that we didn't make a typo in any of the things
that should be the same for all vkwargs dict items:

{kwarg : {'Default': ... , 'Description': ... , 'Validator': ...} }
"""
for key, value in vkwargs.items():
if len(value) != 2:
raise ValueError('Items != 2 in valid kwarg table, for kwarg "'+key+'"')
# has been changed to 3 to support descriptions
if len(value) != 3:
raise ValueError('Items != 3 in valid kwarg table, for kwarg "'+key+'"')
if 'Default' not in value:
raise ValueError('Missing "Default" value for kwarg "'+key+'"')
if 'Description' not in value:
raise ValueError('Missing "Description" value for kwarg "'+key+'"')
if 'Validator' not in value:
raise ValueError('Missing "Validator" function for kwarg "'+key+'"')

Expand Down
153 changes: 153 additions & 0 deletions src/mplfinance/_kwarg_help.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import mplfinance as mpf
import pandas as pd
import textwrap

def df_wrapcols(df,wrap_columns=None):

if wrap_columns is None: return df
if not isinstance(wrap_columns,dict):
raise TypeError('wrap_columns must be a dict of column_names and wrap_lengths')

for col in wrap_columns:
if col not in df.columns:
raise ValueError('column "'+str(col)+'" not found in df.columns')

index = []
column_data = {}
for col in df.columns:
column_data[col] = []

for ix in df.index:
row = df.loc[ix,]

row_data = {}
for col in row.index:
cstr = str(row[col])
if col in wrap_columns:
wlen = wrap_columns[col]
tw = textwrap.wrap(cstr,wlen) if not cstr.isspace() else [' ']
else:
tw = [cstr]
row_data[col] = tw

cmax = max(row_data,key=lambda k: len(row_data[k]))
rlen = len(row_data[cmax])
for r in range(rlen):
for col in row.index:
extension = [' ']*(rlen - len(row_data[col]))
row_data[col].extend(extension)
column_data[col].append(row_data[col][r])
ixstr = str(ix)+'.'+str(r) if r > 0 else str(ix)
index.append(ixstr)

return pd.DataFrame(column_data,index=index)

def make_left_formatter(maxwidth):
wm3 = maxwidth-3
w = maxwidth
def left_formatter(value):
if not isinstance(value,str):
return f'{value:<}'
elif value[0:maxwidth] == '-'*maxwidth:
return f'{value:<{w}.{w}s}'
elif len(value) > maxwidth:
return f'{value:<{wm3}.{wm3}s}...'
else:
return f'{value:<{w}.{w}s}'
return left_formatter


def kwarg_help( func_name=None, kwarg_names=None ):

func_kwarg_map = {
'plot' : mpf.plotting._valid_plot_kwargs,
'make_addplot' : mpf.plotting._valid_addplot_kwargs,
'make_marketcolors' : mpf._styles._valid_make_marketcolors_kwargs,
'make_mpf_style' : mpf._styles._valid_make_mpf_style_kwargs,
'renko_params' : mpf._utils._valid_renko_kwargs,
'pnf_params' : mpf._utils._valid_pnf_kwargs,
'lines' : mpf._utils._valid_lines_kwargs,
'scale_width_adjustment': mpf._widths._valid_scale_width_kwargs,
'update_width_config': mpf._widths._valid_update_width_kwargs,
}

func_kwarg_aliases = {
'addplot' : mpf.plotting._valid_addplot_kwargs,
'marketcolors' : mpf._styles._valid_make_marketcolors_kwargs,
'mpf_style' : mpf._styles._valid_make_mpf_style_kwargs,
'style' : mpf._styles._valid_make_mpf_style_kwargs,
'renko' : mpf._utils._valid_renko_kwargs,
'pnf' : mpf._utils._valid_pnf_kwargs,
'hlines' : mpf._utils._valid_lines_kwargs,
'alines' : mpf._utils._valid_lines_kwargs,
'tlines' : mpf._utils._valid_lines_kwargs,
'vlines' : mpf._utils._valid_lines_kwargs,
}

if func_name is None:
print('\nUsage: `kwarg_help(func_name)` or `kwarg_help(func_name,kwarg_names)`')
print(' kwarg_help is available for the following func_names:')
s = str(list(func_kwarg_map.keys()))
text = textwrap.wrap(s,68)
for t in text:
print(' ',t)
print()
return

fkmap = {**func_kwarg_map, **func_kwarg_aliases}

if func_name not in fkmap:
raise ValueError('Function name "'+func_name+'" NOT a valid function name')

if kwarg_names is not None and isinstance(kwarg_names,str):
kwarg_names = [ kwarg_names, ]

if ( kwarg_names is not None
and (not isinstance(kwarg_names,(list,tuple))
or not all([isinstance(k,str) for k in kwarg_names])
)
):
raise ValueError('kwarg_names must be a sequence (list,tuple) of strings')

vks = fkmap[func_name]()

df = (pd.DataFrame(vks).T).drop('Validator',axis=1)
df.index.name = 'Kwarg'
df.reset_index(inplace=True)

if kwarg_names is not None:
for k in kwarg_names:
if k not in df['Kwarg'].values:
print(' Warning: "'+k+'" is not a valid `kwarg_name` for `func_name` "'+func_name,'"')
df = df[ df['Kwarg'].isin(kwarg_names) ]
if len(df) < 1:
raise ValueError(' None of specified `kwarg_names` are valid for `func_name` "'+func_name,'"')

df['Default'] = ["'"+d+"'" if isinstance(d,str) else str(d) for d in df['Default']]

klen = df['Kwarg'].str.len().max()+1
dlen = df['Default'].str.len().max()+1

wraplen = max( 40, 80-(klen+dlen) )
df = df_wrapcols(df,wrap_columns={'Description':wraplen})

dividers = []
for col in df.columns:
dividers.append('-'*int(df[col].str.len().max()))
dfd = pd.DataFrame(dividers).T
dfd.columns = df.columns
dfd.index = pd.Index(['---'])

df = dfd.append(df)

formatters = { 'Kwarg' : make_left_formatter( klen ),
'Default' : make_left_formatter( dlen ),
'Description' : make_left_formatter( wraplen ),
}

print('\n ','-'*78)
print(' Kwargs for func_name "'+func_name+'":')

s = df.to_string(formatters=formatters,index=False,justify='left')

print('\n ',s.replace('\n','\n '))
Loading