Technical Analysis Using Python: Stochastic Oscillator (Basic)
utopian-io·@imwatsi·
0.000 HBDTechnical Analysis Using Python: Stochastic Oscillator (Basic)
# Repository With Sample Code https://github.com/imwatsi/crypto-market-samples Find the complete Python script on GitHub: [ta_stoch.py](https://github.com/imwatsi/crypto-market-samples/blob/master/ta_stoch/ta_stoch.py) # My Profile On GitHub You can find code used in this tutorial as well as other tools and examples in the GitHub repositories under my profile: https://github.com/imwatsi # What Will I Learn - Import ETHUSD 1 hour candle data from HitBTC - How to use the Stochastic Oscillator class from the open source technical analysis library from Bitfinex - Filter the results based on basic overbought and oversold readings # Requirements - Python 3.6+ - Dependencies - ```requests``` module - ```bfxhfindicators``` module - Active internet connection # Difficulty **Basic** <center></center> # Tutorial Content In this tutorial, we will use the Stochastic indicator from **bfxhfindicators** to calculate the Stochastic Oscillator values of the ETHUSD market, in the 1 hour timeframe. ## Definitions of terms Here are a few definitions of technical terms used in this tutorial: - **Stochastic Oscillator**: a momentum indicator comparing a particular closing price of a security to a range of its prices over a certain period of time. It is used to generate overbought and oversold trading signals, within a 0-100 bounded range of values. It has two values: K and D. K is a fast moving value and D lags behind and is less sensitive to fluctuations. - **Candles**: candle, also called candlestick, is a representation of a range of prices that an asset traded within over a certain period of time. They are used to generate candlestick charts. Each candle has *high, low, open, and close* price values. When obtained from the exchanges, volume info is also included - **Overbought**: a state in which the price has been increasing and is considered due for a reversal - **Oversold**: a state in which the price has been decreasing and is considered due for a reversal ## About the Stochastic indicator The Stochastic indicator from **bfxhfindicators** accepts candles as input. This means we need to feed it dictionary entries of candles, i.e. a stream of dictionaries containing the following: - `high`: the highest price reached during the time period - `low`: the lowest price traded at during the time period - `close`: the price at which the time period ended ## An overview Below is a screenshot of the ETHUSD chart on TradingView, showing the 1 hour candles and the Stochastic Oscillator values beneath. <center></center> What we want to do is to have an object in our code that contains the current values for the %K and %D Stochastic Oscillator numbers. This can be used as part of a strategy to initiate buy or sell signals. ## Let's write the code ### Import the modules We first import the modules needed: ``` import requests import json import time from bfxhfindicators import Stochastic from threading import Thread ``` - `requests` to connect to the HitBTC REST API and get candle data - `json` to parse responses received via requests - `time` for implementing time delays - `bfxhfindicators` module hosts the 'Stochastic' class, which we will use for the technical analysis - `threading` to use the Thread class to open new threads for functions ### Define a function that continuously loads candle data To have continuously updated candle data, a loop is created. It will make a request to the HitBTC API for the latest candle data, at a predefined rate (every 5 seconds in this tutorial, but can be anything you want). This will update the values for the latest candle (the hour we are in) and will also add new candles when we enter a new hour. ``` candles = [] def load_candles(): global candles while True: resp = requests.get('https://api.hitbtc.com/api/2/public/candles/ETHUSD?period=H1') raw_candles = json.loads(resp.content) parsed_candles = [] for raw_c in raw_candles: new_candle = { 'timestamp': raw_c['timestamp'], 'close': float(raw_c['close']), 'low': float(raw_c['min']), 'high': float(raw_c['max']) } parsed_candles.append(new_candle) candles = parsed_candles[:] time.sleep(5) ``` We also defined a variable ```candles = []``` which will store the candles. We define it here because it will be referenced by some code that starts before the requests come in from the server. Without this explicit definition, an error will occur for trying to reference a variable before it is defined. By issuing a GET request to the url ```https://api.hitbtc.com/api/2/public/candles/ETHUSD?period=H1```, we state the symbol 'ETHUSD' and time period for candle 'H1' for 1 hour. HitBTC sends back a JSON object containing a list of dictionaries, with each dictionary being a candle. Here's the format: ``` [ { "timestamp": "2017-10-20T20:00:00.000Z", "open": "0.050459", "close": "0.050087", "min": "0.050000", "max": "0.050511", "volume": "1326.628", "volumeQuote": "66.555987736" }, ... ``` As it is, we cannot pass this dictionary format to the Stochastic indicator because it requires the 'high' and 'low' keys, which in this case are named 'max' and 'min' respectively. That's where the code under this 'for' statement comes into play: ```for raw_c in raw_candles:```. This is effectively a loop that goes through the entire list of candles and recreates it, changing the 'max' and 'min' keys to 'high' and 'low', saving the resulting list in the variable ```parsed_candles```. This final line code copies the new list to our global variable ```candles``` which we will use for our technical analysis: ```candles = parsed_candles[:]```. ### The main code From this point, we write the code that will start executing as soon as the script is run. First, we start a new thread for the ```load_candles()``` loop. ``` # start loop that loads candles Thread(target=load_candles).start() ``` Next, we put a loop with a time delay conditioned on the length of the ```candles``` variable. It makes the script wait until the candles are loaded (until the length of the candles list is bigger than zero). ``` # wait for candles to populate while len(candles) == 0: time.sleep(1) ``` Finally, we write code to do the calculations for the Stochastic Oscillator: ``` # calculate Stochastic Oscillator values while True: iStoch = Stochastic([14,3,3]) for candle in candles: iStoch.add(candle) stoch_values = iStoch.v() # print Stochastic values, identify basic levels str_print = 'ETHUSD: K:%s D:%s' %(round(stoch_values['k'],4), round(stoch_values['d'],4)) if stoch_values['k'] > 80 and stoch_values['d'] > 80: str_print += ' In overbought area...' elif stoch_values['k'] < 20 and stoch_values['d'] < 20: str_print += ' In oversold area...' print(str_print, end='\r', flush=True) time.sleep(1) ``` The Stochastic Oscillator will have the following settings: - K = 14 - D = 3 - Smooth = 3 - This line is used to create an instance of the indicator with those settings: ```iStoch = Stochastic([14,3,3])``` - The current Stochastic values are stored in the ```stoch_values``` variable by this line ```stoch_values = iStoch.v()```. - The section commented "print Stochastic values..." prints the values on the terminal, in realtime. ### Basic filtering based on Stochastic values In the code above, a simple way to filter the results of the Stochastic Oscillator is shown. Values are checked for being either above 80 (for overbought readings) or below 20 (for oversold readings). Much more can be done with these values, including identifying divergences with price action, or identifying when the faster moving %K crosses the smaller moving %D in critical areas. I plan to write a follow-up tutorial with these more advanced filters in the near future. This brings us to the end of this tutorial. #### Find the complete Python script on GitHub: [ta_stoch.py](https://github.com/imwatsi/crypto-market-samples/blob/master/ta_stoch/ta_stoch.py) # Other Related Tutorials [Use Python to Retrieve All USDT Trading Pairs on Binance and Filter by {Price Vs EMA}](https://steemit.com/utopian-io/@imwatsi/use-python-to-retrieve-all-usdt-trading-pairs-on-binance-and-filter-by-price-vs-ema)
👍 seb3364, jadabug, ezravandi, accelerator, supelie, ayomite, soradrofr, dedite, intendoul, yacailyon, aclana, ackanen, adassid, entendes, inton6, esugacha, atradads, xumsofe, edson2, rallo, indedist, entath6, dedledoof, dianna1, mightypanda, bluesniper, primeradue, rimeldal, arerou, herorener, gasengexr, hdtrade, routith, laithut, rowra, ortaisa, yirempon, coorden, unoun, ariofedse, unememe, noraron, ofing, orsustart, hatadru, actearow, veddol, yirsuso, futuramer, pisatofro, ummaispo, ezesting, erorsai, essic, reema6, owantedi, imrimrin, undereda, upona, edese, horsup, fiste, eseane, amosbastian, tobias-g, rufans, helo, jaff8, buckydurddle, jinger, codingdefined, mirkosche, espoem, ascorphat, mops2e, zcool, mcfarhat, penguinpablo, cryptonized, taifkhan, miniature-tiger, utopian.trail, techslut, minersean, erikaflynn, jakipatryk, suesa, che-shyr, didic, suesa-random, daan, abh12345, tykee, silviu93, dakeshi, elear, zoneboy, mcyusuf, gentleshaid, aussieninja, sargoon, darewealth, dongentle2, jubreal, rollthedice, bflanagin, jk6276, dssdsds, jayplayco, stem-espanol, mrsbozz, jk6276.mons, jaxson2011, carloserp-2000, emiliomoron, tomastonyperez, viannis, erickyoussif, ubaldonet, lupafilotaxia, aleestra, lorenzor, tsoldovieri, iamphysical, felixrodriguez, azulear, ivymalifred, vjap55, elvigia, luiscd8a, josedelacruz, joseangelvs, fran.frey, giulyfarci52, wilmer14molina, rewarding, vanarchist, crokkon, alaiza, lapp, steemtpistia, crassipes, agrovision, harry-heightz, eastmael, eliaschess333, dalz, alexs1320, cpufronz, scienceangel, yu-stem, alex-hm, amestyj, cyprianj, eniolw, carlos84, anaestrada12, steem-ua, newsrx, tdre, ryuna.siege, jjay, properfraction, utopian-io, tombstone, jga, cryptouno, dicetime, kaczynski, meedo, blockcreate,