ENH strategy col_names support ENH classic linreg util TST strategies update

This commit is contained in:
Kevin Johnson
2020-09-25 09:18:46 -07:00
parent 591d5a474d
commit 3eee8901bf
11 changed files with 515 additions and 272 deletions
+1
View File
@@ -128,6 +128,7 @@ data/tulip.csv
examples/cache.sqlite
examples/taplot.py
examples/alpaca_trader.py
examples/ChartTA.ipynb
examples/charting.ipynb
examples/ib_trader.ipynb
+9 -9
View File
@@ -45,7 +45,7 @@
"Numpy v1.18.3\n",
"Pandas v1.1.0\n",
"mplfinance v0.12.6a3\n",
"Pandas TA v0.2.08b\n"
"Pandas TA v0.2.12b\n"
]
}
],
@@ -91,7 +91,7 @@
" # All Data: 0, Last Four Years: 0.25, Last Two Years: 0.5, This Year: 1, Last Half Year: 2, Last Quarter: 4\n",
" yearly_divisor = {\"all\": 0, \"10y\": 0.1, \"5y\": 0.2, \"4y\": 0.25, \"3y\": 1./3, \"2y\": 0.5, \"1y\": 1, \"6mo\": 2, \"3mo\": 4}\n",
" yd = yearly_divisor[tf] if tf in yearly_divisor.keys() else 0\n",
" return int(ta.TRADING_DAYS_PER_YEAR / yd) if yd > 0 else df.shape[0]"
" return int(ta.RATE[\"TRADING_DAYS_PER_YEAR\"] / yd) if yd > 0 else df.shape[0]"
]
},
{
@@ -112,13 +112,13 @@
"text": [
"[!] Loading All: SPY, QQQ, AAPL, TSLA\n",
"[i] Loaded['D']: SPY_D.csv\n",
"[i] Runtime: 812.7898 ms (0.8128 s)\n",
"[i] Runtime: 1812.7836 ms (1.8128 s)\n",
"[i] Loaded['D']: QQQ_D.csv\n",
"[i] Runtime: 818.7984 ms (0.8188 s)\n",
"[i] Runtime: 1747.0058 ms (1.7470 s)\n",
"[i] Loaded['D']: AAPL_D.csv\n",
"[i] Runtime: 1227.1223 ms (1.2271 s)\n",
"[i] Runtime: 1105.7967 ms (1.1058 s)\n",
"[i] Loaded['D']: TSLA_D.csv\n",
"[i] Runtime: 1858.9133 ms (1.8589 s)\n"
"[i] Runtime: 906.7782 ms (0.9068 s)\n"
]
}
],
@@ -353,7 +353,7 @@
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x11196a5b0>"
"<matplotlib.axes._subplots.AxesSubplot at 0x11a0cc880>"
]
},
"execution_count": 9,
@@ -396,7 +396,7 @@
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x11d8d3fd0>"
"<matplotlib.axes._subplots.AxesSubplot at 0x11a779940>"
]
},
"execution_count": 10,
@@ -441,7 +441,7 @@
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x11d9e70d0>"
"<matplotlib.axes._subplots.AxesSubplot at 0x10e090670>"
]
},
"execution_count": 11,
+191 -44
View File
@@ -85,7 +85,7 @@
"text": [
"name = All\n",
"description = All the indicators with their default settings. Pandas TA default.\n",
"created = 09/13/2020, 15:34:25\n",
"created = 09/25/2020, 07:53:11\n",
"ta = None\n"
]
}
@@ -116,7 +116,7 @@
"text": [
"name = Common Price and Volume SMAs\n",
"description = Common Price SMAs: 10, 20, 50, 200 and Volume SMA: 20.\n",
"created = 09/13/2020, 15:34:25\n",
"created = 09/25/2020, 07:53:11\n",
"ta = [{'kind': 'sma', 'length': 10}, {'kind': 'sma', 'length': 20}, {'kind': 'sma', 'length': 50}, {'kind': 'sma', 'length': 200}, {'kind': 'sma', 'close': 'volume', 'length': 20, 'prefix': 'VOL'}]\n"
]
}
@@ -158,7 +158,7 @@
{
"data": {
"text/plain": [
"Strategy(name='A', ta=[{'kind': 'sma', 'length': 50}, {'kind': 'sma', 'length': 200}], description=None, created='09/13/2020, 15:34:25', last_run=None, run_time=None)"
"Strategy(name='A', ta=[{'kind': 'sma', 'length': 50}, {'kind': 'sma', 'length': 200}], description=None, created='09/25/2020, 07:53:11')"
]
},
"execution_count": 4,
@@ -186,7 +186,7 @@
{
"data": {
"text/plain": [
"Strategy(name='B', ta=[{'kind': 'ema', 'length': 8}, {'kind': 'ema', 'length': 21}, {'kind': 'log_return', 'cumulative': True}, {'kind': 'rsi'}, {'kind': 'supertrend'}], description=None, created='09/13/2020, 15:34:25', last_run=None, run_time=None)"
"Strategy(name='B', ta=[{'kind': 'ema', 'length': 8}, {'kind': 'ema', 'length': 21}, {'kind': 'log_return', 'cumulative': True}, {'kind': 'rsi'}, {'kind': 'supertrend'}], description=None, created='09/25/2020, 07:53:11')"
]
},
"execution_count": 5,
@@ -214,7 +214,7 @@
{
"data": {
"text/plain": [
"Strategy(name='Runtime Failure', ta=[{'kind': 'percet_return'}], description=None, created='09/13/2020, 15:34:25', last_run=None, run_time=None)"
"Strategy(name='Runtime Failure', ta=[{'kind': 'percet_return'}], description=None, created='09/25/2020, 07:53:11')"
]
},
"execution_count": 6,
@@ -348,20 +348,23 @@
"class Watchlist(builtins.object)\n",
" | Watchlist(tickers: list, tf: str = None, name: str = None, strategy: pandas_ta.core.Strategy = None, ds: object = None, **kwargs)\n",
" | \n",
" | Watchlist Class (** This is subject to change! **)\n",
" | ============================================================================\n",
" | # Watchlist Class (** This is subject to change! **)\n",
" | A simple Class to load/download financial market data and automatically\n",
" | apply Technical Analysis indicators with a Pandas TA Strategy. Default\n",
" | Strategy: pandas_ta.AllStrategy.\n",
" | apply Technical Analysis indicators with a Pandas TA Strategy.\n",
" | \n",
" | Requirements:\n",
" | Default Strategy: pandas_ta.AllStrategy.\n",
" | \n",
" | ## Package Support:\n",
" | ### Data Source (Default: AlphaVantage)\n",
" | - AlphaVantage (pip install alphaVantage-api).\n",
" | - Python Binance (pip install python-binance). # Future Support\n",
" | - Yahoo Finance (pip install yfinance). # Almost Supported\n",
" | \n",
" | # Technical Analysis:\n",
" | - Pandas TA (pip install pandas_ta)\n",
" | - AlphaVantage (pip install alphaVantage-api) for the Default Data Source.\n",
" | To use another Data Source, update the load() method after AV.\n",
" | \n",
" | Required Arguments:\n",
" | ## Required Arguments:\n",
" | - tickers: A list of strings containing tickers. Example: ['SPY', 'AAPL']\n",
" | ============================================================================\n",
" | \n",
" | Methods defined here:\n",
" | \n",
@@ -435,12 +438,42 @@
"text": [
"[!] Loading All: SPY, IWM\n",
"[i] Loaded['D']: SPY_D.csv\n",
" open high low close volume\n",
"date \n",
"1999-11-01 136.5000 137.0000 135.5625 135.5625 4006500.0\n",
"1999-11-02 135.9687 137.2500 134.5937 134.5937 6516900.0\n",
"1999-11-03 136.0000 136.3750 135.1250 135.5000 7222300.0\n",
"1999-11-04 136.7500 137.3593 135.7656 136.5312 7907500.0\n",
"1999-11-05 138.6250 139.1093 136.7812 137.8750 7431500.0\n",
"... ... ... ... ... ...\n",
"2020-08-24 342.1200 343.0000 339.4504 342.9200 48588662.0\n",
"2020-08-25 343.5300 344.2100 342.2700 344.1200 38463381.0\n",
"2020-08-26 344.7600 347.8600 344.1700 347.5700 50790237.0\n",
"2020-08-27 348.5100 349.9000 346.5300 348.3300 58034142.0\n",
"2020-08-28 349.4400 350.7200 348.1500 350.5800 48588940.0\n",
"\n",
"[5241 rows x 5 columns]\n",
"[+] Strategy: Common Price and Volume SMAs\n",
"[i] Indicator arguments: {'timed': False, 'append': True}\n",
"[i] Multiprocessing: 4 of 4 cores.\n",
"[i] Total indicators: 5\n",
"[i] Columns added: 5\n",
"[i] Loaded['D']: IWM_D.csv\n",
" open high low close volume\n",
"date \n",
"2000-05-26 91.06 91.44 90.630 91.44 37400.0\n",
"2000-05-30 92.75 94.81 92.750 94.81 28800.0\n",
"2000-05-31 95.13 96.38 95.130 95.75 18000.0\n",
"2000-06-01 97.11 97.31 97.110 97.31 3500.0\n",
"2000-06-02 101.70 102.40 101.700 102.40 14700.0\n",
"... ... ... ... ... ...\n",
"2020-08-31 157.19 157.37 155.300 155.43 17051511.0\n",
"2020-09-01 155.22 157.31 154.450 157.21 15654144.0\n",
"2020-09-02 157.96 158.98 156.175 158.46 16763449.0\n",
"2020-09-03 158.12 158.29 152.960 153.78 32117585.0\n",
"2020-09-04 155.71 155.89 149.290 152.80 30618783.0\n",
"\n",
"[5102 rows x 5 columns]\n",
"[+] Strategy: Common Price and Volume SMAs\n",
"[i] Indicator arguments: {'timed': False, 'append': True}\n",
"[i] Multiprocessing: 4 of 4 cores.\n",
@@ -810,7 +843,7 @@
{
"data": {
"text/plain": [
"Strategy(name='A', ta=[{'kind': 'sma', 'length': 50}, {'kind': 'sma', 'length': 200}], description=None, created='09/13/2020, 15:34:25', last_run=None, run_time=None)"
"Strategy(name='A', ta=[{'kind': 'sma', 'length': 50}, {'kind': 'sma', 'length': 200}], description=None, created='09/25/2020, 07:53:11')"
]
},
"execution_count": 14,
@@ -834,7 +867,22 @@
"name": "stdout",
"output_type": "stream",
"text": [
"[i] Loaded['D']: IWM_D.csv\n"
"[i] Loaded['D']: IWM_D.csv\n",
" open high low close volume\n",
"date \n",
"2000-05-26 91.06 91.44 90.630 91.44 37400.0\n",
"2000-05-30 92.75 94.81 92.750 94.81 28800.0\n",
"2000-05-31 95.13 96.38 95.130 95.75 18000.0\n",
"2000-06-01 97.11 97.31 97.110 97.31 3500.0\n",
"2000-06-02 101.70 102.40 101.700 102.40 14700.0\n",
"... ... ... ... ... ...\n",
"2020-08-31 157.19 157.37 155.300 155.43 17051511.0\n",
"2020-09-01 155.22 157.31 154.450 157.21 15654144.0\n",
"2020-09-02 157.96 158.98 156.175 158.46 16763449.0\n",
"2020-09-03 158.12 158.29 152.960 153.78 32117585.0\n",
"2020-09-04 155.71 155.89 149.290 152.80 30618783.0\n",
"\n",
"[5102 rows x 5 columns]\n"
]
},
{
@@ -1035,7 +1083,7 @@
{
"data": {
"text/plain": [
"Strategy(name='B', ta=[{'kind': 'ema', 'length': 8}, {'kind': 'ema', 'length': 21}, {'kind': 'log_return', 'cumulative': True}, {'kind': 'rsi'}, {'kind': 'supertrend'}], description=None, created='09/13/2020, 15:34:25', last_run=None, run_time=None)"
"Strategy(name='B', ta=[{'kind': 'ema', 'length': 8}, {'kind': 'ema', 'length': 21}, {'kind': 'log_return', 'cumulative': True}, {'kind': 'rsi'}, {'kind': 'supertrend'}], description=None, created='09/25/2020, 07:53:11')"
]
},
"execution_count": 16,
@@ -1058,7 +1106,22 @@
"name": "stdout",
"output_type": "stream",
"text": [
"[i] Loaded['D']: SPY_D.csv\n"
"[i] Loaded['D']: SPY_D.csv\n",
" open high low close volume\n",
"date \n",
"1999-11-01 136.5000 137.0000 135.5625 135.5625 4006500.0\n",
"1999-11-02 135.9687 137.2500 134.5937 134.5937 6516900.0\n",
"1999-11-03 136.0000 136.3750 135.1250 135.5000 7222300.0\n",
"1999-11-04 136.7500 137.3593 135.7656 136.5312 7907500.0\n",
"1999-11-05 138.6250 139.1093 136.7812 137.8750 7431500.0\n",
"... ... ... ... ... ...\n",
"2020-08-24 342.1200 343.0000 339.4504 342.9200 48588662.0\n",
"2020-08-25 343.5300 344.2100 342.2700 344.1200 38463381.0\n",
"2020-08-26 344.7600 347.8600 344.1700 347.5700 50790237.0\n",
"2020-08-27 348.5100 349.9000 346.5300 348.3300 58034142.0\n",
"2020-08-28 349.4400 350.7200 348.1500 350.5800 48588940.0\n",
"\n",
"[5241 rows x 5 columns]\n"
]
},
{
@@ -1365,7 +1428,7 @@
{
"data": {
"text/plain": [
"Strategy(name='Runtime Failure', ta=[{'kind': 'percet_return'}], description=None, created='09/13/2020, 15:34:25', last_run=None, run_time=None)"
"Strategy(name='Runtime Failure', ta=[{'kind': 'percet_return'}], description=None, created='09/25/2020, 07:53:11')"
]
},
"execution_count": 18,
@@ -1389,6 +1452,21 @@
"output_type": "stream",
"text": [
"[i] Loaded['D']: IWM_D.csv\n",
" open high low close volume\n",
"date \n",
"2000-05-26 91.06 91.44 90.630 91.44 37400.0\n",
"2000-05-30 92.75 94.81 92.750 94.81 28800.0\n",
"2000-05-31 95.13 96.38 95.130 95.75 18000.0\n",
"2000-06-01 97.11 97.31 97.110 97.31 3500.0\n",
"2000-06-02 101.70 102.40 101.700 102.40 14700.0\n",
"... ... ... ... ... ...\n",
"2020-08-31 157.19 157.37 155.300 155.43 17051511.0\n",
"2020-09-01 155.22 157.31 154.450 157.21 15654144.0\n",
"2020-09-02 157.96 158.98 156.175 158.46 16763449.0\n",
"2020-09-03 158.12 158.29 152.960 153.78 32117585.0\n",
"2020-09-04 155.71 155.89 149.290 152.80 30618783.0\n",
"\n",
"[5102 rows x 5 columns]\n",
"[X] Oops! 'AnalysisIndicators' object has no attribute 'percet_return'\n"
]
}
@@ -1431,7 +1509,7 @@
{
"data": {
"text/plain": [
"Strategy(name='Volume MAs and Price MA chain', ta=[{'kind': 'ema', 'close': 'volume', 'length': 10, 'prefix': 'VOLUME'}, {'kind': 'sma', 'close': 'volume', 'length': 20, 'prefix': 'VOLUME'}, {'kind': 'ema', 'length': 5}, {'kind': 'linreg', 'close': 'EMA_5', 'length': 8, 'prefix': 'EMA_5'}], description=None, created='09/13/2020, 15:34:25', last_run=None, run_time=None)"
"Strategy(name='Volume MAs and Price MA chain', ta=[{'kind': 'ema', 'close': 'volume', 'length': 10, 'prefix': 'VOLUME'}, {'kind': 'sma', 'close': 'volume', 'length': 20, 'prefix': 'VOLUME'}, {'kind': 'ema', 'length': 5}, {'kind': 'linreg', 'close': 'EMA_5', 'length': 8, 'prefix': 'EMA_5'}], description=None, created='09/25/2020, 07:53:11')"
]
},
"execution_count": 20,
@@ -1483,7 +1561,22 @@
"name": "stdout",
"output_type": "stream",
"text": [
"[i] Loaded['D']: SPY_D.csv\n"
"[i] Loaded['D']: SPY_D.csv\n",
" open high low close volume\n",
"date \n",
"1999-11-01 136.5000 137.0000 135.5625 135.5625 4006500.0\n",
"1999-11-02 135.9687 137.2500 134.5937 134.5937 6516900.0\n",
"1999-11-03 136.0000 136.3750 135.1250 135.5000 7222300.0\n",
"1999-11-04 136.7500 137.3593 135.7656 136.5312 7907500.0\n",
"1999-11-05 138.6250 139.1093 136.7812 137.8750 7431500.0\n",
"... ... ... ... ... ...\n",
"2020-08-24 342.1200 343.0000 339.4504 342.9200 48588662.0\n",
"2020-08-25 343.5300 344.2100 342.2700 344.1200 38463381.0\n",
"2020-08-26 344.7600 347.8600 344.1700 347.5700 50790237.0\n",
"2020-08-27 348.5100 349.9000 346.5300 348.3300 58034142.0\n",
"2020-08-28 349.4400 350.7200 348.1500 350.5800 48588940.0\n",
"\n",
"[5241 rows x 5 columns]\n"
]
},
{
@@ -1732,7 +1825,7 @@
{
"data": {
"text/plain": [
"Strategy(name='MACD BBands', ta=[{'kind': 'macd'}, {'kind': 'bbands', 'close': 'MACD_12_26_9', 'length': 20, 'prefix': 'MACD'}], description='BBANDS_20 applied to MACD', created='09/13/2020, 15:34:25', last_run=None, run_time=None)"
"Strategy(name='MACD BBands', ta=[{'kind': 'macd'}, {'kind': 'bbands', 'close': 'MACD_12_26_9', 'length': 20, 'prefix': 'MACD'}], description='BBANDS_20 applied to MACD', created='09/25/2020, 07:53:11')"
]
},
"execution_count": 23,
@@ -1782,7 +1875,22 @@
"name": "stdout",
"output_type": "stream",
"text": [
"[i] Loaded['D']: SPY_D.csv\n"
"[i] Loaded['D']: SPY_D.csv\n",
" open high low close volume\n",
"date \n",
"1999-11-01 136.5000 137.0000 135.5625 135.5625 4006500.0\n",
"1999-11-02 135.9687 137.2500 134.5937 134.5937 6516900.0\n",
"1999-11-03 136.0000 136.3750 135.1250 135.5000 7222300.0\n",
"1999-11-04 136.7500 137.3593 135.7656 136.5312 7907500.0\n",
"1999-11-05 138.6250 139.1093 136.7812 137.8750 7431500.0\n",
"... ... ... ... ... ...\n",
"2020-08-24 342.1200 343.0000 339.4504 342.9200 48588662.0\n",
"2020-08-25 343.5300 344.2100 342.2700 344.1200 38463381.0\n",
"2020-08-26 344.7600 347.8600 344.1700 347.5700 50790237.0\n",
"2020-08-27 348.5100 349.9000 346.5300 348.3300 58034142.0\n",
"2020-08-28 349.4400 350.7200 348.1500 350.5800 48588940.0\n",
"\n",
"[5241 rows x 5 columns]\n"
]
},
{
@@ -2078,7 +2186,7 @@
{
"data": {
"text/plain": [
"Strategy(name='Momo, Bands and SMAs and Cumulative Log Returns', ta=[{'kind': 'sma', 'length': 50}, {'kind': 'sma', 'length': 200}, {'kind': 'bbands', 'length': 20}, {'kind': 'macd'}, {'kind': 'rsi'}, {'kind': 'log_return', 'cumulative': True}, {'kind': 'sma', 'close': 'CUMLOGRET_1', 'length': 5, 'suffix': 'CUMLOGRET'}], description='MACD and RSI Momo with BBANDS and SMAs 50 & 200 and Cumulative Log Returns', created='09/13/2020, 15:34:25', last_run=None, run_time=None)"
"Strategy(name='Momo, Bands and SMAs and Cumulative Log Returns', ta=[{'kind': 'sma', 'length': 50}, {'kind': 'sma', 'length': 200}, {'kind': 'bbands', 'length': 20}, {'kind': 'macd'}, {'kind': 'rsi'}, {'kind': 'log_return', 'cumulative': True}, {'kind': 'sma', 'close': 'CUMLOGRET_1', 'length': 5, 'suffix': 'CUMLOGRET'}], description='MACD and RSI Momo with BBANDS and SMAs 50 & 200 and Cumulative Log Returns', created='09/25/2020, 07:53:11')"
]
},
"execution_count": 26,
@@ -2136,7 +2244,22 @@
"output_type": "stream",
"text": [
"[i] Loaded['D']: SPY_D.csv\n",
"[i] Runtime: 782.4791 ms (0.7825 s)\n"
" open high low close volume\n",
"date \n",
"1999-11-01 136.5000 137.0000 135.5625 135.5625 4006500.0\n",
"1999-11-02 135.9687 137.2500 134.5937 134.5937 6516900.0\n",
"1999-11-03 136.0000 136.3750 135.1250 135.5000 7222300.0\n",
"1999-11-04 136.7500 137.3593 135.7656 136.5312 7907500.0\n",
"1999-11-05 138.6250 139.1093 136.7812 137.8750 7431500.0\n",
"... ... ... ... ... ...\n",
"2020-08-24 342.1200 343.0000 339.4504 342.9200 48588662.0\n",
"2020-08-25 343.5300 344.2100 342.2700 344.1200 38463381.0\n",
"2020-08-26 344.7600 347.8600 344.1700 347.5700 50790237.0\n",
"2020-08-27 348.5100 349.9000 346.5300 348.3300 58034142.0\n",
"2020-08-28 349.4400 350.7200 348.1500 350.5800 48588940.0\n",
"\n",
"[5241 rows x 5 columns]\n",
"[i] Runtime: 927.2966 ms (0.9273 s)\n"
]
},
{
@@ -2396,7 +2519,7 @@
{
"data": {
"text/plain": [
"Strategy(name='EMA, MACD History, Log Returns', ta=[{'kind': 'ema', 'params': (10,)}, {'kind': 'macd', 'params': (9, 19, 10), 'col_numbers': (1,)}, {'kind': 'log_return', 'params': (5, False)}], description='EMA, MACD History, and Log Returns Strategy', created='09/13/2020, 15:34:25', last_run=None, run_time=None)"
"Strategy(name='EMA, MACD History, Outter BBands, Log Returns', ta=[{'kind': 'ema', 'params': (10,)}, {'kind': 'macd', 'params': (9, 19, 10), 'col_numbers': (1,)}, {'kind': 'bbands', 'col_numbers': (0, 2), 'col_names': ('LB', 'UB')}, {'kind': 'log_return', 'params': (5, False)}], description='EMA, MACD History, BBands(LB, UB), and Log Returns Strategy', created='09/25/2020, 07:53:11')"
]
},
"execution_count": 29,
@@ -2410,12 +2533,14 @@
" # params sets MACD's keyword arguments: fast=9, slow=19, signal=10\n",
" # and returning the 2nd column: histogram\n",
" {\"kind\":\"macd\", \"params\": (9, 19, 10), \"col_numbers\": (1,)},\n",
" # Selects the Lower and Upper Bands and renames them LB and UB, ignoring the MB\n",
" {\"kind\":\"bbands\", \"col_numbers\": (0,2), \"col_names\": (\"LB\", \"UB\")},\n",
" {\"kind\":\"log_return\", \"params\": (5, False)},\n",
"]\n",
"params_ta_strategy = ta.Strategy(\n",
" \"EMA, MACD History, Log Returns\", # name\n",
" \"EMA, MACD History, Outter BBands, Log Returns\", # name\n",
" params_ta, # ta\n",
" \"EMA, MACD History, and Log Returns Strategy\" # description\n",
" \"EMA, MACD History, BBands(LB, UB), and Log Returns Strategy\" # description\n",
")\n",
"params_ta_strategy"
]
@@ -2428,7 +2553,7 @@
{
"data": {
"text/plain": [
"'EMA, MACD History, Log Returns'"
"'EMA, MACD History, Outter BBands, Log Returns'"
]
},
"execution_count": 30,
@@ -2452,7 +2577,22 @@
"output_type": "stream",
"text": [
"[i] Loaded['D']: SPY_D.csv\n",
"[i] Runtime: 685.6862 ms (0.6857 s)\n"
" open high low close volume\n",
"date \n",
"1999-11-01 136.5000 137.0000 135.5625 135.5625 4006500.0\n",
"1999-11-02 135.9687 137.2500 134.5937 134.5937 6516900.0\n",
"1999-11-03 136.0000 136.3750 135.1250 135.5000 7222300.0\n",
"1999-11-04 136.7500 137.3593 135.7656 136.5312 7907500.0\n",
"1999-11-05 138.6250 139.1093 136.7812 137.8750 7431500.0\n",
"... ... ... ... ... ...\n",
"2020-08-24 342.1200 343.0000 339.4504 342.9200 48588662.0\n",
"2020-08-25 343.5300 344.2100 342.2700 344.1200 38463381.0\n",
"2020-08-26 344.7600 347.8600 344.1700 347.5700 50790237.0\n",
"2020-08-27 348.5100 349.9000 346.5300 348.3300 58034142.0\n",
"2020-08-28 349.4400 350.7200 348.1500 350.5800 48588940.0\n",
"\n",
"[5241 rows x 5 columns]\n",
"[i] Runtime: 180.5198 ms (0.1805 s)\n"
]
},
{
@@ -2483,6 +2623,8 @@
" <th>volume</th>\n",
" <th>EMA_10</th>\n",
" <th>MACDh_9_19_10</th>\n",
" <th>LB</th>\n",
" <th>UB</th>\n",
" <th>LOGRET_5</th>\n",
" </tr>\n",
" <tr>\n",
@@ -2495,6 +2637,8 @@
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
@@ -2507,6 +2651,8 @@
" <td>48588662.0</td>\n",
" <td>337.797677</td>\n",
" <td>-0.000276</td>\n",
" <td>334.962909</td>\n",
" <td>343.657091</td>\n",
" <td>0.014718</td>\n",
" </tr>\n",
" <tr>\n",
@@ -2518,6 +2664,8 @@
" <td>38463381.0</td>\n",
" <td>338.947190</td>\n",
" <td>0.165373</td>\n",
" <td>334.441244</td>\n",
" <td>346.370756</td>\n",
" <td>0.016053</td>\n",
" </tr>\n",
" <tr>\n",
@@ -2529,6 +2677,8 @@
" <td>50790237.0</td>\n",
" <td>340.514974</td>\n",
" <td>0.469555</td>\n",
" <td>335.028792</td>\n",
" <td>349.919208</td>\n",
" <td>0.030201</td>\n",
" </tr>\n",
" <tr>\n",
@@ -2540,6 +2690,8 @@
" <td>58034142.0</td>\n",
" <td>341.935888</td>\n",
" <td>0.613083</td>\n",
" <td>337.277495</td>\n",
" <td>351.690505</td>\n",
" <td>0.029276</td>\n",
" </tr>\n",
" <tr>\n",
@@ -2551,6 +2703,8 @@
" <td>48588940.0</td>\n",
" <td>343.507545</td>\n",
" <td>0.771996</td>\n",
" <td>340.426029</td>\n",
" <td>352.981971</td>\n",
" <td>0.032174</td>\n",
" </tr>\n",
" </tbody>\n",
@@ -2566,13 +2720,13 @@
"2020-08-27 348.51 349.90 346.5300 348.33 58034142.0 341.935888 \n",
"2020-08-28 349.44 350.72 348.1500 350.58 48588940.0 343.507545 \n",
"\n",
" MACDh_9_19_10 LOGRET_5 \n",
"date \n",
"2020-08-24 -0.000276 0.014718 \n",
"2020-08-25 0.165373 0.016053 \n",
"2020-08-26 0.469555 0.030201 \n",
"2020-08-27 0.613083 0.029276 \n",
"2020-08-28 0.771996 0.032174 "
" MACDh_9_19_10 LB UB LOGRET_5 \n",
"date \n",
"2020-08-24 -0.000276 334.962909 343.657091 0.014718 \n",
"2020-08-25 0.165373 334.441244 346.370756 0.016053 \n",
"2020-08-26 0.469555 335.028792 349.919208 0.030201 \n",
"2020-08-27 0.613083 337.277495 351.690505 0.029276 \n",
"2020-08-28 0.771996 340.426029 352.981971 0.032174 "
]
},
"execution_count": 31,
@@ -2584,13 +2738,6 @@
"spy = watch.load(\"SPY\", timed=True)\n",
"spy.tail()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
+143 -167
View File
File diff suppressed because one or more lines are too long
+11 -10
View File
@@ -8,7 +8,7 @@ import pandas as pd # pip install pandas
import yfinance as yf
# yf.pdr_override() # <== that's all it takes :-)
from alphaVantageAPI.alphavantage import AlphaVantage # pip install alphaVantage-api
import alphaVantageAPI as AV # pip install alphaVantage-api
import pandas_ta as ta # pip install pandas_ta
@@ -55,7 +55,7 @@ class Watchlist(object):
A simple Class to load/download financial market data and automatically
apply Technical Analysis indicators with a Pandas TA Strategy.
Default Strategy: pandas_ta.AllStrategy.
Default Strategy: pandas_ta.CommonStrategy
## Package Support:
### Data Source (Default: AlphaVantage)
@@ -67,7 +67,7 @@ class Watchlist(object):
- Pandas TA (pip install pandas_ta)
## Required Arguments:
- tickers: A list of strings containing tickers. Example: ['SPY', 'AAPL']
- tickers: A list of strings containing tickers. Example: ["SPY", "AAPL"]
"""
def __init__(
self,
@@ -78,11 +78,12 @@ class Watchlist(object):
ds: object = None,
**kwargs
):
self.tickers = tickers
self.tf = tf
self.verbose = kwargs.pop("verbose", False)
self.debug = kwargs.pop("debug", False)
self.name = name
self.tickers = tickers
self.tf = tf
self.name = name if isinstance(name, str) else f"Watch: {', '.join(tickers)}"
self.data = None
self.kwargs = kwargs
self.strategy = strategy
@@ -92,9 +93,9 @@ class Watchlist(object):
elif isinstance(ds, str) and ds.lower() == "yahoo":
self.ds = yf
else:
AVkwargs = {"api_key": "YOUR API KEY","clean": True, "export": True, "export_path": ".", "output_size": "full", "premium": False}
AVkwargs = {"api_key": "YOUR API KEY", "clean": True, "export": True, "export_path": ".", "output_size": "full", "premium": False}
av_kwargs = kwargs.pop("av_kwargs", AVkwargs)
self.ds = AlphaVantage(**av_kwargs)
self.ds = AV.AlphaVantage(**av_kwargs)
def _drop_columns(self, df: pd.DataFrame, cols: list = ["Unnamed: 0", "date", "split_coefficient", "dividend"]):
@@ -145,8 +146,8 @@ class Watchlist(object):
print(f"[i] Loaded['{tf}']: {filename_}")
else:
print(f"[+] Downloading['{tf}']: {ticker}")
if isinstance(self.ds, AlphaVantage):
df = self.ds.data(tf, ticker)
if isinstance(self.ds, AV.AlphaVantage):
df = self.ds.data(ticker, tf)
if not df.ta.datetime_ordered:
df = df.set_index(pd.DatetimeIndex(df[index]))
elif isinstance(self.ds, yfinance):
+24
View File
@@ -18,6 +18,14 @@ except DistributionNotFound:
else:
__version__ = _dist.version
from importlib.util import find_spec
Imports = {
"scipy": find_spec("scipy") is not None,
"sklearn": find_spec("sklearn") is not None,
"alphaVantage-api ": find_spec("alphaVantageAPI") is not None,
"yfinance": find_spec("yfinance") is not None
}
# Not ideal and not dynamic but it works.
# Will find a dynamic solution later.
Category = {
@@ -46,4 +54,20 @@ Category = {
"volume": ["ad", "adosc", "aobv", "cmf", "efi", "eom", "mfi", "nvi", "obv", "pvi", "pvol", "pvt"],
}
# https://www.worldtimezone.com/markets24.php
EXCHANGE_TZ = {
"NZSX": 12, "ASX": 11,
"TSE": 9, "HKE": 8, "SSE": 8, "SGX": 8,
"NSE": 5.5, "DIFX": 4, "RTS": 3,
"JSE": 2, "FWB": 1, "LSE": 1,
"BMF": -2, "NYSE": -4, "TSX": -4
}
RATE = {
"TRADING_DAYS_PER_YEAR": 252, # Keep even
"TRADING_HOURS_PER_DAY": 6.5,
"MINUTES_PER_HOUR": 60
}
from pandas_ta.core import *
+23 -17
View File
@@ -23,7 +23,7 @@ from pandas_ta.volatility import *
from pandas_ta.volume import *
from pandas_ta.utils import *
version = ".".join(("0", "2", "11b"))
version = ".".join(("0", "2", "12b"))
# Strategy DataClass
@@ -350,18 +350,18 @@ class AnalysisIndicators(BasePandasObject):
else:
if isinstance(result, pd.DataFrame):
# If specified in kwargs, rename the columns. If not, use the default names.
if 'col_names' in kwargs and isinstance(kwargs['col_names'], tuple):
if len(kwargs['col_names'])>=len(result.columns):
for col, ind_name in zip(result.columns, kwargs['col_names']):
if "col_names" in kwargs and isinstance(kwargs["col_names"], tuple):
if len(kwargs["col_names"])>=len(result.columns):
for col, ind_name in zip(result.columns, kwargs["col_names"]):
df[ind_name] = result.loc[:,col]
else:
print(f'Not enough col_names were specified : got {len(kwargs["col_names"])}, expected {len(result.columns)}.')
print(f"Not enough col_names were specified : got {len(kwargs['col_names'])}, expected {len(result.columns)}.")
return
else:
for i, column in enumerate(result.columns):
df[column] = result.iloc[:,i]
else:
ind_name = kwargs['col_names'][0] if 'col_names' in kwargs and isinstance(kwargs['col_names'], tuple) else result.name
ind_name = kwargs["col_names"][0] if "col_names" in kwargs and isinstance(kwargs["col_names"], tuple) else result.name
df[ind_name] = result
@@ -587,25 +587,31 @@ class AnalysisIndicators(BasePandasObject):
excluded_str = ", ".join(excluded)
print(f"[i] Excluded[{len(excluded)}]: {excluded_str}")
if verbose:
print(f"[i] Multiprocessing: {self.cores} of {cpu_count()} cores.")
timed = kwargs.pop("timed", False)
results = []
pool = Pool(self.cores)
if timed: stime = perf_counter()
if mode["custom"]:
has_col_names = True if len([True for x in ta if 'col_names' in x and isinstance(x['col_names'], tuple)]) else False
custom_ta = [(ind["kind"], ind["params"] if "params" in ind and isinstance(ind["params"], tuple) else (), {**ind, **kwargs}) for ind in ta]
# Custom multiprocessing pool. Must be ordered for Chained Strategies
# May fix this to cpus if Chaining/Composition if it remains inconsistent
results = pool.imap(self._mp_worker, custom_ta, self.cores)#, cpus)
# Without multiprocessing :
for ind in ta:
params = ind["params"] if "params" in ind and isinstance(ind["params"], tuple) else tuple()
getattr(self, ind["kind"])(*params, **{**ind, **kwargs})
if has_col_names:
if verbose: print(f"[i] No mulitproccessing support for 'col_names' option.")
# Without multiprocessing:
for ind in ta:
params = ind["params"] if "params" in ind and isinstance(ind["params"], tuple) else tuple()
getattr(self, ind["kind"])(*params, **{**ind, **kwargs})
else:
if verbose:
print(f"[i] Multiprocessing: {self.cores} of {cpu_count()} cores.")
# Custom multiprocessing pool. Must be ordered for Chained Strategies
# May fix this to cpus if Chaining/Composition if it remains inconsistent
results = pool.imap(self._mp_worker, custom_ta, self.cores)
else:
if verbose:
print(f"[i] Multiprocessing: {self.cores} of {cpu_count()} cores.")
default_ta = [(ind, tuple(), kwargs) for ind in ta]
# All and Categorical multiprocessing pool. Speed over Order.
results = pool.imap_unordered(self._mp_worker, default_ta, self.cores)
+3 -1
View File
@@ -75,7 +75,9 @@ def linreg(close, length=None, offset=None, **kwargs):
linreg.__doc__ = \
"""Linear Regression Moving Average (linreg)
Linear Regression Moving Average
Linear Regression Moving Average (LINREG). This is a simplified version of a
Standard Linear Regression. LINREG is a rolling regression of one variable. A
Standard Linear Regression is between two or more variables.
Source: TA Lib
+66 -18
View File
@@ -1,7 +1,13 @@
# -*- coding: utf-8 -*-
import math
import sys
from datetime import datetime
from functools import reduce
# from importlib.util import find_spec
from operator import mul
from pathlib import Path
from sys import float_info as sflt
from time import perf_counter
from numpy import argmax, argmin, dot, ones, triu
@@ -9,27 +15,17 @@ from numpy import append as npAppend
from numpy import array as npArray
from numpy import ndarray as npNdArray
from numpy import sum as npSum
# from numpy import std as npStd
from numpy import sqrt as npSqrt
from numpy import corrcoef as npCorrcoef
from numpy import seterr
from pandas import DataFrame, Series
from pandas.api.types import is_datetime64_any_dtype
from functools import reduce
from operator import mul
from sys import float_info as sflt
TRADING_DAYS_PER_YEAR = 252 # Keep even
TRADING_HOURS_PER_DAY = 6.5
MINUTES_PER_HOUR = 60
from pandas_ta import Imports, EXCHANGE_TZ, RATE
# https://www.worldtimezone.com/markets24.php
EXCHANGE_TZ = {
"NZSX": 12, "ASX": 11,
"TSE": 9, "HKE": 8, "SSE": 8, "SGX": 8,
"NSE": 5.5, "DIFX": 4, "RTS": 3,
"JSE": 2, "FWB": 1, "LSE": 1,
"BMF": -2, "NYSE": -4, "TSX": -4
}
seterr(divide="ignore", invalid="ignore")
def _above_below(
@@ -318,6 +314,59 @@ def get_time(exchange: str = "NYSE", to_string:bool = False) -> (None, str):
return s if to_string else print(s)
def _linear_regression_np(x: Series, y: Series) -> dict:
"""Simple Linear Regression in Numpy for two 1d arrays for environments
without the sklearn package."""
m = x.size
x_sum = x.sum()
y_sum = y.sum()
# 1st row, 2nd col value corr(x, y)
r = npCorrcoef(x, y)[0,1]
r_mixture = m * (x * y).sum() - x_sum * y_sum
b = r_mixture / (m * (x * x).sum() - x_sum * x_sum)
a = y.mean() - b * x.mean()
line = a + b * x
return {
"a": a, "b": b, "r": r,
"t": r / npSqrt((1 - r * r) / (m - 2)),
"line": line
}
def _linear_regression_sklearn(x, y):
"""Simple Linear Regression in Scikit Learn for two 1d arrays for
environments with the sklearn package."""
from sklearn.linear_model import LinearRegression
regression = LinearRegression().fit(DataFrame(x), y=y)
r = regression.score(DataFrame(x), y=y)
a, b = regression.intercept_, regression.coef_[0]
return {
"a": a, "b": b, "r": r,
"t": r / npSqrt((1 - r * r) / (x.size - 2)),
"line": a + b * x
}
def linear_regression(x: Series, y: Series) -> dict:
"""Classic Linear Regression in Numpy or Scikit-Learn"""
x = verify_series(x)
y = verify_series(y)
m, n = x.size, y.size
if m != n:
print(f"[X] Linear Regression X and y observations do not match: {m} != {n}")
return
if Imports["sklearn"]:
return _linear_regression_sklearn(x, y)
else:
return _linear_regression_np(x, y)
def is_percent(x: int or float) -> bool:
if isinstance(x, (int, float)):
return x is not None and x >= 0 and x <= 100
@@ -325,8 +374,7 @@ def is_percent(x: int or float) -> bool:
def non_zero_range(high: Series, low: Series) -> Series:
"""Returns the difference of two series and adds epsilon to any zero values. This occurs commonly in crypto data when
high = low.
"""Returns the difference of two series and adds epsilon to any zero values. This occurs commonly in crypto data when 'high' = 'low'.
"""
diff = high - low
if diff.eq(0).any().any():
+31 -6
View File
@@ -99,9 +99,9 @@ class TestStrategyMethods(TestCase):
]
custom = pandas_ta.Strategy(
"Momo, Bands and SMAs and Cumulative Log Returns", # name
"Commons with Cumulative Log Return EMA Chain", # name
momo_bands_sma_ta, # ta
"MACD and RSI Momo with BBANDS and SMAs 50 & 200 and Cumulative Log Returns" # description
"Common indicators with specific lengths and a chained indicator" # description
)
self.data.ta.strategy(custom, verbose=verbose, timed=strategy_timed)
@@ -110,15 +110,40 @@ class TestStrategyMethods(TestCase):
self.category = "Custom B"
custom_args_ta = [
{"kind":"fisher", "params": (13, 7)},
{"kind":"macd", "params": (9, 19, 7), "col_numbers": (1,)},
{"kind":"ema", "params": (5,)},
{"kind":"linreg", "close": "EMA_5", "length": 8, "suffix": "EMA_5"}
{"kind":"fisher", "params": (13, 7)},
]
custom = pandas_ta.Strategy(
"Custom Args Tuple", custom_args_ta,
"Allow for easy filling in indicator arguments without naming them"
"Allow for easy filling in indicator arguments by argument placement."
)
self.data.ta.strategy(custom, verbose=verbose, timed=strategy_timed)
def test_custom_col_names_tuple(self):
self.category = "Custom C"
custom_args_ta = [
{"kind":"bbands", "col_names": ("LB", "MB", "UB")}
]
custom = pandas_ta.Strategy(
"Custom Col Numbers Tuple", custom_args_ta,
"Allow for easy renaming of resultant columns"
)
self.data.ta.strategy(custom, verbose=verbose, timed=strategy_timed)
# @skip
def test_custom_col_numbers_tuple(self):
self.category = "Custom D"
custom_args_ta = [
{"kind":"macd", "col_numbers": (1,)}
]
custom = pandas_ta.Strategy(
"Custom Col Numbers Tuple", custom_args_ta,
"Allow for easy selection of resultant columns"
)
self.data.ta.strategy(custom, verbose=verbose, timed=strategy_timed)
+13
View File
@@ -161,6 +161,19 @@ class TestUtilities(TestCase):
self.assertEqual(self.utils.EXCHANGE_TZ["NYSE"], -4)
self.assertIsInstance(result, str)
def test_linear_regression(self):
x = Series([1, 2, 3, 4, 5])
y = Series([1.8, 2.1, 2.7, 3.2, 4])
# r = {"a": 1.1099999999999985, "b": 0.5500000000000006}
result = self.utils.linear_regression(x, y)
self.assertIsInstance(result, dict)
self.assertIsInstance(result["a"], float)
self.assertIsInstance(result["b"], float)
self.assertIsInstance(result["r"], float)
self.assertIsInstance(result["t"], float)
self.assertIsInstance(result["line"], Series)
def test_pascals_triangle(self):
self.assertIsNone(self.utils.pascals_triangle(inverse=True), None)