{"id":19603121,"url":"https://github.com/0100101001010000/pytechnicalindicators","last_synced_at":"2025-06-26T09:37:15.056Z","repository":{"id":53727234,"uuid":"319910153","full_name":"0100101001010000/PyTechnicalIndicators","owner":"0100101001010000","description":"A simple technical indicator package","archived":false,"fork":false,"pushed_at":"2025-01-30T21:25:55.000Z","size":1396,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-15T10:57:50.405Z","etag":null,"topics":["finance","package","python3","technical-analysis","technical-indicators","trading"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/0100101001010000.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"Contributing.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-09T09:45:13.000Z","updated_at":"2025-01-30T21:25:54.000Z","dependencies_parsed_at":"2023-09-26T05:14:34.305Z","dependency_job_id":"7531c73e-df8b-4e72-b96c-eb6383b8ea84","html_url":"https://github.com/0100101001010000/PyTechnicalIndicators","commit_stats":{"total_commits":40,"total_committers":3,"mean_commits":"13.333333333333334","dds":"0.050000000000000044","last_synced_commit":"c22f2d987236038e4f2fc09cfc8ed9e8cdb18ebb"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0100101001010000%2FPyTechnicalIndicators","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0100101001010000%2FPyTechnicalIndicators/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0100101001010000%2FPyTechnicalIndicators/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0100101001010000%2FPyTechnicalIndicators/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/0100101001010000","download_url":"https://codeload.github.com/0100101001010000/PyTechnicalIndicators/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251178058,"owners_count":21548156,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["finance","package","python3","technical-analysis","technical-indicators","trading"],"created_at":"2024-11-11T09:28:12.576Z","updated_at":"2025-04-27T17:32:39.185Z","avatar_url":"https://github.com/0100101001010000.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"![alt text](./banner.webp)\n\n# PyTechnicalIndicators\n\nA simple, lightweight package used to calculate Technical Indicators in Python.\n\nThis package only uses Python built in types, and the Python standard library.\n\n## Installation\n\nInstall using pip\n\n```shell\npip install PyTechnicalIndicators\n```\n\n## Usage\n\nTo see this package in use and explanations go to the [PyTechnicalIndicators Example Repo](www.github.com/0100101001010000/PyTechnicalIndicators_Examples),\nthis README is specific to calling functions in the package.\n\nThe PyTechnicalIndicators package is split into three directories.\n\n`Bulk` is used to calculate multiple Technical Indicators for a large list of prices.\n\n`Single` is used to calculate a singe Technical Indicator for a price.\n\n`Chart Patterns` is used to calculate chart patterns to be displayed on OHLC charts.\n\n### Bulk\nThe `Bulk` directory has 11 files used to calculate different Technical Indicator categories.\n\n#### Basic Indicators\n`basic_indicators` has functions native to the Python standard library that get calculated for a list of asset prices and\nreturns a list of technical indicators.\n\n##### Log\nCalculates the log for a list of prices\n```python\nfrom PyTechnicalIndicators.Bulk.basic_indicators import log\nprices = [100, 102, 105, 103, 108]\nbulk_log = log(prices)\nprint(bulk_log)\n# will print [4.605170185988092, 4.624972813284271, 4.653960350157523, 4.634728988229636, 4.68213122712422]\n```\n\n##### Log Differnce\nCalculates difference in log between a price at t and t-1\n```python\nfrom PyTechnicalIndicators.Bulk.basic_indicators import log_diff\nprices = [100, 102, 105, 103, 108]\nbulk_log_diff = log_diff(prices)\nprint(bulk_log_diff)\n# will print [0, 0.019802627296178876, 0.028987536873252395, -0.019231361927887214, 0.04740223889458406]\n```\nThe first value will always be 0 because there is no other value to do the difference against.\n\n##### Standard Deviation\nCalculates the standard deviation of a list of prices over a period. Period parameter that needs to be \ndetermined by the caller\n```python\nfrom PyTechnicalIndicators.Bulk.basic_indicators import standard_deviation\nprices = [100, 102, 105, 103, 108]\nbulk_stddev = standard_deviation(prices, 3)\nprint(bulk_stddev)\n# will print [2.516611478423583, 1.5275252316519468, 2.516611478423583]\n```\n\n##### Mean\nCalculates price average over a period. Period needs to be determined by the caller. \n```python\nfrom PyTechnicalIndicators.Bulk.basic_indicators import mean\nprices = [100, 102, 105, 103, 108]\nbulk_mean = mean(prices, 3)\nprint(bulk_mean)\n# will print [102.333333333333333, 103.3333333333333333, 105.333333333333333]\n```\n\n##### Median\nCalculates the price median over a period. Period needs to be determined by the caller.\n```python\nfrom PyTechnicalIndicators.Bulk.basic_indicators import median\nprices = [100, 102, 105, 103, 108]\nbulk_median = median(prices, 3)\nprint(bulk_median)\n# will print [102, 103, 105]\n```\n\n##### Variance\nCalculates price variance over a period. Period needs to be determined by the caller.\n```python\nfrom PyTechnicalIndicators.Bulk.basic_indicators import variance\nprices = [100, 102, 105, 103, 108]\nbulk_variance = variance(prices, 3)\nprint(bulk_variance)\n# will print [6.33333333333333333, 2.3333333333333333, 6.333333333333333]\n```\n\n##### Mean Absolute Deviation\nCalculates the prices absolute deviation from the mean over a period. Period needs to be determined by the caller.\n```python\nfrom PyTechnicalIndicators.Bulk.basic_indicators import mean_absolute_deviation\nprices = [100, 102, 105, 103, 108]\nbulk_mean_absolute_deviation = mean_absolute_deviation(prices, 3)\nprint(bulk_mean_absolute_deviation)\n# will print [1.7777777777777761, 1.1111111111111096, 1.7777777777777761]\n```\n\n##### Median Absolute Deviation\nCalculates the prices absolute deviation from the median over a period. Period needs to be determined by the caller.\n```python\nfrom PyTechnicalIndicators.Bulk.basic_indicators import median_absolute_deviation\nprices = [100, 102, 105, 103, 108]\nbulk_median_absolute_deviation = median_absolute_deviation(prices, 3)\nprint(bulk_median_absolute_deviation)\n# will print [1.6666666666666667, 1.0, 1.6666666666666667]\n```\n\n##### Mode Absolute Deviation\nCalculates the prices absolute deviation from the median over a period. Period needs to be determined by the caller.\n```python\nfrom PyTechnicalIndicators.Bulk.basic_indicators import mode_absolute_deviation\nprices = [100, 102, 105, 103, 108]\nbulk_mode_absolute_deviation = mode_absolute_deviation(prices, 3)\nprint(bulk_mode_absolute_deviation)\n# will print [2.3333333333333335, 1.3333333333333333, 1.6666666666666667]\n```\n\n#### Candle Indicators\n`candle_indicators` has technical indicators intended to be used on OHLC charts.\n\n##### Bollinger Bands\nCalculates the Bollinger Bands for typical prices. The period defaults to 20, moving average model defaults to 'ma' \n(moving average), and the standard deviation multiplier defaults to 2. These can be changed by the caller.\n\nThe first item in the tuple is the lower band, the second item is the upper band.\n```python\nfrom PyTechnicalIndicators.Bulk.candle_indicators import bollinger_bands\n# Default Bollinger Bands\nprices = [103, 105, 102, 107, 103, 111, 106, 104, 105, 108, 112, 120, 125, 110, 107, 108, 105, 103, 106, 107, 110, 108]\nbbands = bollinger_bands(prices)\nprint(bbands)\n# will print [(96.36499833879442, 119.33500166120557), (96.91237286601877, 119.48762713398123), (97.16213062944371, 119.53786937055628)]\n\n# Personalised Bollinger Bands\nprices = [110, 107, 108, 105, 103, 106, 107, 110, 108]\npersonalised_bbands = bollinger_bands(prices, period=7, ma_model='ema', stddev_multiplier=3)\nprint(personalised_bbands) \n# will print [(99.46018315489414, 112.81255052123461), (100.42609144537805, 113.77845881171852), (100.49915238054767, 114.23128362705957)]\n```\n\n##### Ichimoku Cloud\nCalculates the Ichimoku Cloud from high, low, and closing prices. The conversion period defaults to 9, the base period\ndefaults to 26, and the span B period defaults to 52. These can be changed by the caller.\n\nReturns the leading span A, leading span B, baseline, conversion line, and lagged close based on the base period, in that order.\n```python\nfrom PyTechnicalIndicators.Bulk.candle_indicators import ichimoku_cloud\n# Default Ichimoku Cloud\nhighs = [119, 117, 110, 100, 103, 104, 111, 103, 119, 120, 104, 111, 113, 114, 107, 102, 103, 111, 108, 107, 118,\n         106, 109, 118, 114, 108, 120, 103, 119, 119, 110, 100, 118, 111, 101, 105, 113, 112, 103, 117, 107, 115,\n         114, 116, 110, 108, 103, 100, 100, 100, 116, 115, 113, 119]\nlows = [114, 111, 103, 100, 103, 96, 100, 101, 91, 115, 93, 98, 107, 95, 104, 99, 95, 94, 96, 92, 114, 97, 108, 106,\n        107, 106, 97, 101, 92, 107, 110, 91, 101, 104, 93, 97, 92, 106, 102, 96, 100, 102, 109, 113, 109, 108, 95,\n        95, 98, 94, 104, 98, 99, 103]\nclose = [114, 116, 108, 100, 103, 102, 106, 101, 103, 118, 102, 106, 112, 101, 107, 99, 101, 111, 103, 106, 116,\n         106, 108, 106, 113, 106, 109, 103, 106, 118, 110, 94, 109, 107, 93, 101, 103, 110, 102, 102, 102, 112, 111,\n         115, 110, 108, 103, 98, 98, 95, 113, 112, 109, 114]\nicloud = ichimoku_cloud(highs, lows, close)\nprint(icloud) \n# will print [(105.25, 105.5, 105.5, 105, 109), (105.0, 105.5, 105, 105, 103), (105.75, 105.5, 105, 106.5, 106)]\n\n# Personalised Ichimoku Cloud\nhighs = [117, 107, 115, 114, 116, 110, 108, 103, 100, 100, 100, 116, 115, 118, 121]\nlows = [96, 100, 102, 109, 113, 109, 108, 95, 95, 98, 94, 104, 98, 95, 92]\nclose = [99, 103, 108, 113, 115, 110, 108, 96, 95, 99, 99, 109, 108, 113, 116]\nicloud = ichimoku_cloud(highs, lows, close, conversion_period=5, base_period=3, span_b_period=13)\nprint(icloud) \n# will print [(105.0, 105.5, 105, 105, 99), (106.25, 106.0, 106.5, 106, 109), (106.5, 106.5, 106.5, 106.5, 108)]\n```\n\n#### Correlation Indicators\n`correlation_indicators` are indicators that calculate the correlation between two assets.\n\n##### Correlate Asset Prices\nCalculates the price correlation between two asset prices over a given period. Period needs to be determined by caller.\n```python\nfrom PyTechnicalIndicators.Bulk.correlation_indicators import correlate_asset_prices\nasset_a_price = [120, 110, 105, 112, 114, 116]\nasset_b_price = [150, 155, 162, 165, 159, 154]\ncorrelation = correlate_asset_prices(asset_a_price, asset_b_price, 5)\nprint(correlation) \n# will print [-0.65025528597848, -0.4217205045478597]\n```\n\n#### Momentum Indicators\n`momentum_indicators` are indicators that calculate price momentum of an asset.\n\n##### Rate of Change\nCalculates the rate of change of an asset over a period. Period needs to be determined by caller.\n```python\nfrom PyTechnicalIndicators.Bulk.momentum_indicators import rate_of_change\nclosing_prices = [100, 101, 105, 103, 99, 80, 85, 100, 90, 85]\nroc = rate_of_change(closing_prices, 3)\nprint(roc) \n# will print [3.0, -1.9801980198019802, -23.809523809523807, -17.475728155339805, 1.0101010101010102, 12.5, 0]\n```\n\n##### On Balance Volume\nCalculates the on balance volume from asset prices and volume.\n```python\nfrom PyTechnicalIndicators.Bulk.momentum_indicators import on_balance_volume\nclosing_prices = [100, 105, 111, 107, 108]\nvolume = [1200, 1800, 1600, 1700, 1500]\nobv = on_balance_volume(closing_prices, volume)\nprint(obv) \n# will print [1200, 3000, 4600, 2900, 4400]\n```\n\n##### Commodity Channel Index\nCalculates the commodity channel index from typical prices over a given period. Period needs to be determined by caller.\nMoving average model defaults to 'ma' (moving average) and absolute deviation model default to 'mean'. These can be\nchanged by caller.\n\n```python\nfrom PyTechnicalIndicators.Bulk.momentum_indicators import commodity_channel_index\n# Default Commodity Channel Index\nprices = [103, 106, 111, 113, 111, 102, 98, 99, 95]\ncci = commodity_channel_index(prices, 7)\nprint(cci) \n# [-119.7640117994101, -86.35170603674531, -94.51476793248943]\n\nprices = [103, 106, 111, 113, 111, 102, 98, 99, 95]\npersonalised_cci = commodity_channel_index(prices, period=7, ma_model='ema', absolute_deviation_model='median')\nprint(cci) \n```\n\n#### Moving Averages\n`moving_averages` has indicators related to calculating and using moving averages.\n\n##### Moving Average\nCalculates the moving average of an asset over a given period. Period needs to be determined by caller.\n```python\nfrom PyTechnicalIndicators.Bulk.moving_averages import moving_average\nprices = [110, 107, 108, 105, 103, 106, 107]\nmas = moving_average(prices, 5)\nprint(mas) \n# [106.6, 105.8, 105.8]\n```\n\n##### Exponential Moving Average\nCalculates the exponential moving average of an asset over a given period. Period needs to be determined by caller.\n```python\nfrom PyTechnicalIndicators.Bulk.moving_averages import exponential_moving_average\nprices = [110, 107, 108, 105, 103, 106, 107]\nemas = exponential_moving_average(prices, 5)\nprint(emas) \n# [105.35071090047394, 105.36492890995261, 105.9099526066351]\n```\n\n##### Smoothed Moving Average\nCalculates the smoothed moving average of an asset over a given period. Period needs to be determined by caller.\n```python\nfrom PyTechnicalIndicators.Bulk.moving_averages import smoothed_moving_average\nprices = [110, 107, 108, 105, 103, 106, 107]\nsmas = smoothed_moving_average(prices, 5)\nprint(smas) \n# [105.89005235602093, 105.52213231794384, 105.81770585435507]\n```\n\n##### Personalised Moving Average\nThe `personalised_moving_average` is an internal function used by the smoothed (nominator=1, denominator=0), and the\nexponential (nominator=2, denominator=1) moving average functions as the underlying logic is indentical with changes in\nthe nominator and denominator of the alpha variables for each. This function is exposed in the event that the caller \nknows what they're doing, or feel lucky, and wants to tweak the alpha when calculating the moving average.\n```python\nfrom PyTechnicalIndicators.Bulk.moving_averages import personalised_moving_average\nprices = [110, 107, 108, 105, 103, 106, 107]\npmas = personalised_moving_average(prices, period=5, alpha_nominator=5, alpha_denominator=3)\nprint(pmas)\n```\n\n##### Moving Average Convergence Divergence\nCalculates the Moving Average Convergence Divergence (MACD). This is a high level function that calls `macd_line`, \n`signal_line`, and does the difference of the two to allow a histogram to be charted. It returns the three in that \norder.\n\nThe `macd_line` and `signal_line` can be called independently and are covered below.\n```python\nfrom PyTechnicalIndicators.Bulk.moving_averages import moving_average_convergence_divergence\n# Default MACD\nprices = [103, 105, 102, 107, 103, 111, 106, 104, 105, 108, 112, 120, 125, 110, 107, 108, 105, 103, 106, 107, 101,\n              99, 103, 106, 104, 102, 109, 116]\nmacd = moving_average_convergence_divergence(prices)\nprint(macd)\n\n# Personalised MACD\npersonalised_macd = moving_average_convergence_divergence(prices, macd_short_period=3, macd_long_period=9, signal_period=3, ma_model='ma')\nprint(personalised_macd)\n```\n\n##### MACD Line\nCalculate the MACD line for `moving_average_convergence_divergence`. The short period defaults to 12, the long period\ndefaults to 26, and the moving average model defaults to 'ema' (exponential moving average).\n```python\nfrom PyTechnicalIndicators.Bulk.moving_averages import macd_line\n# Default MACD Line\nprices = [103, 105, 102, 107, 103, 111, 106, 104, 105, 108, 112, 120, 125, 110, 107, 108, 105, 103, 106, 107, 101,\n              99, 103, 106, 104, 102, 109, 116]\nmacd = macd_line(prices)\nprint(macd)\n# [-2.164962379494412, -1.597159438916961, -0.4970353844502142]\n\n# Personalised MACD Line\nprices = [110, 107, 108, 105, 103, 106, 107]\npers_macd = macd_line(prices, short_period=3, long_period=5, ma_model='ma')\nprint(pers_macd) \n# [-1.2666666666666657, -1.1333333333333258, -0.46666666666666856]\n```\n\n##### Signal Line\nCalculates the signal line for `moving_average_convergence_divergence`. The period defaults to 9, nd the moving average\nmodel defaults to 'ema' (exponential moving average).\n```python\nfrom PyTechnicalIndicators.Bulk.moving_averages import signal_line\n# Default Signal Line\nmacds = [-2, -1.8, -1, -0.3, 0.1, 0.6, 1.2, 2.4, 1.9, 1.8, 1.2]\nsignal = signal_line(macds)\nprint(signal)\n# [0.8922983167758831, 1.1916575053179188, 1.2863408873310813]\n\n# Personalised Signal Line\nmacds = [0.1, 0.6, 1.2, 2.4, 1.9]\nsignal = signal_line(macds, period=3, ma_model='ma')\nprint(signal)\n# [0.6333333333333333, 1.3999999999999997, 1.8333333333333333]\n```\n\n##### McGinley Dynamic\nCalculates the McGinely dynamic of an asset over a period. Period needs to be determined by the caller.\n```python\nfrom PyTechnicalIndicators.Bulk.moving_averages import mcginley_dynamic\nprices = [100, 110, 112, 115, 113, 111]\nmd = mcginley_dynamic(prices, 10)\nprint(md) \n# [100, 100.68301345536507, 101.42207997889615, 102.24351258209249, 102.96445361554517, 103.55939307450244]\n```\n\n##### Moving Average Envelopes\nCalculates upper and lower envelopes for a list of prices over a given period. Moving average model defaults to 'ma'\n(moving average), the difference between the bands and the moving average defaults to 3%. These can be updated by the\ncaller.\n```python\nfrom PyTechnicalIndicators.Bulk.moving_averages import moving_average_envelopes\n# Default MA Envelopes\nprices = [202, 205, 208, 204, 201, 198, 202]\nmae = moving_average_envelopes(prices, 5)\nprint(mae) \n# [(210.12, 204, 197.88), (209.296, 203.2, 197.10399999999998), (208.678, 202.6, 196.522)]\n\n# Personalied MA Envelopes\nprices = [202, 205, 208, 204, 201, 198, 202]\npers_mae = moving_average_envelopes(prices, 5, 'ma', 3)\nprint(pers_mae) \n# [(210.12, 204, 197.88), (209.296, 203.2, 197.10399999999998), (208.678, 202.6, 196.522)]\n```\n\n#### Oscillators\nTechnical Indicators that oscillate\n\n##### Money Flow Index\nCalculates the money flow index for an asset. Period defaults to 14 but can be updated by caller.\n```python\nfrom PyTechnicalIndicators.Bulk.oscillators import money_flow_index\n# Default MFI\ntypical_prices = [100, 105, 103, 104, 106, 109, 104, 107, 111, 115, 109, 108, 107, 106, 105, 108]\nvolume = [1200, 1200, 1300, 1200, 1600, 1400, 2000, 1800, 1600, 1500, 1200, 1100, 1500, 1400, 1200, 1300]\nmfi = money_flow_index(typical_prices, volume)\nprint(mfi)\n# [39.58136997172759, 33.33167997619165, 33.54593097992682]\n\n# Personalised MFI\npers_mfi = money_flow_index(typical_prices, volume, 3)\nprint(pers_mfi) \n# [99.00990099009901, 51.75879396984925, 57.608695652173914, 52.6381129733085, 57.681641708264, 51.92211682476285, 0, 0, 0, 0, 57.465091299677766, 51.958562641631595, 0, 52.7027027027027]\n```\n\n##### Chaikin Oscillator\nCalculates the Chaikin ocillator for an asset. The short period defaults to 3, the long period to 10, the moving average\nmodel to 'ema' (exponential moving average).\n```python\nfrom PyTechnicalIndicators.Bulk.oscillators import chaikin_oscillator\n# Default Chaikin Oscillator\nhigh = [150, 157, 163, 152, 155, 160, 158, 153, 148, 144, 145, 143]\nlow = [132, 143, 153, 148, 145, 151, 142, 138, 132, 135, 137, 132]\nclose = [148, 155, 157, 150, 148, 158, 155, 142, 145, 137, 140, 138]\nvolume = [1500, 1600, 1800, 2200, 2000, 1900, 1750, 1800, 2100, 1800, 1700, 1500]\nco = chaikin_oscillator(high, low, close, volume)\nprint(co)\n\n# Personalised Chaikin Oscillator\npers_co = chaikin_oscillator(high, low, close, volume, 5, 20, 'ma')\nprint(pers_co)\n```\n\n##### Stochastic Oscillator\nCalculates the stochastic oscillator for an asset. Period defaults to 14, can be changed by caller.\n```python\nfrom PyTechnicalIndicators.Bulk.oscillators import stochastic_oscillator\n# Default Stochastic Oscillator\nclose = [100, 92, 88, 82, 75, 68, 74, 76, 84, 84, 83, 89, 95, 89, 97, 104]\nso = stochastic_oscillator(close)\nprint(so) \n# [65.625, 100, 100]\n\n# Personalised Stochastic Oscillator\nclose = [100, 92, 88, 82, 75, 68, 74, 76, 84, 84, 83, 89, 95, 89]\npso = stochastic_oscillator(close, 5)\nprint(pso) \n# [0.0, 0.0, 30.0, 57.14285714285714, 100.0, 100.0, 90.0, 100.0, 100.0, 50.0]\n```\n\n##### Fast Stochastic\nCalculates the fast stochastic from a list of stochastic oscillators for a given period. Moving average model defaults\nto 'ma' (moving average). Period needs to be determined by the caller.\n```python\nfrom PyTechnicalIndicators.Bulk.oscillators import fast_stochastic\n# Default Fast Stochastic\nstochastic_oscillators = [0.0, 0.0, 30.0, 57.14285714285714, 100.0, 100.0, 90.0, 100.0, 100.0, 50.0]\nfs = fast_stochastic(stochastic_oscillators, 5)\nprint(fs) \n\n# Personalised Fast Stochastic\nstochastic_oscillators = [0.0, 0.0, 30.0, 57.14285714285714, 100.0, 100.0, 90.0, 100.0, 100.0, 50.0]\npers_fs = fast_stochastic(stochastic_oscillators, 5, 'ema')\nprint(pers_fs) \n# [58.13134732566012, 77.14285714285714, 85.9783344617468, 94.19092755585648, 98.29383886255926, 79.66824644549763]\n```\n\n##### Slow Stochastic\nCalculates the slow stochastic from a list of fast stochastics over a given period. Moving average model defaults\nto 'ma' (moving average). Period needs to be determined by the caller.\n```python\nfrom PyTechnicalIndicators.Bulk.oscillators import slow_stochastic\n# Default Slow Stochastic\nfast_stochastics = [58.13134732566012, 77.14285714285714, 85.9783344617468, 94.19092755585648, 98.29383886255926, 79.66824644549763]\nss = slow_stochastic(fast_stochastics, 5)\nprint(ss)\n    \n# Personalised Slow Stochastic\nfast_stochastics = [58.13134732566012, 77.14285714285714, 85.9783344617468, 94.19092755585648, 98.29383886255926, 79.66824644549763]\npers_ss = slow_stochastic(fast_stochastics, 5, 'ema')\nprint(pers_ss) \n# [89.69128533244347, 87.43902556418001]\n```\n\n##### Slow Stochastic DS\nCalculates the %DS-Slow from the slow stochastic over a given period. Moving average model defaults\nto 'ma' (moving average). Period needs to be determined by the caller.\n```python\nfrom PyTechnicalIndicators.Bulk.oscillators import slow_stochastic_ds\n# Default Slow Stochastic DS\nslow_stochastics = [89, 87, 88, 83, 82]\nssds = slow_stochastic_ds(slow_stochastics, 3)\nprint(ssds)\n# [88, 86, 84.33333333333333]\n\n# Personalised Slow Stochastic DS\nslow_stochastics = [89, 87, 88, 83, 82]\npers_ssds = slow_stochastic_ds(slow_stochastics, 3, 'ma')\nprint(pers_ssds)\n# [88, 86, 84.33333333333333]\n```\n\n##### Williams %R\nCalculates the Williams %R for an asset over a given period.\n```python\nfrom PyTechnicalIndicators.Bulk.oscillators import williams_percent_r\nhigh = [150, 157, 163, 152, 155, 160, 158, 153, 148, 144, 145, 143]\nlow = [132, 143, 153, 148, 145, 151, 142, 138, 132, 135, 137, 132]\nclose = [148, 155, 157, 150, 148, 158, 155, 142, 145, 137, 140, 138]\nwr = williams_percent_r(high, low, close, 3)\nprint(wr)\n# [-19.35483870967742, -65.0, -83.33333333333333, -13.333333333333334, -27.77777777777778, -81.81818181818181, -50.0, -76.19047619047619, -50.0, -53.84615384615385]\n```\n\n#### Other Indicators\nIndicators that don't really fall into other categories\n\n##### Value Added Index\nCalculates the value added index for an asset. Starting investment defaults to 1000 but can be changed by caller.\n```python\nfrom PyTechnicalIndicators.Bulk.other_indicators import return_on_investment\nprices = [100, 210, 270, 250, 180, 220]\n\n# Default Value Added Index\nroi = return_on_investment(prices)\nprint(vai)\n# [(2000, 100), (2500, 25), (2500, 0), (1000, -60)]\n\n# Personalised Value Added Index\nvai = return_on_investment(prices, 2000)\nprint(vai)\n# [(4000, 100), (5000, 25), (5000, 0), (2000, -60)]\n```\n\n##### True Range\nCalculates the true range for an asset. Primarily used internally.\n```python\nfrom PyTechnicalIndicators.Bulk.other_indicators import true_range\nhigh = [190, 190, 150]\nlow = [120, 150, 120]\nclose = [150, 120, 190]\ntr = true_range(high, low, close) \nprint(tr)\n# [70, 70, 70]\n```\n\n##### Average Range Constant\nCalculates the average range constant for an asset. The constant defaults to 3 but can be updated by caller.\n```python\nfrom PyTechnicalIndicators.Bulk.other_indicators import average_range_constant\naverage_true_range = [10, 11]\n\n# Default ARC\narc = average_range_constant(average_true_range) \nprint(arc)\n#[30, 33]\n    \n# Personalised ARC\npers_arc = average_range_constant(average_true_range, 2) \nprint(pers_arc)\n# [20, 22]\n```\n\n##### Significant Close\nCalculates the significant close of an asset for a given period.\n```python\nfrom PyTechnicalIndicators.Bulk.other_indicators import significant_close\nclose = [100, 105, 109, 106, 107, 110]\nsc = significant_close(close, 4) \nprint(sc)\n# [109, 109, 110]\n```\n\n#### Strength Indicators\n\n##### Relative Strength Index\nCalculates the RSI of an asset. Period defaults to 14m and moving average model defaults to 'sma' (smoothed moving \naverage)\n```python\nfrom PyTechnicalIndicators.Bulk.strength_indicators import relative_strength_index\n# Default RSI\nprices = [100, 103, 110, 115, 123, 115, 116, 112, 110, 106, 116, 116, 126, 130, 118]\nrsi = relative_strength_index(prices)\nprint(rsi) \n# [60.44650041420754, 49.98706804800788]\n\n# Personal RSI\npers_rsi = relative_strength_index(prices, 13, 'ma')\nprint(pers_rsi)\n# [58.27814569536424, 58.82352941176471, 51.35135135135135]\n```\n\n##### Accumulation Distribution Index\nCalculate the ADI of an asset.\n```python\nfrom PyTechnicalIndicators.Bulk.strength_indicators import accumulation_distribution_indicator\nhigh = [190, 220, 215]\nlow = [160, 180, 170]\nclose = [165, 200, 200]\nvolume = [1200, 1500, 1200]\nadi = accumulation_distribution_indicator(high, low, close, volume)\nprint(adi) \n# [-800, -800, -400]\n```\n\n##### Directional Indicator\nCalculate the directional indicator of an asset over a period. \n\nReturns positive and negative direction indicators, and true range to be used in `directional_index`.\n```python\nfrom PyTechnicalIndicators.Bulk.strength_indicators import directional_indicator\nhigh = [127, 107, 130, 109, 120, 110, 125, 110, 105, 103]\nlow = [87, 97, 85, 81, 80, 75, 85, 70, 60, 50]\nclose = [115, 106, 124, 90, 88, 79, 90, 85, 83, 45]\ndi = directional_indicator(high, low, close, 5)\nprint(di)\n# [\n#     (20.858895705521473, 2.4539877300613497, 163),\n#     (16.444981862152358, 4.9576783555018135, 165.4),\n#     (21.332404828226554, 3.8068709377901575, 172.32),\n#     (16.534724721122704, 11.384490824037423, 177.856),\n#     (12.561830965460091, 13.988535108027989, 187.2848),\n#     (9.056111058075762, 14.89632957740407, 207.82783999999998)\n# ]\n```\n\n##### Directional Index\nCalculates the directional index from directional indicator values (positive and negative indicators).\n```python\nfrom PyTechnicalIndicators.Bulk.strength_indicators import directional_index\npositive_directional_indicator = [20.858895705521473, 16.444981862152358, 21.332404828226554, 16.534724721122704, 12.561830965460091, 9.056111058075762]\nnegative_directional_indicator = [2.4539877300613497, 4.9576783555018135, 3.8068709377901575, 11.384490824037423, 13.988535108027989, 14.89632957740407]\nidx = directional_index(positive_directional_indicator, negative_directional_indicator)\nprint(idx)\n# [0.7894736842105263, 0.536723163841808, 0.6971375807940905, 0.18446914773642656, 0.053735761632022705, 0.24382561293889254]\n```\n\n##### Average Direction Index\nCalculates the average direction index over a given period from the directional index.\n```python\nfrom PyTechnicalIndicators.Bulk.strength_indicators import average_directional_index\nidx = [0.7894736842105263, 0.536723163841808, 0.6971375807940905, 0.18446914773642656, 0.053735761632022705, 0.24382561293889254]\nadx = average_directional_index(idx, 3, 'ma')\nprint(adx)\n# [0.6744448096154749, 0.47277663079077503, 0.31178083005417995, 0.16067684076911393]\n```\n\n##### Average Directional Index Rating\nCalculates the average directional index rating of the average directional index over a period.\n```python\nfrom PyTechnicalIndicators.Bulk.strength_indicators import average_directional_index_rating\nadx = [0.6744448096154749, 0.47277663079077503, 0.31178083005417995, 0.16067684076911393]\nadxr = average_directional_index_rating(adx, 3)\nprint(adxr)\n# [0.49311281983482746, 0.3167267357799445]\n```\n\n#### Support and Resistance Indicators\n\n##### Pivot points\nCalculates the pivot points of an asset.\n```python\nfrom PyTechnicalIndicators.Bulk.support_resistance_indicators import pivot_points\nhigh = [115, 119, 125, 118, 116]\nlow = [99, 96, 110, 105, 108]\nclose = [108, 113, 120, 115, 110]\npivot = pivot_points(high, low, close)\nprint(pivot) \n# [\n#     (107.33333333333333, 99.66666666666666, 115.66666666666666, 91.33333333333333, 123.33333333333333),\n#     (109.33333333333333, 99.66666666666666, 122.66666666666666, 86.33333333333333, 132.33333333333331),\n#     (118.33333333333333, 111.66666666666666, 126.66666666666666, 103.333333333333333, 133.33333333333331),\n#     (112.66666666666667, 107.33333333333334, 120.33333333333334, 99.66666666666667, 125.66666666666667),\n#     (111.33333333333333, 106.66666666666666, 114.66666666666666, 103.33333333333333, 119.33333333333333)\n# ]\n```\n\n#### Trend Indicators\n\n##### Aroon Up\nCalculates the Aroon up for an asset. Period defaults to 25.\n```python\nfrom PyTechnicalIndicators.Bulk.trend_indicators import aroon_up\nperiod_from_high = [117, 107, 115, 114, 116, 110, 108, 103, 100, 100, 100, 116, 115, 118, 121]\naroon_up = aroon_up(period_from_high, 10)\nprint(aroon_up) \n# [0.0, 100.0, 90.0, 100.0, 100.0]\n```\n\n##### Aroon Down\nCalculates the Aroon Down for an asset. Period defaults to 25.\n```python\nfrom PyTechnicalIndicators.Bulk.trend_indicators import aroon_down\nperiod_from_low = [96, 100, 102, 109, 113, 109, 108, 95, 95, 98, 94, 104, 98, 95, 92]\naroon_down = aroon_down(period_from_low, 10)\nprint(aroon_down) \n# [100.0, 90.0, 80.0, 70.0, 100.0]\n```\n\n##### Aroon Oscillator\nCalculates the Aroon oscillator of an asset.\n```python\nfrom PyTechnicalIndicators.Bulk.trend_indicators import aroon_oscillator\nhighs = [117, 107, 115, 114, 116, 110, 108, 103, 100, 100, 100, 116, 115, 118, 121]\nlows = [96, 100, 102, 109, 113, 109, 108, 95, 95, 98, 94, 104, 98, 95, 92]\naroon_oscillator = aroon_oscillator(highs, lows, 10)\nprint(aroon_oscillator)\n# [-100.0, 10.0, 10.0, 30.0, 0.0]\n```\n\n##### Parabolic Stop and Reverse\nCalculates the parabolic SaR of an asset over a given period.\n```python\nfrom PyTechnicalIndicators.Bulk.trend_indicators import parabolic_sar\nhighs = [109, 111, 112, 110, 111, 113, 109, 107]\nlows = [90, 94, 98, 100, 96, 89, 95, 93]\nclose = [100, 103, 109, 108, 110, 111, 108, 106]\npsar = parabolic_sar(highs, lows, close, 5)\nprint(psar)\n# [(90.44, 0.02, 112, 'rising'),  (91.3424, 0.04, 113, 'rising'), (92.208704, 0.04, 113, 'rising'), (93.04035584, 0.04, 113, 'rising')]\n```\n\n#### Volatility Indicators\n\n##### Average True Range\nCalculates the average true range of an asset over a given period.\n```python\nfrom PyTechnicalIndicators.Bulk.volatility_indicators import average_true_range\nhigh = [120, 125, 123, 127, 121, 110]\nlow = [90, 110, 116, 113, 96, 79]\nclose = [100, 115, 120, 125, 110, 83]\natr = average_true_range(high, low, close, 3)\nprint(atr)\n# [17.333333333333332, 16.22222222222222, 19.14814814814815, 23.09876543209877]\n```\n\n##### Ulcer Index\nCalculates the Ulcer index of an asset over a given period.\n```python\nfrom PyTechnicalIndicators.Bulk.volatility_indicators import ulcer_index\nclose_prices = [103, 105, 106, 104, 101, 99, 93]\nui = ulcer_index(close_prices, 5)\nprint(ui)\n# [2.2719989771306217, 3.7261165392700946, 6.630672977662482]\n```\n\n##### Volatility Index\nCalculate the volatility index of an asset over a given period.\n```python\nfrom PyTechnicalIndicators.Bulk.volatility_indicators import volatility_index\nhigh = [190, 190, 150]\nlow = [120, 150, 120]\nclose = [150, 120, 190]\nvi = volatility_index(high, low, close, 14)\nprint(vi) \n# [5.0, 9.642857142857142, 13.95408163265306]\n```\n\n##### Volatility System\nCalculates the volatility system of an asset. Period defaults to 7, average true range constant defaults to 3.\n```python\nfrom PyTechnicalIndicators.Bulk.volatility_indicators import volatility_system\nhigh = [120, 125, 123, 127, 121, 110]\nlow = [90, 110, 116, 113, 96, 79]\nclose = [100, 115, 120, 125, 110, 83]\nvs = volatility_system(high, low, close, 3, 2)\nprint(vs) \n# [(125, 32.44444444444444, 92.55555555555556, 16.22222222222222),\n# (125, 38.2962962962963, 86.7037037037037, 19.14814814814815),\n# (83, 46.19753086419754, 129.19753086419755, 23.09876543209877)]\n```\n\n### Single\n\nMost of the `Single` functions are missing the period parameter as the length of the passed in prices is assumed to be \nthe period.\n\n#### Basic Indicators\nSingle `basic_indicators` is missing a number of functions that bulk has because they are native Python functions. There\nwas no need to have a wrapper function call the native function. Package user can just call the native function.\n\n##### Mean Absolute Deviation\nCalculates the prices absolute deviation from the mean.\n```python\nfrom PyTechnicalIndicators.Single.basic_indicators import mean_absolute_deviation\nprices = [100, 102, 105]\nsingle_mean_absolute_deviation = mean_absolute_deviation(prices)\nprint(single_mean_absolute_deviation)\n# 1.7777777777777761\n```\n\n##### Median Absolute Deviation\nCalculates the prices absolute deviation from the median.\n```python\nfrom PyTechnicalIndicators.Single.basic_indicators import median_absolute_deviation\nprices = [100, 102, 105]\nsingle_median_absolute_deviation = median_absolute_deviation(prices)\nprint(single_median_absolute_deviation)\n# 1.6666666666666667\n```\n\n##### Mode Absolute Deviation\nCalculates the prices absolute deviation from the median over a period. Period needs to be determined by the caller.\n```python\nfrom PyTechnicalIndicators.Single.basic_indicators import mode_absolute_deviation\nprices = [100, 102, 105]\nsingle_mode_absolute_deviation = mode_absolute_deviation(prices)\nprint(single_mode_absolute_deviation)\n# 2.3333333333333335\n```\n\n#### Candle Indicators\n`candle_indicators` has technical indicators intended to be used on OHLC charts.\n\n##### Bollinger Bands\nCalculates the Bollinger Bands for typical prices. The moving average model defaults to 'ma' \n(moving average), and the standard deviation multiplier defaults to 2.\n\nThe first item in the tuple is the lower band, the second item is the upper band.\n```python\nfrom PyTechnicalIndicators.Single.candle_indicators import bollinger_bands\n# Default Bollinger Bands\nprices = [103, 105, 102, 107, 103, 111, 106, 104, 105, 108, 112, 120, 125, 110, 107, 108, 105, 103, 106, 107]\nbbands = bollinger_bands(prices)\nprint(bbands)\n# (96.36499833879442, 119.33500166120557)\n\n# Personalised Bollinger Bands\nprices = [110, 107, 108, 105, 103, 106, 107]\npersonalised_bbands = bollinger_bands(prices, ma_model='ema', stddev_multiplier=3)\nprint(personalised_bbands) \n# (99.46018315489414, 112.81255052123461)\n```\n\n##### Ichimoku Cloud\nCalculates the Ichimoku Cloud from high, low, and closing prices. The conversion period defaults to 9, the base period\ndefaults to 26, and the span B period defaults to 52. These can be changed by the caller.\n\nReturns the leading span A, leading span B, baseline, conversion line, and lagged close based on the base period, in that order.\n```python\nfrom PyTechnicalIndicators.Single.candle_indicators import ichimoku_cloud\n# Default Ichimoku Cloud\nhighs = [119, 117, 110, 100, 103, 104, 111, 103, 119, 120, 104, 111, 113, 114, 107, 102, 103, 111, 108, 107, 118,\n         106, 109, 118, 114, 108, 120, 103, 119, 119, 110, 100, 118, 111, 101, 105, 113, 112, 103, 117, 107, 115,\n         114, 116, 110, 108, 103, 100, 100, 100, 116, 115]\nlows = [114, 111, 103, 100, 103, 96, 100, 101, 91, 115, 93, 98, 107, 95, 104, 99, 95, 94, 96, 92, 114, 97, 108, 106,\n        107, 106, 97, 101, 92, 107, 110, 91, 101, 104, 93, 97, 92, 106, 102, 96, 100, 102, 109, 113, 109, 108, 95,\n        95, 98, 94, 104, 98]\nclose = [114, 116, 108, 100, 103, 102, 106, 101, 103, 118, 102, 106, 112, 101, 107, 99, 101, 111, 103, 106, 116,\n         106, 108, 106, 113, 106, 109, 103, 106, 118, 110, 94, 109, 107, 93, 101, 103, 110, 102, 102, 102, 112, 111,\n         115, 110, 108, 103, 98, 98, 95, 113, 112]\nicloud = ichimoku_cloud(highs, lows, close)\nprint(icloud) \n# (105.25, 105.5, 105.5, 105, 109)\n\n# Personalised Ichimoku Cloud\nhighs = [117, 107, 115, 114, 116, 110, 108, 103, 100, 100, 100, 116, 115]\nlows = [96, 100, 102, 109, 113, 109, 108, 95, 95, 98, 94, 104, 98]\nclose = [99, 103, 108, 113, 115, 110, 108, 96, 95, 99, 99, 109, 108]\nicloud = ichimoku_cloud(highs, lows, close, conversion_period=5, base_period=3, span_b_period=13)\nprint(icloud) \n# (105.0, 105.5, 105, 105, 99)\n```\n\n#### Correlation Indicators\n`correlation_indicators` are indicators that calculate the correlation between two assets.\n\n##### Correlate Asset Prices\nCalculates the price correlation between two asset prices.\n```python\nfrom PyTechnicalIndicators.Single.correlation_indicators import correlate_asset_prices\nasset_a_price = [120, 110, 105, 112, 114]\nasset_b_price = [150, 155, 162, 165, 159]\ncorrelation = correlate_asset_prices(asset_a_price, asset_b_price)\nprint(correlation) \n# -0.65025528597848\n```\n\n#### Momentum Indicators\n`momentum_indicators` are indicators that calculate price momentum of an asset.\n\n##### Rate of Change\nCalculates the rate of change of an asset. Unlike the Bulk function this function takes a current and previous closing \nprice.\n```python\nfrom PyTechnicalIndicators.Single.momentum_indicators import rate_of_change\nroc = rate_of_change(current_close_price=101, previous_close_price=100)\nprint(roc) \n# 3.0\n```\n\n##### On Balance Volume\nCalculates the on balance volume from asset prices and volume. A previous observation parameter can be passed in to make\nthe calculation more precise.\n```python\nfrom PyTechnicalIndicators.Single.momentum_indicators import on_balance_volume\nclosing_prices = [100, 105, 111, 107, 108]\nvolume = [1200, 1800, 1600, 1700, 1500]\nobv = on_balance_volume(current_close=105, previous_close=100, current_volume=1800)\nprint(obv) \n# 1200\nnext_obv = on_balance_volume(current_close=105, previous_close=100, current_volume=1800, previous_obv=1200)\n# 3000\n```\n\n##### Commodity Channel Index\nCalculates the commodity channel index of an asset.\nMoving average model defaults to 'ma' (moving average) and absolute deviation model default to 'mean'.\n\n```python\nfrom PyTechnicalIndicators.Single.momentum_indicators import commodity_channel_index\n# Default Commodity Channel Index\nprices = [103, 106, 111, 113, 111, 102, 98]\ncci = commodity_channel_index(prices)\nprint(cci) \n# -119.7640117994101\n\nprices = [103, 106, 111, 113, 111, 102, 98]\npersonalised_cci = commodity_channel_index(prices, ma_model='ema', absolute_deviation_model='median')\nprint(cci) \n```\n\n#### Moving Averages\n`moving_averages` has indicators related to calculating and using moving averages.\n\n##### Moving Average\nCalculates the moving average of an asset.\n```python\nfrom PyTechnicalIndicators.Single.moving_averages import moving_average\nprices = [110, 107, 108, 105, 103]\nmas = moving_average(prices)\nprint(mas) \n# 106.6\n```\n\n##### Exponential Moving Average\nCalculates the exponential moving average of an asset.\n```python\nfrom PyTechnicalIndicators.Single.moving_averages import exponential_moving_average\nprices = [110, 107, 108, 105, 103]\nemas = exponential_moving_average(prices)\nprint(emas) \n# 105.35071090047394\n```\n\n##### Smoothed Moving Average\nCalculates the smoothed moving average of an asset.\n```python\nfrom PyTechnicalIndicators.Single.moving_averages import smoothed_moving_average\nprices = [110, 107, 108, 105, 103]\nsmas = smoothed_moving_average(prices)\nprint(smas) \n# 105.89005235602093\n```\n\n##### Personalised Moving Average\nThe `personalised_moving_average` is an internal function used by the smoothed (nominator=1, denominator=0), and the\nexponential (nominator=2, denominator=1) moving average functions as the underlying logic is indentical with changes in\nthe nominator and denominator of the alpha variables for each. This function is exposed in the event that the caller \nknows what they're doing, or feel lucky, and wants to tweak the alpha when calculating the moving average.\n```python\nfrom PyTechnicalIndicators.Single.moving_averages import personalised_moving_average\nprices = [110, 107, 108, 105, 103]\npmas = personalised_moving_average(prices, alpha_nominator=5, alpha_denominator=3)\nprint(pmas)\n```\n\n##### MACD Line\nCalculate the MACD line for `moving_average_convergence_divergence`. The short period defaults to 12, the long period\ndefaults to 26, and the moving average model defaults to 'ema' (exponential moving average).\n```python\nfrom PyTechnicalIndicators.Single.moving_averages import macd_line\n# Default MACD Line\nprices = [103, 105, 102, 107, 103, 111, 106, 104, 105, 108, 112, 120, 125, 110, 107, 108, 105, 103, 106, 107, 101,\n              99, 103, 106, 104, 102]\nmacd = macd_line(prices)\nprint(macd)\n# -2.164962379494412\n\n# Personalised MACD Line\nprices = [110, 107, 108, 105, 103]\npers_macd = macd_line(prices, short_period=3, long_period=5, ma_model='ma')\nprint(pers_macd) \n# -1.2666666666666657\n```\n\n##### Signal Line\nCalculates the signal line for `moving_average_convergence_divergence`. The moving average\nmodel defaults to 'ema' (exponential moving average).\n```python\nfrom PyTechnicalIndicators.Single.moving_averages import signal_line\n# Default Signal Line\nmacds = [-2, -1.8, -1, -0.3, 0.1, 0.6, 1.2, 2.4, 1.92]\nsignal = signal_line(macds)\nprint(signal)\n# 0.8922983167758831\n\n# Personalised Signal Line\nmacds = [0.1, 0.6, 1.2]\nsignal = signal_line(macds, ma_model='ma')\nprint(signal)\n# 0.6333333333333333\n```\n\n##### McGinley Dynamic\nCalculates the McGinely dynamic of an asset for a given period.\n```python\nfrom PyTechnicalIndicators.Single.moving_averages import mcginley_dynamic\nmd = mcginley_dynamic(100, period=10)\nprint(md) \n# 100\nnext_md = mcginley_dynamic(110, period=10, previous_mcginley_dynamic=md)\nprint(next_md)\n# 100.68301345536507\n```\n\n##### Moving Average Envelopes\nCalculates upper and lower envelopes for a list of prices. Moving average model defaults to 'ma'\n(moving average), the difference between the bands and the moving average defaults to 3%.\n```python\nfrom PyTechnicalIndicators.Bulk.moving_averages import moving_average_envelopes\n# Default MA Envelopes\nprices = [202, 205, 208, 204, 201]\nmae = moving_average_envelopes(prices, period=5)\nprint(mae) \n# (210.12, 204, 197.88)\n\n# Personalised MA Envelopes\nprices = [202, 205, 208, 204, 201]\npers_mae = moving_average_envelopes(prices, period=5, ma_model='ma', difference=3)\nprint(pers_mae) \n# (210.12, 204, 197.88)\n```\n\n#### Oscillators\nTechnical Indicators that oscillate\n\n##### Money Flow Index\nCalculates the money flow index for an asset.\n```python\nfrom PyTechnicalIndicators.Single.oscillators import money_flow_index\n# Default MFI\ntypical_prices = [100, 105, 103, 104, 106, 109, 104, 107, 111, 115, 109, 108, 107]\nvolume = [1200, 1200, 1300, 1200, 1600, 1400, 2000, 1800, 1600, 1500, 1200, 1100, 1500]\nmfi = money_flow_index(typical_prices, volume)\nprint(mfi)\n# 39.58136997172759\n\n# Personalised MFI\ntypical_prices = [100, 105, 103]\nvolume = [1200, 1200, 1300]\npers_mfi = money_flow_index(typical_prices, volume)\nprint(pers_mfi) \n# 99.00990099009901\n```\n\n##### Chaikin Oscillator\nCalculates the Chaikin ocillator for an asset. The short period defaults to 3, the moving average\nmodel to 'ema' (exponential moving average). The long period from the bulk model is assumed to be the length of the list.\n```python\nfrom PyTechnicalIndicators.Single.oscillators import chaikin_oscillator\n# Default Chaikin Oscillator\nhigh = [150, 157, 163, 152, 155, 160, 158, 153, 148, 144, 145, 143]\nlow = [132, 143, 153, 148, 145, 151, 142, 138, 132, 135, 137, 132]\nclose = [148, 155, 157, 150, 148, 158, 155, 142, 145, 137, 140, 138]\nvolume = [1500, 1600, 1800, 2200, 2000, 1900, 1750, 1800, 2100, 1800, 1700, 1500]\nco = chaikin_oscillator(high, low, close, volume)\nprint(co)\n\n# Personalised Chaikin Oscillator\npers_co = chaikin_oscillator(high, low, close, volume, 5, 'ma')\nprint(pers_co)\n```\n\n##### Stochastic Oscillator\nCalculates the stochastic oscillator for an asset. \n```python\nfrom PyTechnicalIndicators.Bulk.oscillators import stochastic_oscillator\nclose = [100, 92, 88, 82, 75, 68, 74, 76, 84, 84, 83, 89, 95, 89]\nso = stochastic_oscillator(close)\nprint(so) \n# 65.625\n```\n\n##### Fast Stochastic\nCalculates the fast stochastic from a list of stochastic oscillators. Moving average model defaults\nto 'ma' (moving average). Period needs to be determined by the caller.\n```python\nfrom PyTechnicalIndicators.Single.oscillators import fast_stochastic\nstochastic_oscillators = [0.0, 0.0, 30.0, 57.14285714285714]\nfs = fast_stochastic(stochastic_oscillators, 'ema')\nprint(fs) \n# 58.13134732566012\n```\n\n##### Slow Stochastic\nCalculates the slow stochastic from a list of fast stochastics. Moving average model defaults\nto 'ma' (moving average). \n```python\nfrom PyTechnicalIndicators.Single.oscillators import slow_stochastic\nfast_stochastics = [58.13134732566012, 77.14285714285714, 85.9783344617468, 94.19092755585648, 98.29383886255926]\nss = slow_stochastic(fast_stochastics, 'ema')\nprint(ss) \n# 89.69128533244347\n```\n\n##### Slow Stochastic DS\nCalculates the %DS-Slow from the slow stochastic. Moving average model defaults\nto 'ma' (moving average).\n```python\nfrom PyTechnicalIndicators.Bulk.oscillators import slow_stochastic_ds\n\nslow_stochastics = [89, 87, 88]\nssds = slow_stochastic_ds(slow_stochastics, 3, 'ma')\nprint(ssds)\n# 88\n```\n\n##### Williams %R\nCalculates the Williams %R for an asset over a given period.\n```python\nfrom PyTechnicalIndicators.Single.oscillators import williams_percent_r\nhigh = 150\nlow = 132\nclose = 148\nwr = williams_percent_r(high, low, close)\nprint(wr)\n# -19.35483870967742\n```\n\n#### Other Indicators\nIndicators that don't really fall into other categories\n\n##### Return on Invesment\nCalculates the value added index for an asset. Starting investment defaults to 1000 but can be changed by caller.\nThe `Single` function takes a start price and end price.\n```python\nfrom PyTechnicalIndicators.Single.other_indicators import return_on_investment\nroi = return_on_investment(start_price=100, end_price=200)\nprint(roi)\n# (2000, 100)\n```\n\n##### True Range\nCalculates the true range for an asset. Primarily used internally.\n```python\nfrom PyTechnicalIndicators.Single.other_indicators import true_range\nhigh = 190\nlow = 120\nclose = 150\ntr = true_range(high, low, close) \nprint(tr)\n# 70\n```\n\n##### Average Range Constant\nCalculates the average range constant for an asset. The constant defaults to 3 but can be updated by caller.\n```python\nfrom PyTechnicalIndicators.Single.other_indicators import average_range_constant\npers_arc = average_range_constant(10, 2) \nprint(pers_arc)\n# 20\n```\n\n##### Significant Close\nCalculates the significant close of an asset.\n```python\nfrom PyTechnicalIndicators.Single.other_indicators import significant_close\nclose = [100, 105, 109, 106]\nsc = significant_close(close) \nprint(sc)\n# 109\n```\n\n#### Strength Indicators\n\n##### Relative Strength Index\nCalculates the RSI of an asset. Moving average model defaults to 'sma' (smoothed moving \naverage)\n```python\nfrom PyTechnicalIndicators.Single.strength_indicators import relative_strength_index\n# Default RSI\nprices = [100, 103, 110, 115, 123, 115, 116, 112, 110, 106, 116, 116, 126]\npers_rsi = relative_strength_index(prices, 'ma')\nprint(pers_rsi)\n# 58.27814569536424\n```\n\n##### Accumulation Distribution Index\nCalculate the ADI of an asset.\n```python\nfrom PyTechnicalIndicators.Single.strength_indicators import accumulation_distribution_indicator\nhigh = 190\nlow = 160\nclose = 165\nvolume = 1200\nadi = accumulation_distribution_indicator(high, low, close, volume)\nprint(adi) \n# -800\n```\n\n##### Directional Indicator\nCalculate the directional indicator of an asset. \n\nReturns positive and negative direction indicators, and true range to be used in `directional_index`.\n```python\nfrom PyTechnicalIndicators.Single.strength_indicators import directional_indicator\nhigh = [127, 107, 130, 109, 120]\nlow = [87, 97, 85, 81, 80]\nclose = [115, 106, 124, 90, 88]\ndi = directional_indicator(high, low, close)\nprint(di)\n# (20.858895705521473, 2.4539877300613497, 163)\n```\n\n##### Directional Index\nCalculates the directional index from directional indicator values (positive and negative indicators).\n```python\nfrom PyTechnicalIndicators.Single.strength_indicators import directional_index\npositive_directional_indicator = 20.858895705521473\nnegative_directional_indicator = 2.4539877300613497\nidx = directional_index(positive_directional_indicator, negative_directional_indicator)\nprint(idx)\n# 0.7894736842105263\n```\n\n##### Average Direction Index\nCalculates the average direction index from the directional index.\n```python\nfrom PyTechnicalIndicators.Single.strength_indicators import average_directional_index\nidx = [0.7894736842105263, 0.536723163841808, 0.6971375807940905]\nadx = average_directional_index(idx, 'ma')\nprint(adx)\n# 0.6744448096154749\n```\n\n##### Average Directional Index Rating\nCalculates the average directional index rating of the average directional index over a period. Unlike the `Bulk` \nversion the `Single` version takes the current `average_directional_index` and the previous one.\n```python\nfrom PyTechnicalIndicators.Single.strength_indicators import average_directional_index_rating\nadx = [0.6744448096154749, 0.47277663079077503, 0.31178083005417995, 0.16067684076911393]\nadxr = average_directional_index_rating(current_average_directional_index=0.47277663079077503, previous_average_directional_index=0.6744448096154749)\nprint(adxr)\n# 0.49311281983482746\n```\n\n#### Support and Resistance Indicators\n\n##### Pivot points\nCalculates the pivot points of an asset.\n```python\nfrom PyTechnicalIndicators.Single.support_resistance_indicators import pivot_points\nhigh = 115\nlow = 99\nclose = 108\npivot = pivot_points(high, low, close)\nprint(pivot) \n# (107.33333333333333, 99.66666666666666, 115.66666666666666, 91.33333333333333, 123.33333333333333),\n```\n\n#### Trend Indicators\n\n##### Aroon Up\nCalculates the Aroon up for an asset.\n```python\nfrom PyTechnicalIndicators.Single.trend_indicators import aroon_up\nperiod_from_high = [116, 110, 108, 103, 100, 100, 100, 116, 115, 118, 121]\naroon_up = aroon_up(period_from_high, 10)\nprint(aroon_up) \n# 100.0\n```\n\n##### Aroon Down\nCalculates the Aroon Down for an asset.\n```python\nfrom PyTechnicalIndicators.Single.trend_indicators import aroon_down\nperiod_from_low = [109, 108, 95, 95, 98, 94, 104, 98, 95, 92]\naroon_down = aroon_down(period_from_low, 10)\nprint(aroon_down) \n# 100.0\n```\n\n##### Aroon Oscillator\nCalculates the Aroon oscillator of an asset.\n```python\nfrom PyTechnicalIndicators.Single.trend_indicators import aroon_oscillator\nhighs = [110, 108, 103, 100, 100, 100, 116, 115, 118, 121]\nlows = [109, 108, 95, 95, 98, 94, 104, 98, 95, 92]\naroon_oscillator = aroon_oscillator(highs, lows, 10)\nprint(aroon_oscillator)\n# 0.0\n```\n\n##### Parabolic Stop and Reverse\nThe `Single` version of this function is intended for intended use.\n```python\nfrom PyTechnicalIndicators.Single.trend_indicators import parabolic_sar\nhighs = [110, 111, 113, 109, 107]\nlows = [100, 96, 89, 95, 93]\nclose = [108, 110, 111, 108, 106]\npsar = parabolic_sar(highs, lows, close, previous_psar=92.208704, acceleration_factor=0.04, extreme=113, state='rising')\nprint(psar)\n# (93.04035584, 0.04, 113, 'rising')\n```\n\n#### Volatility Indicators\n\n##### Average True Range\nCalculates the average true range of an asset.  `Single` has two versions of this function the first when there isn't \na previous ATR, the other when there is.\n```python\nfrom PyTechnicalIndicators.Single.volatility_indicators import average_true_range_initial, average_true_range\nhigh = [120, 125, 123]\nlow = [90, 110, 116]\nclose = [100, 115, 120]\natr = average_true_range_initial(high, low, close)\nprint(atr)\n# 17.333333333333332\nnext_atr = average_true_range(high=127, low=113, close=125, previous_average_true_range=atr, period=3)\nprint(next_atr)\n# 16.22222222222222\n```\n\n##### Ulcer Index\nCalculates the Ulcer index of an asset.\n```python\nfrom PyTechnicalIndicators.Single.volatility_indicators import ulcer_index\nclose_prices = [103, 105, 106, 104, 101]\nui = ulcer_index(close_prices)\nprint(ui)\n# 2.2719989771306217\n```\n\n##### Volatility Index\nCalculate the volatility index of an asset. Function takes an optional previous VI parameter if one has been calculated.\n```python\nfrom PyTechnicalIndicators.Single.volatility_indicators import volatility_index\nvi = volatility_index(high=190, low=120, close=150, period=14)\nprint(vi) \n# 5.0\nnext_vi = volatility_index(high=190, low=150, close=120, period=14, previous_volatility_index=vi)\nprint(next_vi)\n# 9.642857142857142\n```\n\n##### Volatility System\nCalculates the volatility system of an asset. Period defaults to 7, average true range constant defaults to 3. Takes an\noptional previous parameter is one is available.\n```python\nfrom PyTechnicalIndicators.Single.volatility_indicators import volatility_system\nhigh = [120, 125, 123]\nlow = [90, 110, 116]\nclose = [100, 115, 120]\nvs = volatility_system(high, low, close, period=3, average_true_range_constant=2)\nprint(vs) \n# (125, 32.44444444444444, 92.55555555555556, 16.22222222222222)\nhigh = [125, 123, 127]\nlow = [110, 116, 113]\nclose = [115, 120, 125]\nnext_vs = volatility_system(high, low, close, period=3, average_true_range_constant=2, previous_volatility_system=vs)\n# (125, 38.2962962962963, 86.7037037037037, 19.14814814814815)\n```\n\n### Chart Patterns\n\n#### Chart Trends\nA series of functions to help with OHLC analysis\n\n##### Get Trend Line\nCalculates the trend line for a series of points and locations. This function is primarily intended for internal use as the \nlocations of each point is expected and calculated by other functions. Returns slope then intercept.\n```python\nfrom PyTechnicalIndicators.Chart_Patterns.chart_trends import get_trend_line\nprice_points = [(100, 2), (110, 5), (115, 7), (140, 18)]\ntrend = get_trend_line(price_points)\nprint(trend)\n# (2.4315068493150687, 96.79794520547945)\n```\n\n##### Get Peak Trend\nCalculates the trend line for all peaks. Function takes a period parameter to determine the highest point within \nperiod, defaults to 5. Returns slope then intercept.\n```python\nfrom PyTechnicalIndicators.Chart_Patterns.chart_trends import get_peak_trend\nprices = [100, 103, 95, 90, 81, 99, 113, 99, 113, 95, 87, 92, 86, 94, 86, 82, 97, 77, 90, 107]\npeak_trend = get_peak_trend(prices, 10)\nprint(peak_trend)\n# (-0.860813704496788, 118.04496788008565)\n```\n\n##### Get Valley Trend\nCalculates the trend line for all valleys. Function takes a period parameter to determine the lowest point within \nperiod, defaults to 5. Returns slope then intercept.\n```python\nfrom PyTechnicalIndicators.Chart_Patterns.chart_trends import get_valley_trend\nprices = [100, 103, 95, 90, 81, 99, 113, 99, 113, 95, 87, 92, 86, 94, 86, 82, 97, 77, 90, 107]\npeak_trend = get_valley_trend(prices, 10)\nprint(peak_trend)\n# (-0.09683794466403162, 83.60079051383399)\n```\n\n##### Get Overall Trend\nCalculates the overall trend line for all prices. Returns slope then intercept.\n```python\nfrom PyTechnicalIndicators.Chart_Patterns.chart_trends import get_overall_trend\nprices = [100, 103, 95, 90, 81, 99, 113, 99, 113, 95, 87, 92, 86, 94, 86, 82, 97, 77, 90, 107]\noverall_trend = get_overall_trend(prices)\nprint(overall_trend)\n# (-0.48270676691729325, 98.88571428571429)\n```\n\n##### Breakdown Trends\nCalculates new trend starts and ends for a list of prices. The standard deviation multiplier defaults to 2 but can be \nupdated by caller, a higher multiplier is more forgiving in price changes before announcing a new trend. The sensitivity\ndenominator defaults to 2 and can be updated by caller, it decides how forgiving it should be when lists are small vs \nlarge lists.\n```python\nfrom PyTechnicalIndicators.Chart_Patterns.chart_trends import break_down_trends\nprices = [100, 103, 95, 90, 81, 99, 113, 99, 113, 95, 87, 92, 86, 94, 86, 82, 97, 77, 90, 107]\ntrend_breakdown = break_down_trends(prices)\nprint(trend_breakdown)\n# [(0, 1, 3.0, 100.0), (2, 4, -7.0, 109.66666666666667), (5, 7, 0.0, 103.66666666666667), (8, 15, -2.9404761904761907, 125.69047619047619), (16, 18, -3.5, 147.5), (19, 19, 0, 0)]\n```\n\n#### Peaks\n\n##### Get Peaks\nIntended use is to be used in combination with `get_peak_trends` so that peaks are highlight on chart with the trend\nline. Optional period can be passed in to determine the highest point of the period. Defaults to 5.\n```python\nfrom PyTechnicalIndicators.Chart_Patterns.peaks import get_peaks\nprices = [100, 103, 95, 90, 81, 99, 113, 99, 113, 95, 87, 92, 86, 94, 86, 82, 97, 77, 90, 107]\npks = get_peaks(prices, 10)\nprint(pks)\n# [(113, 6), (113, 8), (97, 16), (107, 19)]\n```\n\n#### Valleys\n\n##### Get Valleys\nIntended use is to be used in combination with `get_valley_trends` so that peaks are highlight on chart with the trend\nline. Optional period can be passed in to determine the lowest point of the period. Defaults to 5.\n```python\nfrom PyTechnicalIndicators.Chart_Patterns.valleys import get_valleys\nprices = [100, 103, 95, 90, 81, 99, 113, 99, 113, 95, 87, 92, 86, 94, 86, 82, 97, 77, 90, 107]\nvalleys = get_valleys(prices, 10)\nprint(valleys)\n# [(113, 6), (113, 8), (97, 16), (107, 19)]\n```\n\n## License\n`PyTechnicalIndicators` is available under the GNU AFFERO GENERAL PUBLIC LICENSE.\n\nThe following information was taken from [choosealicense.com](choosealicense.com/licenses/agpl-3.0/)\n\n\u003e Under GNU AGPLv3 copyright and license notices must be preserved. Contributor provide an express grant of patent \n\u003e rights. When a modified version is used to provide a service over a network, the complete source code of the modified\n\u003e version must be made available.\n\nFor more information go look at the `License`\n\n## Contributing\n\nTo contribute to `PyTechnicalIndicators` follow these simple steps:\n* Raise a PR with your changes\n* If there is a new function make sure that a test covers it\n* Assign 0100101001010000 to the PR\n\nFor ideas on how to contribute go to `Contributing.md` and pick an item from the TODO list. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0100101001010000%2Fpytechnicalindicators","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F0100101001010000%2Fpytechnicalindicators","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0100101001010000%2Fpytechnicalindicators/lists"}