Try using the HL band in order

Introduction

This time, I made an algorithm using the HL (HighLow) band. For details on the HL band, please refer to the following article.

How to read and use HL bands [Technical indicators / trends]

Briefly, in the HL band, the line connecting the maximum value of the high price for a certain period (High band), the line connecting the minimum value of the low price (Low band), and the average line of the two lines (Middle band) I am using it.

Let's move on to the main subject.

HL band algorithm

signal

Buy signal: When the closing price (cp) breaks through the Middle band Sell signal: When the closing price (cp) falls below the Middle band or when the closing price breaks through the High band

I referred to here to determine the signal.

code

This code is here

#HL band
import maron
import maron.signalfunc as sf
import maron.execfunc as ef
import pandas as pd
import talib as ta 
import numpy as np 

#ot = maron.OrderType.MARKET_CLOSE #Order at the timing of the closing price the day after the signal is issued
ot = maron.OrderType.MARKET_OPEN   #Order at the timing of the opening price the day after the signal is issued
#ot = maron.OrderType.LIMIT        #Limit order

def initialize(ctx):
  #Setting
  ctx.logger.debug("initialize() called")
  ctx.configure(
    channels={               #Channel used
      "jp.stock": {
        "symbols": [
          "jp.stock.2914",
          "jp.stock.3382", 
          "jp.stock.4063", 
          "jp.stock.4452",
          "jp.stock.4502",
          "jp.stock.4503",
          "jp.stock.4568",
          "jp.stock.6094",
          "jp.stock.6501",
          "jp.stock.6758",
          "jp.stock.6861",
          "jp.stock.6954",
          "jp.stock.6981",
          "jp.stock.7203",
          "jp.stock.7267",
          "jp.stock.7751",
          "jp.stock.7974",
          "jp.stock.8031",
          "jp.stock.8058",
          "jp.stock.8306",
          "jp.stock.8316",
          "jp.stock.8411",
          "jp.stock.8766",
          "jp.stock.8802",
          "jp.stock.9020",
          "jp.stock.9022",
          "jp.stock.9432",
          "jp.stock.9433",
          "jp.stock.9437",
          "jp.stock.9984",
          
        ],
        "columns": [
          "close_price",     #closing price
          "close_price_adj", #closing price(After stock split adjustment)
          "high_price_adj",    #High price(After stock split adjustment)
          "low_price_adj",     #Low price(After stock split adjustment)
          "volume_adj",     #Volume
          "txn_volume",     #Trading price
        ]
      }
    }
  )
  
  #Signal definition
  def _my_signal(data):
    cp =  data["close_price_adj"].fillna(method='ffill')  #Get closing price
    hp = data["high_price_adj"].fillna(method='ffill')    #Get high
    lp = data["low_price_adj"].fillna(method='ffill')     #Get low price
    hband = hp.rolling(20).max()                          #High band setting
    lband = lp.rolling(20).min()                          #Low band setting
    mband = (hband - lband)/2 + lband                     #Middle band setting
    
    market_sig = pd.DataFrame(data=0.0, columns=cp.columns, index=cp.index)
    buy_sig = ((mband.shift(1) > cp.shift(1)) & (mband < cp))
    sell_sig = ((mband > cp) | (cp > hband))
    # buy_1 when sig is True.0、sell_When sig is True-1.Set to 0
    market_sig[buy_sig == True] = 1.0
    market_sig[sell_sig == True] = -1.0
    market_sig[(buy_sig == True) & (sell_sig == True)] = 0.0
    #ctx.logger.debug(market_sig)

    return {
      # "hband:g2": hband,
      # "lband:g2": lband,
      # "mband:g2": mband,
      "hband": hband,
      "lband": lband,
      "mband": mband,
      "market:sig": market_sig,
    }
      
  #Signal registration
  ctx.regist_signal("my_signal", _my_signal)

def handle_signals(ctx, date, current):
  '''
  current: pd.DataFrame
  '''
  market_sig = current["market:sig"]
  
  done_syms = set([])
  
  #Loss cut, profit setting
  for (sym, val) in ctx.portfolio.positions.items():
    returns = val["returns"]
    if returns < -0.02:
      sec = ctx.getSecurity(sym)
      sec.order(-val["amount"], comment="Loss cut(%f)" % returns)
      done_syms.add(sym)
    elif returns > 0.04:
      sec = ctx.getSecurity(sym)
      sec.order(-val["amount"], comment="Profit-taking sale(%f)" % returns)
      done_syms.add(sym)

  #Buy signal
  buy = market_sig[market_sig > 0.0]
  for (sym, val) in buy.items():
    if sym in done_syms:
      continue
    
    sec = ctx.getSecurity(sym)
    sec.order(sec.unit() * 1, orderType=ot, comment="SIGNAL BUY")
    #ctx.logger.debug("BUY: %s,  %f" % (sec.code(), val))
    pass
    
  # #Sell signal
  sell = market_sig[market_sig < 0.0]
  for (sym, val) in sell.items():
    if sym in done_syms:
      continue
    sec = ctx.getSecurity(sym)
    sec.order(sec.unit() * -1, orderType=ot, comment="SIGNAL SELL")
    #ctx.logger.debug("SELL: %s,  %f" % (sec.code(), val))
    pass

