Skip to main content

Detection for support and resistance trendlines on python

Project description

pytrendline

About

Given a OHLC candlestick chart, pytrendline allows you to detect support and resistance lines formed by the High and Close price series.

pytrendline preview

The trendline scanning algorithm scans for the existence of trendlines by attempting to draw lines between points [(0,1),(0,2),(0,3)...(0,N)] for the first iteration. Subsequent iteration attempts to draw lines between points [(1,2),(1,3),...(1,N)], then [(2,3),(2,4)...(2,N)] and so forth.

Because this operates by doing a full exhaustive search, the runtime is of cubic complexity O(N^3). If low latency is important and your use case is extremely large datasets, you might want to look into alternative algorithms / libraries. For picking up trendlines on day-trading use cases (small number of candles) or offline analysis it works great.

The algorithm also speeds up significantly if the search is narrowed down to only include lines with pivot points as one of the start or end points.

Note: pivot points are identified as local maximum or minimum points ie “troughs” and “peaks” in the candlestick chart.

How the algorithm works

  1. Pivot points are identified in the candlestick chart.

  2. In each scan between points (i,j), pytrendln attempts to draw a line on top of the candlestick chart and checks the following:

  • What are the “points” that make up the trendline? For a trendline to be valid it must satisfy the minimum number of points specified in argument detect(...) argument min_points_required. A date in a trendline is determined to be a valid “point” if the distance between the drawn trendline and the candlestick price does not exceed max_allowable_error_pt_to_trend

Error between trendline and price

  • Does the trendline cross over a candlestick body somewhere in its trajectory? If the trendline intersects some distance higher breakout_tolerance above the candlestick body, we consider this line to be a breakout. Breakout trendlines are only considered valid if detect(...) argument ignore_breakouts is set to False.

  • Checks if the trendline satisfies optional pivot point requirements. If not, the trendline is discarded.

A score is given to the trendline using scoring function specified in detect(...) argument config. The default scoring function scores trendlines higher if the mean distance between trendline and candle points are low and also gives additional favorability to a higher number of points.

Default scoring function:

"scoring_function": lambda candles, err_distances, num_points, slope: (util.avg_candle_range(candles) / util.mean(err_distances)) * (2.5 ** num_points),
  1. Oftentimes, the trendline search finds trendlines that are almost identical in slope and last price and groups them. Because we might only care about the best scored trendline from each of these groups, the best one is identified and you can choose to discard the rest for your analysis.

Duplicate grouping

This grouping is done by 2D clustering the set of (slope,last_price) pairs for all trendlines. Two trendlines are identified to be a part of the same group if both their slopes and last_price are within duplicate_grouping_threshold_slope and duplicate_grouping_threshold_last_price respectively.

  1. Results for all trendlines are returned into an easily sortable and filter-able Pandas dataframe.

Usage

For detecting trendlines, a Pandas dataframe containing OHLC data must be packaged into a pytrendline.CandlestickData object and then passed on to pytrendline.detect(...)

# Package Candlestick Data
candles_df = pd.read_csv('./fixtures/example.csv')
candles_df['Date'] = pd.to_datetime(candles_df['Date'])

candlestick_data = pytrendline.CandlestickData(
  df=candles_df,
  time_interval="1m", # choose between 1m,3m,5m,10m,15m,30m,1h,1d
  open_col="Open", # name of the column containing candle "Open" price
  high_col="High", # name of the column containing candle "High" price
  low_col="Low", # name of the column containing candle "Low" price
  close_col="Close", # name of the column containing candle "Close" price
  datetime_col="Date" # name of the column containing candle datetime price (use none if datetime is in index)
)

# Detect
results = pytrendline.detect(
  candlestick_data=candlestick_data,

  # Choose between BOTH, SUPPORT or RESISTANCE
  trend_type=pytrendline.TrendlineTypes.BOTH,
  # Specify if you require the first point of a trendline to be a pivot
  first_pt_must_be_pivot=False,
  # Specify if you require the last point of the trendline to be a pivot
  last_pt_must_be_pivot=False,
  # Specify if you require all trendline points to be pivots
  all_pts_must_be_pivots=False,
  # Specify if you require one of the trendline points to be global max or min price
  trendline_must_include_global_maxmin_pt=False,
  # Specify minimum amount of points required for trendline detection (NOTE: must be at least two)
  min_points_required=3,
  # Specify if you want to ignore prices before some date
  scan_from_date=None,
  # Specify if you want to ignore 'breakout' lines. That is, lines that interesect a candle
  ignore_breakouts=True,
  # Specify and override to default config (See docs on how)
  config={}
)

Tuning algorithm parameters

DEFAULT_CONFIG within source file detect.py [TODO LINK] contains default parameters regarding thresholds for pivot detection, trendline detection, grouping, scoring, etc. All of these config parameters are a lambda taking candlestick data as input.

You can override a default by passing a new key string + lambda pair to the config parameter in detect.

results = detect(
   …
   config={
        # Force the tolerance to be derived from last candle price
        "max_allowable_error_pt_to_trend": lambda candles: candles.iloc[-1].Close / 100,
   }
)

Plotting results

pytrendline provides a plot(...) function to visualize the results in an interactive HTML chart generated with the aid of Bokeh.

outf = pytrendline.plot(
  results=results,
  filedir='.',
  filename='example_output.html',
)
os.system("open " + outf)

In the resulting plot, pivot points are marked as green diamonds, best trendlines for each duplicate gruop is shown in solid dashed blue/orange, and non-best trendlines are shown in transaparent dotted blue/orange.

Running example

You can run the example included in this repo to get a taste of what is possible with this library.

  1. Clone this github repo into a local directory.
  2. Install required libraries using
pip install -r requirements.txt 
  1. Run
python example.py

Installing library

Library can install using pip:

pip install trendln

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytrendline-1.0.1.tar.gz (18.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytrendline-1.0.1-py3-none-any.whl (18.3 kB view details)

Uploaded Python 3

File details

Details for the file pytrendline-1.0.1.tar.gz.

File metadata

  • Download URL: pytrendline-1.0.1.tar.gz
  • Upload date:
  • Size: 18.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.5.0 pkginfo/1.7.0 requests/2.23.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.7.8

File hashes

Hashes for pytrendline-1.0.1.tar.gz
Algorithm Hash digest
SHA256 f8fe72c3d46860a7a498339125c90aebf275a11fd1cd95c08d4ef36f17020926
MD5 a2ebbac4fd946253565be8167f8f83c0
BLAKE2b-256 7f89a07942eec52e2abf6f00f8739425f9482c959f71d949fb9dd97201c565b1

See more details on using hashes here.

File details

Details for the file pytrendline-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: pytrendline-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 18.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.5.0 pkginfo/1.7.0 requests/2.23.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.7.8

File hashes

Hashes for pytrendline-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3e0ac5ab03eabf2a05a35755dba05be2d91747d1ae9edfc9d3b6999a0f31a97c
MD5 94b91a3f6d93fa0ea3d3561da952da4f
BLAKE2b-256 c1b942996698a140768fbd91e8cd56b2518792aa85fef8921b75d36679118c97

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page