Skip to content
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
76 changes: 76 additions & 0 deletions .github/workflows/mplfinance_checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: mplfinance Checks
on: [ push, pull_request ]
jobs:
Regression_Tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8, 3.9]
steps:
- name: Preliminary Information
run: |
echo "The job was automatically triggered by a ${{ github.event_name }} event."
echo "This job is now running on a ${{ runner.os }} server hosted by GitHub!"
echo "The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
echo " "
echo "github.ref = ${{ github.ref }}"
echo "github.sha = ${{ github.sha }}"
echo "github.event.pull_request.head.ref = ${{ github.event.pull_request.head.ref }}"
echo "github.event.pull_request.head.sha = ${{ github.event.pull_request.head.sha }}"
echo "github.event.pull_request.base.ref = ${{ github.event.pull_request.base.ref }}"
echo "github.event.pull_request.base.sha = ${{ github.event.pull_request.base.sha }}"
echo " "

- name: Check out repository code
uses: actions/checkout@v2

- run: echo "The ${{ github.repository }} repository has been cloned to the runner."

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi

- name: Install My Package
run: pip install .

- name: Run Pytest
run: python -m pytest

- run: echo "This job's status is ${{ job.status }}."

Pull_Request_Updates_Version:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Check out repository code
uses: actions/checkout@v2

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: '3.10'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install packaging

- name: Fetch base and head on PR
if: ${{ github.event.pull_request.base.sha }}
run: |
git fetch origin master ${{ github.event.pull_request.base.sha }}
git fetch origin master ${{ github.event.pull_request.head.sha }}

- name: Check that Pull Request includes updating the Version
run: |
git show ${{ github.event.pull_request.base.sha }}:src/mplfinance/_version.py > scripts/tv0.py
git show ${{ github.sha }}:src/mplfinance/_version.py > scripts/tv1.py
python scripts/version_update_check.py tv0 tv1

File renamed without changes.
21 changes: 21 additions & 0 deletions examples/mpf_demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import pandas as pd
import mplfinance as mpf

infile = 'data/yahoofinance-SPY-20200901-20210113.csv'

df = pd.read_csv(infile, index_col=0, parse_dates=True).iloc[0:60]

# mpf.plot(df,figscale=1.5,type='candle',mav=(10,20))




#mpf.plot(df,type='candle',figscale=1.5)

#df = pd.read_csv(infile, index_col=0, parse_dates=True).iloc[0:180]
#mpf.plot(df,type='renko',figscale=1.5)
#mpf.plot(df,type='pnf',figscale=1.5)

#mpf.plot(df,type='candle',figscale=1.5,mav=10)

mpf.plot(df,type='candle',volume=True,mav=(10,20),figscale=1.5)
20 changes: 20 additions & 0 deletions examples/mpf_rsi_demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import pandas as pd
import mplfinance as mpf

infile = 'data/yahoofinance-SPY-20200901-20210113.csv'

df = pd.read_csv(infile, index_col=0, parse_dates=True).iloc[0:60]

import rsi
df['rsi'] = rsi.relative_strength(df['Close'],n=7)

print(df.head())
print(df.tail())

apd = mpf.make_addplot(df['rsi'],panel=2,color='lime',ylim=(10,90),secondary_y=True)

mpf.plot(df,type='candle',volume=True,mav=(10,20),figscale=1.5,addplot=apd,panel_ratios=(1,0.6))
mpf.plot(df,type='candle',style='charles',volume=True,mav=(10,20),figscale=1.5,addplot=apd,panel_ratios=(1,0.6))
mpf.plot(df,type='candle',style='mike',volume=True,mav=(10,20),figscale=1.5,addplot=apd,panel_ratios=(1,0.6))
mpf.plot(df,type='candle',style='checkers',volume=True,mav=(10,20),figscale=1.5,addplot=apd,panel_ratios=(1,0.6))
mpf.plot(df,type='candle',style='yahoo',volume=True,mav=(10,20),figscale=1.5,addplot=apd,panel_ratios=(1,0.6))
32 changes: 32 additions & 0 deletions examples/rsi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import numpy as np
def relative_strength(prices, n=14):
"""
compute the n period relative strength indicator
http://stockcharts.com/school/doku.php?id=chart_school:glossary_r#relativestrengthindex
http://www.investopedia.com/terms/r/rsi.asp
"""
deltas = np.diff(prices)
seed = deltas[:n + 1]
up = seed[seed >= 0].sum() / n
down = -seed[seed < 0].sum() / n
rs = up / down
rsi = np.zeros_like(prices)
rsi[:n] = 100. - 100. / (1. + rs)

for i in range(n, len(prices)):
delta = deltas[i - 1] # cause the diff is 1 shorter

if delta > 0:
upval = delta
downval = 0.
else:
upval = 0.
downval = -delta

