Strategy Overview
BullTrender employs a series of technical indicators to drive decision-making in real-time trading:
- SuperTrend: Utilized for its effectiveness in determining the prevailing market direction based on price volatility.
- Moving Average Convergence Divergence (MACD): This indicator is crucial for identifying momentum shifts by comparing the interplay between short-term and long-term price trends.
- Simple Moving Averages (SMA): Incorporates both fast and slow SMAs to provide insights into immediate and longer-term market trends.
- Relative Strength Index (RSI): Measures the velocity and magnitude of price movements to identify potential market extremes.
- Volume Analysis: Assesses trading volume against historical averages to validate the strength of price movements and market sentiment.
![superbulltrender 1980x1080 web](https://api.machinatrader.com/wp-content/uploads/2024/04/superbulltrender_1980x1080_web-1024x576.jpg)
Trading Logic
- Buy Signal: A buy order is executed when the following bullish indicators converge, indicating a strong potential for upward movement:
– SuperTrend shows a positive reading.
– MACD line is above its signal line.
– Fast SMA exceeds the Slow SMA.
– RSI is above 50.
– Current trading volume is significantly higher than the historical average, adjusted by the predetermined Volume Multiplier. - Sell Signal: Sell orders are placed when any of the following conditions suggest a downturn or diminishing momentum:
– SuperTrend indicates a downward trend.
– MACD line falls below the signal line.
– Fast SMA is below the Slow SMA.
– RSI drops below 50.
- Hold: Consistent with MachinaTrader’s operational guidelines, BullTrender does not issue explicit ‘hold’ signals. Instead, it maintains the current position by default when neither buy nor sell criteria are met, thus avoiding unnecessary trades and optimizing portfolio stability.
When to Use and how to Optimize
BullTrender is best utilized in environments where Bitcoin displays clear price movements and substantial volumes. It is particularly well-suited for day traders who are actively engaged and can respond quickly to the signals provided by the strategy.
Optimization of BullTrender involves fine-tuning its parameters based on ongoing market analysis and backtesting results:
- Backtesting: Regularly test the strategy against historical data to assess its performance and make necessary adjustments.
- Parameter Adjustments: Tailor the periods for MACD, SMA, RSI, and the settings for SuperTrend to align with current market volatility and trading patterns. The Volume Multiplier may also be adjusted to better gauge the significance of volume changes.
- Market Responsiveness: Adapt parameter settings in response to changes in market conditions. Shorter periods may be more effective during high volatility, whereas longer periods can help reduce the noise in more stable conditions.
The BullTrender strategy on the MachinaTrader platform provides a robust tool for traders aiming to exploit the dynamic nature of the Bitcoin market. Through strategic parameter adjustments and vigilant market monitoring, traders can enhance their trading performance while managing risk effectively.
Code
using System;
using System.Linq;
using MachinaEngine.Data;
using MachinaEngine.Data.Market;
using System.Collections.Generic;
using MachinaEngine.Parameters;
using MachinaEngine.Interfaces;
using MachinaEngine.Orders;
using MachinaEngine.Algorithm.MTIndicators;
using static MachinaEngine.Algorithm.MTIndicators.TradeBarExtensions;
namespace MachinaEngine.Algorithm.CSharp
{
public class BitcoinDayTrader : MEAlgorithm
{
#region Parameters
[Parameter("Fast SMA Period")]
public int FastSMAPeriod { get; set; } = 7;
[Parameter("Slow SMA Period")]
public int SlowSMAPeriod { get; set; } = 25;
[Parameter("RSI Period")]
public int RSIPeriod { get; set; } = 14;
[Parameter("SuperTrend Period")]
public int SuperTrendPeriod { get; set; } = 10;
[Parameter("SuperTrend Multiplier")]
public decimal SuperTrendMultiplier { get; set; } = 3m;
[Parameter("MACD Fast Period")]
public int MACDFastPeriod { get; set; } = 12;
[Parameter("MACD Slow Period")]
public int MACDSlowPeriod { get; set; } = 26;
[Parameter("MACD Signal Period")]
public int MACDSignalPeriod { get; set; } = 9;
[Parameter("Volume Multiplier")]
public decimal VolumeMultiplier { get; set; } = 1.5m;
#endregion
public int BarsBack = 100;
public override void Initialize()
{
foreach (var symbol in MTO.Symbols)
{
SetupHistory(symbol, MTO.PeriodSeconds, BarsBack);
}
}
public override void OnTradeBar(Slice slice)
{
foreach (var symbol in slice.Symbols)
{
var history = SymbolHistory(symbol, MTO.PeriodSeconds);
if (history == null || history.Count < BarsBack)
{
Error($"Insufficient history for {symbol}.");
continue;
}
// Assuming SuperTrend, MACD, and SMA return single latest values directly
var superTrend = history.SuperTrend(SuperTrendPeriod, SuperTrendMultiplier).LastOrDefault();
var macd = history.Macd(MACDFastPeriod, MACDSlowPeriod, MACDSignalPeriod);
var fastSMA = history.Sma(FastSMAPeriod).LastOrDefault() ?? 0m;
var slowSMA = history.Sma(SlowSMAPeriod).LastOrDefault() ?? 0m;
var rsi = history.Rsi(RSIPeriod).LastOrDefault() ?? 0m;
var currentVolume = history.LastOrDefault()?.Volume ?? 0;
var averageVolume = history.Average(x => x.Volume);
if (superTrend.IsBullish && macd.Macd.LastOrDefault() > macd.Signal.LastOrDefault() &&
fastSMA > slowSMA && rsi > 50 &&
currentVolume > averageVolume * VolumeMultiplier)
{
if (!Portfolio[symbol].Invested)
{
SetHoldings(symbol, 1.0); // Buy
Log($"Buying {symbol} at {Time}");
}
}
else if (!superTrend.IsBullish || macd.Macd.LastOrDefault() < macd.Signal.LastOrDefault() ||
fastSMA < slowSMA || rsi < 50)
{
if (Portfolio[symbol].Invested)
{
Liquidate(symbol); // Sell
Log($"Selling {symbol} at {Time}");
}
}
// Plotting corrections
Plot(symbol.Value, "SuperTrend", superTrend.SuperTrend ?? 0m);
Plot(symbol.Value, "MACD", macd.Macd.LastOrDefault() ?? 0m);
Plot(symbol.Value, "Signal", macd.Signal.LastOrDefault() ?? 0m);
Plot(symbol.Value, "Fast SMA", fastSMA);
Plot(symbol.Value, "Slow SMA", slowSMA);
Plot(symbol.Value, "RSI", rsi);
}
}
public override void OnEndOfAlgorithm()
{
Log($"{Time} - TotalPortfolioValue: {Portfolio.TotalPortfolioValue}");
}
}
}