From 5b1ac7b50515e26a82fcabde7625907cd0051b03 Mon Sep 17 00:00:00 2001 From: Dayal Chand Aichara Date: Wed, 30 Oct 2019 09:57:37 +0900 Subject: [PATCH] V-1.0.2 --- PriceIndices.egg-info/PKG-INFO | 4 +- .../price_indicators.cpython-36.pyc | Bin 10965 -> 11056 bytes PriceIndices/price_indicators.py | 106 ++++++++++-------- README.md | 8 +- dist/PriceIndices-1.0.2-py3-none-any.whl | Bin 0 -> 8935 bytes dist/PriceIndices-1.0.2.tar.gz | Bin 0 -> 7887 bytes setup.py | 4 +- 7 files changed, 65 insertions(+), 57 deletions(-) create mode 100644 dist/PriceIndices-1.0.2-py3-none-any.whl create mode 100644 dist/PriceIndices-1.0.2.tar.gz diff --git a/PriceIndices.egg-info/PKG-INFO b/PriceIndices.egg-info/PKG-INFO index bf9d67e..5164e28 100644 --- a/PriceIndices.egg-info/PKG-INFO +++ b/PriceIndices.egg-info/PKG-INFO @@ -1,12 +1,12 @@ Metadata-Version: 2.1 Name: PriceIndices -Version: 1.0.1 +Version: 1.0.2 Summary: A python package to get historical market data of cryptocurrencies from CoinMarketCap, and calculate & plot different indicators. Home-page: https://github.com/dc-aichara/Price-Indices Author: Dayal Chand Aichara Author-email: dc.aichara@gmail.com License: MIT -Download-URL: https://github.com/dc-aichara/PriceIndices/archive/v-1.0.1.tar.gz +Download-URL: https://github.com/dc-aichara/PriceIndices/archive/v-1.0.2.tar.gz Description: diff --git a/PriceIndices/__pycache__/price_indicators.cpython-36.pyc b/PriceIndices/__pycache__/price_indicators.cpython-36.pyc index 20d1bff0e6effadfb4d462260d1f36888858c16b..f8e40d6ec30e6c6e14858c2c19462effce6e3532 100644 GIT binary patch delta 1401 zcmb7@&u<$=6vyYy&hCykUMC^86Wb|G)PQVAA%%(qYKaid0U<>Z5seg4#E%Dv0SWB* z;FjGO$-O{iDb@S|ToB?|$bmZ&5?m0M3W*yR&Rjs^fW&uZ9alkcz$1I#yyw~3`RwQ2 zd+F}=R)|*^>;5lk${WQYS+V{$nT8^Xwp zMr4AKz&yI*e(z_M&&EC*HC!!j2-a1x=;Bh5ANm5yuCU|^i7WUGaiFoBZm9-8X7ZSN zuk=F`@hZ=b>1CORd4zeKDJI-WaS3PQ>3U$ zb&Ms9I%)f8t3hSE)w*EsR%^qj3bGPpWhUKY=1vXvY+f-(T8zb_S z@<@>A?t@FhC@r+< z9RkF}nx8H-*MFPRiBHwh&?fpfI<~de8J_lQ2@9wF`gCDc_P@fDR8V1!;(TDK|Z}#4KpV5jSV$;sfMhY4S>zIkeF->R%W+^I+OQ`Lm nQ|B~A_T$dQg^uh!juqP-+D7=E3+=a^55tY5ot(2L;1$F`Oh`a|3zkQPBmG%*o>#OTe0Xi!K{q9#v`tBF#20Nrg# z%8fKa<{#isz;N&{FvbH%E}p!Zc+i_?-%JYv@nR>tJM(>;nZD2azTKJIzwcg1Cf)Db z9~UoAZMkbOx3zJ8!o~PHEZCU9rKmf>5bUi$<1TD7%m6;#YFFm(D@ zznaI6=oD4@fYM#12anW&aZGfK!y|da3@ogm*MWydBqEd6cE}NEYmPD6B8{022X;(% z|Ev}PIlk=3+zXYv~&Vb=#4V_yY6SzVT% zUz6EVVRDKjmJ=YL5ArkyXyhTSp9A2~OpOG%dhW=@(%BYq)jx~wX}WIGwOl22^*6DG z5L80M+t8#beWD0x5|x99bu6OzQk)=w;!6wx9i;_En`+nKfxy!k*U)$*MoBOUb3zw{ zj>06Sh^ZiMMRBI`?AFCaFdmi$Nx| zdbyXhVeFxOaJq)6HwnPF%ncXEejP%v6$IrNN4rJgI0ivJ7_NaK_xv+0W94E9x7gx1 zC1rG-L1rg!sK(I!C8!5^8+6xDA4bMfYMu%eiG~PFETOF{Z$=iatx%vtg%@fkj3Ip* zRPrlR`iyGCkG(@X=hfEqYVQ#0N9wPoy1X%Rd)f>V*slo@D@{mfcce6-Q6gk(cX(K! zzi9Ue6(hT8@9vGXxaV|R%6{{-{^B(*%g41l<8i9`a#cCSRc+;hPwgY9iHbC@p1}02 dHsQ_Gpgu{j)8iFAq(An~oOG&gS#FPQ{sB!+{8Rt{ diff --git a/PriceIndices/price_indicators.py b/PriceIndices/price_indicators.py index 066d7f9..cca00f4 100644 --- a/PriceIndices/price_indicators.py +++ b/PriceIndices/price_indicators.py @@ -146,10 +146,11 @@ def get_rsi_graph(self, rsi_data): plt.suptitle('Price and Relative Strength Index', color='red', fontsize=24) plt.savefig('rsi.png', bbox_inches='tight', facecolor='orange') return plt.show() + except Exception as e: return e - def get_bollinger_bands(df, days=20): + def get_bollinger_bands(df, days=20, plot=None): """ Type: Trend, volatility, momentum indicator @@ -178,25 +179,27 @@ def get_bollinger_bands(df, days=20): data['plus'] = data['SMA'] + data['SD']*2 data['minus'] = data['SMA'] - data['SMA']*2 data1 = data.sort_values(by='date', ascending=False).reset_index(drop=True) - fig, ax = plt.subplots(figsize=(16, 12)) - plt.plot(data1['date'], data1['plus'], color='g') - plt.plot(data1['date'], data1['minus'], color='g') - plt.plot(data1['date'], data1['price'], color='orange') - plt.legend() - plt.xlabel('Time', color='b', fontsize=22) - plt.ylabel('Price', color='b', fontsize=22) - plt.title('Bollinger Bands', color='b', fontsize=27) - plt.tick_params(labelsize=17) - fig.set_facecolor('yellow') - plt.grid() - plt.savefig('bollinger_bands.png', bbox_inches='tight', facecolor='orange') - plt.show() + while plot: + fig, ax = plt.subplots(figsize=(16, 12)) + plt.plot(data1['date'], data1['plus'], color='g') + plt.plot(data1['date'], data1['minus'], color='g') + plt.plot(data1['date'], data1['price'], color='orange') + plt.legend() + plt.xlabel('Time', color='b', fontsize=22) + plt.ylabel('Price', color='b', fontsize=22) + plt.title('Bollinger Bands', color='b', fontsize=27) + plt.tick_params(labelsize=17) + fig.set_facecolor('yellow') + plt.grid() + plt.savefig('bollinger_bands.png', bbox_inches='tight', facecolor='orange') + plt.show() + break return data1 except Exception as e: return e - def get_moving_average_convergence_divergence(df): + def get_moving_average_convergence_divergence(df, plot=None): """ Type Trend and momentum indicator @@ -220,23 +223,24 @@ def get_moving_average_convergence_divergence(df): data['MACD'] = data['EMA_12'] - data['EMA_26'] data1 = data.dropna() - fig, ax = plt.subplots(figsize=(14, 9)) - plt.plot(data1['date'], data1['price'], color='r', label='Price') - plt.plot(data1['date'], data1['MACD'], color='b', label='MACD') - plt.legend() - plt.title('Price and MACD Plot', fontsize=28, color='b') - plt.xlabel('Time', color='b', fontsize=19) - plt.ylabel('Price', color='b', fontsize=19) - plt.savefig('macd.png', bbox_inches='tight', facecolor='orange') - fig.set_facecolor('orange') - plt.show() - + while plot: + fig, ax = plt.subplots(figsize=(14, 9)) + plt.plot(data1['date'], data1['price'], color='r', label='Price') + plt.plot(data1['date'], data1['MACD'], color='b', label='MACD') + plt.legend() + plt.title('Price and MACD Plot', fontsize=28, color='b') + plt.xlabel('Time', color='b', fontsize=19) + plt.ylabel('Price', color='b', fontsize=19) + plt.savefig('macd.png', bbox_inches='tight', facecolor='orange') + fig.set_facecolor('orange') + plt.show() + break return data1 except Exception as e: return print('MACD Error - {}'.format(e)) - def get_simple_moving_average(df, days=15): + def get_simple_moving_average(df, days=15, plot=None): """ Simple moving average of given days :param price_data: pandas DataFrame @@ -249,22 +253,24 @@ def get_simple_moving_average(df, days=15): data['SMA'] = data['price'].rolling(days).mean() data1 = data.dropna() data1 = data1.sort_values(by='date', ascending=False).reset_index(drop=True) - fig, ax = plt.subplots(figsize=(14, 9)) - plt.plot(data1['date'], data1['price'], color='r', label='Price') - plt.plot(data1['date'], data1['SMA'], color='b', label='SMA') - plt.legend() - plt.title('Price and SMA Plot', fontsize=28, color='b') - plt.xlabel('Time', color='b', fontsize=19) - plt.ylabel('Price', color='b', fontsize=19) - plt.savefig('sma.png', bbox_inches='tight', facecolor='orange') - fig.set_facecolor('orange') - plt.show() + while plot: + fig, ax = plt.subplots(figsize=(14, 9)) + plt.plot(data1['date'], data1['price'], color='r', label='Price') + plt.plot(data1['date'], data1['SMA'], color='b', label='SMA') + plt.legend() + plt.title('Price and SMA Plot', fontsize=28, color='b') + plt.xlabel('Time', color='b', fontsize=19) + plt.ylabel('Price', color='b', fontsize=19) + plt.savefig('sma.png', bbox_inches='tight', facecolor='orange') + fig.set_facecolor('orange') + plt.show() + break return data1 except Exception as e: return print('SMA Error - {}'.format(e)) - def get_exponential_moving_average(df, periods=[20]): + def get_exponential_moving_average(df, periods=[20], plot=None): """ The EMA is a moving average that places a greater weight and significance on the most recent data points. Like all moving averages, this technical indicator is used to produce buy and sell signals based on crossovers and divergences from the historical average. @@ -280,17 +286,19 @@ def get_exponential_moving_average(df, periods=[20]): data['EMA_{}'.format(period)] = data['price'].ewm(span=period, adjust=False).mean() data = data.dropna() data1 = data - fig, ax = plt.subplots(figsize=(14, 9)) - plt.plot(data1['date'], data1['price'], color='r', label='Price') - for period in periods: - plt.plot(data1['date'], data1['EMA_{}'.format(period)], label='EMA_{}'.format(period)) - plt.legend() - plt.title('Price and EMA Plot', fontsize=28, color='b') - plt.xlabel('Time', color='b', fontsize=19) - plt.ylabel('Price/EMA', color='b', fontsize=19) - plt.savefig('ema.png', bbox_inches='tight', facecolor='orange') - fig.set_facecolor('orange') - plt.show() + while plot: + fig, ax = plt.subplots(figsize=(14, 9)) + plt.plot(data1['date'], data1['price'], color='r', label='Price') + for period in periods: + plt.plot(data1['date'], data1['EMA_{}'.format(period)], label='EMA_{}'.format(period)) + plt.legend() + plt.title('Price and EMA Plot', fontsize=28, color='b') + plt.xlabel('Time', color='b', fontsize=19) + plt.ylabel('Price/EMA', color='b', fontsize=19) + plt.savefig('ema.png', bbox_inches='tight', facecolor='orange') + fig.set_facecolor('orange') + plt.show() + break return data1 except Exception as e: diff --git a/README.md b/README.md index 4071e27..2b2298c 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ This will return a plot of RSI against time and also save RSI plot in your worki - #### Get Bollinger Bands and its plot ```python ->>> df_bb = Indices.get_bollinger_bands(price_data , 20) +>>> df_bb = Indices.get_bollinger_bands(price_data , 20, plot=True) >>> df_bb.tail() date price SMA SD pluse minus 2243 2013-05-02 105.21 115.2345 6.339257 127.913013 -115.2345 @@ -136,7 +136,7 @@ This will also save Bollingers bands plot in your working directory as 'bollinge ```python ->>> df_macd = Indices.get_moving_average_convergence_divergence(price_data) +>>> df_macd = Indices.get_moving_average_convergence_divergence(price_data, plot=True) """This will return a pandas DataFrame and save EMA plot as 'macd.png' in working directory. """" >>> df_macd.head() @@ -154,7 +154,7 @@ This will also save Bollingers bands plot in your working directory as 'bollinge - #### Get Simple Moving Average (SMA) and its plot ```python ->>> df_sma = Indices.get_simple_moving_average(price_data, 20) +>>> df_sma = Indices.get_simple_moving_average(price_data, 20, plot=True) """This will return a pandas DataFrame and save EMA plot as 'sma.png' in working directory. """" >>> df_sma.head() @@ -172,7 +172,7 @@ This will also save Bollingers bands plot in your working directory as 'bollinge - ### Get Exponential Moving Average (EMA) and its plot ```python ->>> df_ema = Indices.get_exponential_moving_average(price_data, [20,70]) +>>> df_ema = Indices.get_exponential_moving_average(price_data, [20,70], plot=True) """This will return a pandas DataFrame and save EMA plot as 'ema.png' in working directory. """" diff --git a/dist/PriceIndices-1.0.2-py3-none-any.whl b/dist/PriceIndices-1.0.2-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..38e90eb43ee03a68fe16fb3a3b7cd1e4ae98257d GIT binary patch literal 8935 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 K6h)FhdjA26N*a{_ literal 0 HcmV?d00001 diff --git a/dist/PriceIndices-1.0.2.tar.gz b/dist/PriceIndices-1.0.2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..af9b69098553fd551ce9cfb9b3b83c883c6d9401 GIT binary patch literal 7887 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