up = (up * (n - 1) + upval) / n
down = (down * (n - 1) + downval) / n

rs = up / down
rsi[i] = 100. - 100. / (1. + rs)

return rsi
54 changes: 54 additions & 0 deletions examples/scratch_pad/issues/issue436.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from select import select
from datetime import datetime

import time
import pandas as pd
import mplfinance as mpf
import sys

coin = 'BTC'
bot_status = 'trading'

def limit():
timeout = 2.5
print(end='')
rlist, _, _ = select([sys.stdin], [], [], timeout)
print('rlist=',rlist)
if rlist:
s = sys.stdin.readline().strip()
print('s=',s)
if s == 'g':
print('\033[1;34m show chart')
chart()


def dataframe():
# response = **_api exchange_**.candles(coin + '-EUR', '1m', {})
# ohlcv = []
# for s in range(len(response)):
# timestamp = (int(response[s][0]))/1000
# open = float(response[s][1])
# high = float(response[s][2])
# low = float(response[s][3])
# close = float(response[s][4])
# volume = float(response[s][5])
# candles = {'timestamp': (datetime.utcfromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')), 'open': open, 'high': high, 'low': low, 'close': close, 'volume': volume}
# ohlcv.append(candles)
# dataframe = pd.DataFrame(data=ohlcv, dtype=float)
dataframe = pd.read_csv('../../data/SP500_NOV2019_Hist.csv',index_col=0, parse_dates=True)
return dataframe


def chart():
df = dataframe()
df.index = pd.DatetimeIndex(df['timestamp'])
df = df.iloc[::-1]
s = mpf.make_mpf_style(base_mpf_style='charles', gridcolor='#555555', gridstyle="--", rc={'axes.edgecolor': 'white', 'font.size': 5})
fig, axlist = mpf.plot(df, type='candle', style=s, title= coin, ylabel = 'Price (€)', volume=True, warn_too_much_data=9999999, returnfig=True)
mpf.show(block=True)


# trade loop
while bot_status == 'trading':
limit()
print('test')
15 changes: 15 additions & 0 deletions examples/scratch_pad/issues/issue438.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import mplfinance as mpf
import pandas as pd

#daily = pd.read_csv('/Users/jsb/Desktop/mplfinance-master/examples/data/SP500_NOV2019_Hist.csv',
# index_col=0, parse_dates=True)
daily = pd.read_csv('../../data/SP500_NOV2019_Hist.csv',
index_col=0, parse_dates=True)
daily.index.name = 'Date'
# print(daily.shape)
print(daily)
# daily = daily.loc[:, ['Open', 'High', 'Low', 'Close', 'Volume']]

mpf.figure(figsize=(20, 8), dpi=100)

mpf.plot(daily, type='candle', tight_layout=True)
108 changes: 108 additions & 0 deletions examples/scratch_pad/issues/so68871906.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
### !pip install yfinance
### !pip install mplfinance
import yfinance as yf
import mplfinance as mpf
import numpy as np
import pandas as pd

# get the data from yfiance
df=yf.download('BTC-USD',start='2008-01-04',end='2021-06-3',interval='1d')

#code snippet 5.1
# Fit linear regression on close
# Return the t-statistic for a given parameter estimate.
def tValLinR(close):
#tValue from a linear trend
x = np.ones((close.shape[0],2))
x[:,1] = np.arange(close.shape[0])
ols = sm1.OLS(close, x).fit()
return ols.tvalues[1]

#code snippet 5.2
'''
#search for the maximum absolutet-value. To identify the trend
# - molecule - index of observations we wish to labels.
# - close - which is the time series of x_t
# - span - is the set of values of L (look forward period) that the algorithm will #try (window_size)
# The L that maximizes |tHat_B_1| (t-value) is choosen - which is the look-forward #period
# with the most significant trend. (optimization)
'''
def getBinsFromTrend(molecule, close, span):

#Derive labels from the sign of t-value of trend line
#output includes:
# - t1: End time for the identified trend
# - tVal: t-value associated with the estimated trend coefficient
#- bin: Sign of the trend (1,0,-1)
#The t-statistics for each tick has a different look-back window.

#- idx start time in look-forward window
#- dt1 stop time in look-forward window
#- df1 is the look-forward window (window-size)
#- iloc ?

out = pd.DataFrame(index=molecule, columns=['t1', 'tVal', 'bin', 'windowSize'])
hrzns = range(*span)
windowSize = span[1] - span[0]
maxWindow = span[1]-1
minWindow = span[0]
for idx in close.index:
idx += (maxWindow*pd.Timedelta('1 day'))
if idx >= close.index[-1]:
break
df_tval = pd.Series(dtype='float64')
iloc0 = close.index.get_loc(idx)
if iloc0+max(hrzns) > close.shape[0]:
continue
for hrzn in hrzns:
dt1 = close.index[iloc0-hrzn+1]
df1 = close.loc[dt1:idx]
df_tval.loc[dt1] = tValLinR(df1.values) #calculates t-statistics on period
dt1 = df_tval.replace([-np.inf, np.inf, np.nan], 0).abs().idxmax() #get largest t-statistics calculated over span period