Code commentary

For the explanation of the basic code, please see here because the material created for the study session is at the link below.

I will explain the important points this time.

** Lines 69-71 **

    hband = hp.rolling(20).max()                          #High band setting
    lband = lp.rolling(20).min()                          #Low band setting
    mband = (hband - lband)/2 + lband                     #Middle band setting

Here, each band is set. Hband is the maximum value of the high price (cp) in the last 20 days, lband is the minimum value of the low price (lp) in the last 20 days, and mband is the average of hband and lband. Masu.

For more information about rolling, click here [https://pandas.pydata.org/pandas-docs/version/0.25.3/reference/api/pandas.core.window.Rolling.min.html)

** Lines 74-75 **

    buy_sig = ((mband.shift(1) > cp.shift(1)) & (mband < cp))
    sell_sig = ((mband > cp) | (cp > hband))

Buy signal: When the closing price (cp) breaks through mband Sell signal: When the closing price (cp) falls below mband or when the closing price breaks through hband

Back test results

hlband2.PNG

Profit and loss ratio is 17% in 3 years ,,,,

It's not very profitable.

Looking at the values of MaxDrawdown, SharpRatio, and α, there seems to be considerable room for improvement.

Impressions

The HL band is generally used in the breakout method, and it will stall unless it is a big market (a market where the entire stock market is booming and soaring compared to usual, and the trading volume is also greatly expanded). The results also show that using the HL band does not provide a very good algorithm in all situations, as it is often the case.

Disclaimer Precautions

Please note that we cannot guarantee any damage caused by actual trading using this code.

Recommended Posts

Try using the HL band in order
Try using the Wunderlist API in Python
Try using the Kraken API in Python
Try using the BitFlyer Ligntning API in Python
Try using the DropBox Core API in Python
Try using the Twitter API
Try using the Twitter API
Try using the PeeringDB 2.0 API
Try using Spyder included in Anaconda
Try using LevelDB in Python (plyvel)
Try using the Python Cmd module
Cython to try in the shortest
Try using Leap Motion in Python
Try using FireBase Cloud Firestore in Python for the time being
Try using the web application framework Flask
Try using the $ 6 discount LiDAR (Camsense X1)
Try using the camera with Python's OpenCV
Tweet using the Twitter API in Python
Try cluster analysis using the K-means method
Try the new scheduler chaining in PyTorch 1.4
Try hitting the YouTube API in Python
Try hitting the Spotify API in Django.
Try using Tkinter
Try using docker-py
Try to separate Controllers using Blueprint in Flask
[Cloudian # 7] Try deleting the bucket in Python (boto3)
Try using cookiecutter
Try using PDFMiner
Python: Try using the UI on Pythonista 3 on iPad
Try using the Chinese morphological analysis engine jieba
Try using geopandas
Try using Selenium
Try using scipy
Try using the Python web framework Tornado Part 1
Try using LINE Notify for the time being
Try drawing contour plots using matplotlib in OpenFOAM
Try using pandas.DataFrame
Pre-process the index in Python using Solr's ScriptUpdateProcessor
Try using the collections module (ChainMap) of python3
Try using django-swiftbrowser
Try using matplotlib
Try using the Python web framework Tornado Part 2
Try using tf.metrics
Try implementing the Monte Carlo method in Python
Try using PyODE
Try using an object-oriented class in R (R6 method)
Try using ChatWork API and Qiita API in Python
Get the file name in a folder using glob
[Unity (C #), Python] Try running Python code in Unity using IronPython
[AWS IoT] Register things in AWS IoT using the AWS IoT Python SDK
Initial settings when using the foursquare API in python
Determine the threshold using the P tile method in python
Try using the temperature sensor (LM75B) on the Raspberry Pi.
Try loading the image in a separate thread (OpenCV-Python)
About the uncluttered arrangement in the import order of flake8
Try to delete tweets in bulk using Twitter API
Try face detection in real time using a webcam
Try to decipher the login data stored in Firefox
Using the National Diet Library Search API in Python
[Python] How to output the list values in order
Using the LibreOffice app in Python (1) Where are the macros?