0bps

Strategy vault / Trend following

Low High Trend Strategy

This strategy is designed based on the market principle of buying low and selling high. It tracks the highest and lowest prices over a certain period, establishes a long position when the price breaks through the…

Author
ChaoZhang
Complexity
Intermediate · 49 lines
Parameters
8
Backtest bar
1d · swing
Tested on
BTC/USDT · futures

IMG

Overview

This strategy is designed based on the market principle of buying low and selling high. It tracks the highest and lowest prices over a certain period, establishes a long position when the price breaks through the lowest price, and closes the position when the price falls below the highest price or the take profit condition is met. At the same time, this strategy adds an optional trend filter that only allows buying when the price is in an uptrend.

Strategy Logic

Highest and Lowest Price Calculation

  • Lowest price (lowcriteria): Call ta.lowest function to calculate the lowest price over the lookback period set by user (default 20 bars) and plot the lowest price line.

  • Highest price (highcriteria): Call ta.highest function to calculate the highest price over the lookback period set by user (default 10 bars) and plot the highest price line.

Entry Signal

When the current price breaks through the lowest price line, a buy signal is triggered to establish a long position.

Exit Signal

Two exit methods are provided for option:

  1. Fixed take profit: Close the position for profit when the price reaches the preset take profit level (e.g. 8% above entry price).

  2. Breakdown of highest price: Close the position to cut losses when the price falls below the highest price line, judging a trend reversal.

Trend Filter

Add an EMA line to determine the trend direction. Allow buying only when the price is above EMA line (an uptrend). This filter can be enabled or disabled.

Advantage Analysis

  • Adopt the classic strategy of buying low and selling high, aligning with market fundamentals.

  • Add trend judgment to avoid frequent opening during price fluctuations.

  • Provide two exit options for pursuing high profits or reducing losses.

  • Customizable parameters adapt to more market environments.

  • Huge room for strategy optimization via parameter tuning, filter design etc.

Risk Analysis

  • Fixed take profit level fails to adjust based on actual market moves, resulting in premature profit-taking or insufficient profit target.

  • Selling at the breakdown of highest price may already generate huge losses, unable to effectively control losses.

  • EMA trend judgment only looks back a certain period, possibly lagging behind the actual trend change.

  • Backtest results cannot represent the future. Live performance has uncertainties.

Optimization Directions

  • Add profit-taking methods like trailing stop, partial exit etc. to dynamically adjust take profit level.

  • Optimize exit signals e.g. partial exits, adding other indicators.

  • Enhance trend judgment by incorporating more indicators or machine learning.

  • Optimize parameters by more extensive backtests to find optimum sets.

  • Add stop loss methods to better control losses.

Summary

This strategy generally applies the classic low buy high sell principle and can perform well under certain conditions. But there is still room for improving via parameter tuning, exit optimization, stop loss mechanisms etc. This article provides an in-depth analysis on the strategy's logic, pros, cons and optimization directions, aiming to share the strategy idea as well as remind investors of the risks and trade cautiously with quantitative strategies.

Parameters

NameDefaultWhat it controls
v_input_1timestamp(01 Jan 2000 05:00 +0000)Start Time
v_input_2timestamp(01 Jan 2099 00:00 +0000)End Time
v_input_320Lowest Price Lookback
v_input_410Highest Price Lookback
v_input_5trueSell with Take-Profit % intead of highest price cross?
v_input_float_18Take Profit %
v_input_6trueOnly buy when price is above EMA trend?
v_input_7200EMA Length

Source Pine Script

/*backtest
start: 2022-11-16 00:00:00
end: 2023-11-22 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// @version=5
// Author = TradeAutomation


strategy(title="Low-High-Trend Strategy", shorttitle="Low-High-Trend Strategy", process_orders_on_close=true, overlay=true, commission_type=strategy.commission.cash_per_order, commission_value=1, slippage=3, initial_capital = 25000, margin_long=50, margin_short=50, default_qty_type=strategy.percent_of_equity, default_qty_value=110)


// Backtest Date Range Inputs // 
StartTime = input(defval=timestamp('01 Jan 2000 05:00 +0000'), title='Start Time')
EndTime = input(defval=timestamp('01 Jan 2099 00:00 +0000'), title='End Time')
InDateRange = true

// Strategy Calculations //
lowcriteria = ta.lowest(close, input(20, "Lowest Price Lookback", tooltip="The strategy will BUY when the price crosses over the lowest it has been in the last X amount of bars"))[1]
highcriteria = ta.highest(close, input(10, "Highest Price Lookback", tooltip="If Take-Profit is not checked, the strategy will SELL when the price crosses under the highest it has been in the last X amount of bars"))[1]
plot(highcriteria, color=color.green)
plot(lowcriteria, color=color.red)

// Take Profit //
TakeProfitInput = input(true, "Sell with Take-Profit % intead of highest price cross?")
TakeProfit = ta.crossover(close,strategy.position_avg_price*(1+(.01*input.float(8, title="Take Profit %", step=.25))))

// Operational Functions //
TrendFilterInput = input(true, "Only buy when price is above EMA trend?")
ema = ta.ema(close, input(200, "EMA Length"))
TrendisLong = (close>ema)
plot(ema)

// Entry & Exit Functions//
if (InDateRange and TrendFilterInput==true)
    strategy.entry("Long", strategy.long, when = ta.crossover(close, lowcriteria) and TrendisLong)
if (InDateRange and TrendFilterInput==false)
    strategy.entry("Long", strategy.long, when = ta.crossover(close, lowcriteria))
if (InDateRange and TakeProfitInput==true)
    strategy.close("Long", when = TakeProfit)
if (InDateRange and TakeProfitInput==false)
    strategy.close("Long", when = ta.crossunder(close, highcriteria))
if (not InDateRange)
    strategy.close_all()
    

Published by ChaoZhang on the FMZ strategy square · last modified 2023-11-23. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.

Build this with AgenKit

A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.

in Claude Code, Cursor, Codex & 4 more
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/Low-High-Trend-Strategy.md
  1. npx agenkit install engineering-kit in your project
  2. Paste the command into your agent and approve each phase
  3. Get tests, backtest, risk controls and a paper-trading switch

Understand it first

Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.

Related specs

esc

Try , , or .

↑↓ move↵ open