print(df_tval.index[-1])
print(dt1)
print(abs(df_tval.values).argmax() + minWindow)
out.loc[idx, ['t1', 'tVal', 'bin', 'windowSize']] = df_tval.index[-1], df_tval[dt1], np.sign(df_tval[dt1]), abs(df_tval.values).argmax() + minWindow #prevent leakage
out['t1'] = pd.to_datetime(out['t1'])
out['bin'] = pd.to_numeric(out['bin'], downcast='signed')

#deal with massive t-Value outliers - they dont provide more confidence and they ruin the scatter plot
tValueVariance = out['tVal'].values.var()
tMax = 20
if tValueVariance < tMax:
tMax = tValueVariance

out.loc[out['tVal'] > tMax, 'tVal'] = tMax #cutoff tValues > 20
out.loc[out['tVal'] < (-1)*tMax, 'tVal'] = (-1)*tMax #cutoff tValues < -20
return out.dropna(subset=['bin'])

if __name__ == '__main__':
#snippet 5.3
idx_range_from = 3
idx_range_to = 10
df1 = getBinsFromTrend(df.index, df['Close'], [idx_range_from,idx_range_to,1]) #[3,10,1] = range(3,10) This is the issue
tValues = df1['tVal'].values #tVal

doNormalize = False
#normalise t-values to -1, 1
if doNormalize:
np.min(tValues)
minusArgs = [i for i in range(0, len(tValues)) if tValues[i] < 0]
tValues[minusArgs] = tValues[minusArgs] / (np.min(tValues)*(-1.0))

plus_one = [i for i in range(0, len(tValues)) if tValues[i] > 0]
tValues[plus_one] = tValues[plus_one] / np.max(tValues)

#+(idx_range_to-idx_range_from+1)
plt.scatter(df1.index, df0.loc[df1.index].values, c=tValues, cmap='viridis') #df1['tVal'].values, cmap='viridis')
plt.plot(df0.index, df0.values, color='gray')
plt.colorbar()
plt.show()
plt.savefig('fig5.2.png')
plt.clf()
plt.df['Close']()
plt.scatter(df1.index, df0.loc[df1.index].values, c=df1['bin'].values, cmap='vipridis')

#Test methods
ols_tvalue = tValLinR( np.array([3.0, 3.5, 4.0]) )
2 changes: 2 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[pytest]
python_files = tests/*
37 changes: 37 additions & 0 deletions scripts/version_update_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import os
import sys
import importlib
from packaging import version

if len(sys.argv) < 3:
raise RuntimeError('Got less than 2 Version Arguments!')

debug = True if (len(sys.argv) > 3 and sys.argv[3] == 'debug') else False

v0 = importlib.import_module(sys.argv[1])
pv0 = version.parse(v0.__version__)

v1 = importlib.import_module(sys.argv[2])
pv1 = version.parse(v1.__version__)

if debug:
print('sys.argv=',sys.argv)
print('v0=',v0)
print('v1=',v1)
print('pv0=',pv0)
print('pv1=',pv1)
# cmd='cat '+sys.argv[1]+'.py'
# print('os.system("'+cmd+'")')
# os.system(cmd)
# cmd='cat '+sys.argv[2]+'.py'
# print('os.system("'+cmd+'")')
# os.system(cmd)
print('v0.__version__=',v0.__version__)
print('v1.__version__=',v1.__version__)

if not pv1 > pv0:
print('ERROR: Pull Request requires mplfinance version to be updated: (Version '+str(pv1)+' is NOT greater than '+str(pv0)+')')
exit(1)
else:
print('Version was updated OK (from '+str(pv0)+' to '+str(pv1)+')')
exit(0)
2 changes: 1 addition & 1 deletion src/mplfinance/_version.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

version_info = (0, 12, 7, 'alpha', 18)
version_info = (0, 12, 8, 'beta', 0)

_specifier_ = {'alpha': 'a','beta': 'b','candidate': 'rc','final': ''}

Expand Down
2 changes: 1 addition & 1 deletion src/mplfinance/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def decorator(*args, **kwargs):

def _warn_no_xgaps_deprecated(value):
warnings.warn('\n\n ================================================================= '+
'\n\n WARNING: `no_xgaps` is deprecated:'+
'\n\n WARNING: `no_xgaps` is /deprecated/:'+
'\n Default value is now `no_xgaps=True`'+
'\n However, to set `no_xgaps=False` and silence this warning,'+
'\n use instead: `show_nontrading=True`.'+
Expand Down
Binary file modified tests/reference_images/addplot12.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.