trend-follow.io

Opensource trend-following systematic trading algorithms based on top trend following traders (Richard Dennis, Olivier Seban and Nick Radge).

Turtle strategy pro

The modified Turtle Trading strategy for trading cryptocurrencies (BTCUSD and ETHUSD) from famous trend-following approach developed by legendary commodity traders Richard Dennis and William Eckhardt in the early 1980s. The strategy involves buying a stock or contract during a breakout (when prices move above a trading range) and quickly selling on a retracement or price fall.

Prerequisites

  • Liquidity
  • Volatility
  • Trending market

Table of Contents

About strategy

The Turtle Trading strategy was developed by Richard Dennis and William Eckhardt in the early 1980s. Story relates that Richard Dennis, a successful commodity trader, believed that trading could be taught to anyone and decided to conduct an experiment to confirm his theory. He created a group of people known as the “Turtles” and taught them his trade system.

The basic principle of the Turtle Trading strategy is to follow the trend. The goal is to identify and trade strong trends on financial markets. Turtles learned to buy and hold futures contracts for markets that were in a strong uptrend and sell short and hold contracts for markets in a strong downtrend. Personally, I think it’s better focus on markets in a long-term up-trend and trade only on the long side.

“Turtle trading trading system is simple to learn but to work properly it requires a trending market, confidence in the system, consistency and discipline.” Richard Dennis

Prerequisites

  • Liquidity
  • Volatility
  • Trending market

Author

Richard Dennis, a legendary figure in the world of trading, rose to prominence in the 1980s with his innovative trading strategies. Born in 1949, Dennis started his career as a commodities trader in Chicago. He gained widespread recognition for his role in the Turtle Trading Experiment, where he famously recruited and trained a group of novice traders, teaching them his proprietary trading techniques.

Dennis’ trading philosophy emphasized the importance of following systematic rules rather than relying on emotions or intuition. He believed that successful trading could be taught, regardless of one’s background or experience. This belief was exemplified in the Turtle experiment, where his students, dubbed the “Turtle Traders,” achieved remarkable success.

Richard Dennis’s legacy endures as a testament to the power of disciplined trading strategies and the potential for individuals to achieve success in the financial markets with the right guidance and methodology.

Entry and exit conditions for long side

Entry

  • Price break-out above max 20 days high price (set stop market order)

Exit

  • Price break-out below min 10 days low price (stop loss move to break even point and then use default turtle exit - Daily close price is below min 10 days low price)

Position sizing

The size of the position is determined on the basis of volatility, the more volatile the market, the smaller the positions, and conversely, the less volatile the market, the larger positions are traded so that the risk per trade is always the same in various volatile markets.

Simple by ATR

private double ComputeTradeAmount(){
    int AtrMultiplier = 2;
    double amount = (RiskPerTradeInPercentage * AccountSize) / AtrMultiplier * ATR(20, Days)
    return amount;
}

Advance accurately determine the percentage risk

private double ComputeTradeAmount(double entryPrice, double stopPrice)
{
    double riskPerTrade = (RiskPercentage / 100) * Account.Balance;
        double move = entryPrice - stopPrice;
        double amountRaw = riskPerTrade / ((Math.Abs(move) / Symbol.PipSize) * Symbol.PipValue);
        double amount = ((int)(amountRaw / Symbol.VolumeInUnitsStep)) * Symbol.VolumeInUnitsStep;
        return amount;
}

Management of position

  • Only one position open for one market.

Code example

Example strategy implementation in C# programming language for trading platform cTrader.

using System;

using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;


namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class TurtleTrendFollowPro_cBot : Robot
    {
    
        // ********************************
        // User defined inputs
        // ********************************
        
        // Basic settings
        [Parameter("Entry Length", Group ="Basic settings", DefaultValue =20)]
        public int EntryLength {get; set;}
        
        [Parameter("Exit Length", Group ="Basic settings", DefaultValue =10)]
        public int ExitLength {get; set;}
        
        [Parameter("Risk Percentage", Group ="Basic settings", DefaultValue =1)]
        public double RiskPercentage {get; set;}
        
        // Filter settings
        [Parameter("Enable Filter", Group ="Filter settings", DefaultValue =false)]
        public bool EnableFilter {get; set;} 
        
        [Parameter("Price above SMA(X)", Group ="Filter settings", DefaultValue =200)]
        public int SmaLength {get;set;}
        
        [Parameter("RSI > X", Group ="Filter settings", DefaultValue = 0)]
        public int RsiValue {get;set;}
        
        
        protected override void OnStart()
        {
            OnBarClosed();
        }

        protected override void OnBarClosed()
        {
            // **********************************
            // Perform calculations and analysis
            // **********************************
            
            // Basic
            double upperChannel = Indicators.DonchianChannel(EntryLength).Top.LastValue;
            double lowerChannel = Indicators.DonchianChannel(ExitLength).Bottom.LastValue;
            double closePrice = Bars.ClosePrices.LastValue;
            string label = $"TurtleTrendFollow_cBot-{Symbol.Name}-L1";
            Position position = Positions.Find(label);
            
            // Trade amount
            double qtyInLots = ComputeTradeAmount(upperChannel,lowerChannel);
            
            // Filter
            bool priceAboveSMA = closePrice > Indicators.SimpleMovingAverage(Bars.ClosePrices, SmaLength).Result.LastValue;
            bool rsiAboveValue = Indicators.RelativeStrengthIndex(Bars.ClosePrices, 14).Result.LastValue > RsiValue;
            bool filter = EnableFilter ? priceAboveSMA && rsiAboveValue : true;
       
            
            // ********************************
            // Manage trade
            // ********************************
            
            if(position == null)
            {
                if(filter)
                {
                
                    // Cancel all pending orders for this symbol
                    foreach(PendingOrder pendingOrder in PendingOrders){
                        if(pendingOrder.Label == label)
                        {
                            CancelPendingOrder(pendingOrder);
                        }
                    }
                
                    // Place stop order or market order
                    double stopLossPips = (Math.Abs(upperChannel - lowerChannel)/Symbol.PipSize);
                    if(closePrice >= upperChannel)
                    {
                      ExecuteMarketOrder(TradeType.Buy, Symbol.Name, qtyInLots, label, stopLossPips, null);
                    } else
                    {
                       PlaceStopOrder(TradeType.Buy,Symbol.Name,qtyInLots,upperChannel,label,stopLossPips,null);
                    }
                }

            } else {
               // Update stop loss
               double stopLossPrice = lowerChannel < position.EntryPrice ? lowerChannel : position.EntryPrice;
               ModifyPosition(position,stopLossPrice,position.TakeProfit);
               
               if(closePrice < lowerChannel){
                    position.Close();
               }
            }

            Print("Sucessful call OnBarClosed() method.");
         }
        
        private double ComputeTradeAmount(double entryPrice, double stopPrice)
        {
            double riskPerTrade = (RiskPercentage / 100) * Account.Balance;
            double move = entryPrice - stopPrice;
            double amountRaw = riskPerTrade / ((Math.Abs(move) / Symbol.PipSize) * Symbol.PipValue);
            double amount = ((int)(amountRaw / Symbol.VolumeInUnitsStep)) * Symbol.VolumeInUnitsStep;
            return amount;
        }
        
    }   
}

Source code on github

Backtests

Suitable markets for trading

  • Cryptocurrencies (Bitcoin, Ethereum)

Resources

About Us


We are small team of freelance software developers and trend follow momentum base algo traders on cryptocurrencies and US stocks market.

We specializes in developing custom algo trading strategies and indicators in many trading platforms as TradingView, cTrader, TradeStation or MultiCharts.

You can hire us for consulting/developing algotrading systems.

Discord: Trend-follow.io
Email: trend-follow@mailinator.com