Skip to content

Instantly share code, notes, and snippets.

@itsbalamurali
Created February 18, 2021 09:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save itsbalamurali/3126706e77ced6845debfab6e02ec272 to your computer and use it in GitHub Desktop.
Save itsbalamurali/3126706e77ced6845debfab6e02ec272 to your computer and use it in GitHub Desktop.
using System;
using QuantConnect.Brokerages;
using QuantConnect.Data.Consolidators;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using QuantConnect.Orders;
using QuantConnect.Orders.Fees;
using QuantConnect.Securities;
using Telegram.Bot;
using Telegram.Bot.Types.Enums;
namespace QuantConnect.Algorithm.CSharp
{
public class SuperTrendRenko : QCAlgorithm
{
private MovingAverageConvergenceDivergence _macd;
private RelativeStrengthIndex _rsi;
private Momentum _mom;
private VolumeWeightedAveragePriceIndicator _vwap;
private AwesomeOscillator _awesomeOscillator;
private AverageTrueRange _atr;
private OrderTicket _takeprofit;
private OrderTicket _initial;
private string _symbol = "RELIANCE";
private TimeSpan tradingStartTime = new TimeSpan(9, 15, 0);
private TimeSpan tradingEndTime = new TimeSpan(15, 00, 0);
private Resolution _resolution = Resolution.Minute;
//private Identity _prevClose;
private SuperTrend _superTrend;
private DonchianChannel _donchianChannel;
private int capital = 100000;
private bool enableTgNotifications = true;
private string holdings = "| Ticker | Market | Quantity | AveragePrice | CurrentPrice |" + "\n" +
"|------|------|------|------|------|------|\n";
private TelegramBotClient botClient = new TelegramBotClient("");
public override void Initialize()
{
SetTimeZone(TimeZones.Kolkata);
// backtest parameters
SetStartDate(2020, 8, 1);
SetEndDate(2021, 1, 15);
SetAccountCurrency(Currencies.INR);
// cash allocation for backtesting
SetCash(capital);
SetBenchmark(t => 0);
AddEquity(_symbol, _resolution, Market.NSE);
Securities[_symbol].SetFeeModel(new ZerodhaFeeModel());
Securities[_symbol].SetLeverage(4);
Securities[_symbol].SetBuyingPowerModel(new CashBuyingPowerModel());
_macd = new MovingAverageConvergenceDivergence( 12, 26, 9);
_rsi = new RelativeStrengthIndex( 14, MovingAverageType.Exponential);
_mom = new Momentum( 14);
_vwap = VWAP(_symbol,14);
_superTrend = new SuperTrend("superTrend", 10, 3);
_atr = new AverageTrueRange( 14);
_donchianChannel = new DonchianChannel( 20);
_awesomeOscillator = new AwesomeOscillator( 34, 5);
var renkoConsolidator = new RenkoConsolidator(8);
renkoConsolidator.DataConsolidated += (sender, renkoBar) =>
{
HandleRenkoClose(renkoBar);
};
// register the consolidator for updates
SubscriptionManager.AddConsolidator(_symbol, renkoConsolidator);
RegisterIndicator(_symbol, _superTrend, renkoConsolidator);
RegisterIndicator(_symbol, _macd, renkoConsolidator);
RegisterIndicator(_symbol, _atr, renkoConsolidator);
RegisterIndicator(_symbol, _mom, renkoConsolidator);
RegisterIndicator(_symbol, _rsi, renkoConsolidator);
RegisterIndicator(_symbol, _donchianChannel, renkoConsolidator);
RegisterIndicator(_symbol, _awesomeOscillator, renkoConsolidator);
SetBrokerageModel(BrokerageName.Zerodha);
}
private void HandleRenkoClose(RenkoBar renkoBar)
{
var isMarketOpen = Time.TimeOfDay >= tradingStartTime && Time.TimeOfDay < tradingEndTime;
if (!isMarketOpen)
{
Log("Not our trading time!");
return;
}
if (!_macd.IsReady || !_superTrend.IsReady || !_atr.IsReady || !_awesomeOscillator.IsReady || !_donchianChannel.IsReady)
{
return;
}
var entryLimitPrice = (_atr.Current / 2) + renkoBar.Close;
var trend = _superTrend > renkoBar.Close ? "Red" : "Green";
var quantity = (Portfolio.Cash/entryLimitPrice).SmartRounding();
// Let's go long
if (
!Portfolio.Invested &&
renkoBar.Direction == BarDirection.Rising &&
_awesomeOscillator > 0 &&
renkoBar.High >= _donchianChannel.UpperBand.Current.Value &&
renkoBar.Close > _superTrend.Current.Value &&
trend == "Green"
)
{
//Send a Telegram Notifications
sendTgNotification("**Going Long 🔺 on " + _symbol + " at " + Time + " ** \n" +
statsNotification(renkoBar, _awesomeOscillator,
_donchianChannel, _atr.Current, _vwap, trend));
//Take Long Positions
//SetHoldings(_symbol, 1.0);
if (_takeprofit == null || _takeprofit.Status == OrderStatus.Filled)
{
_initial = LimitOrder(_symbol, quantity, entryLimitPrice);
}
}
//Exit Long
if (Portfolio.Invested && Portfolio[_symbol].IsLong && _donchianChannel.UpperBand != renkoBar.High)
{
if (_initial.Status == OrderStatus.Filled)
{
_takeprofit = LimitOrder(_symbol, -Portfolio[_symbol].Quantity, entryLimitPrice.SmartRounding());
}
}
//let's go short
if (
!Portfolio.Invested &&
renkoBar.Direction == BarDirection.Falling &&
renkoBar.Low <= _donchianChannel.LowerBand.Current.Value&&
_donchianChannel.Current > renkoBar.Close &&
_superTrend.Current > renkoBar.Close &&
_awesomeOscillator.Current < 0 &&
trend == "Red"
)
{
//Send a Telegram Notification
sendTgNotification("**Going Short 🔻 on " + _symbol + " at " + Time + " ** \n" +
statsNotification(renkoBar, _awesomeOscillator,
_donchianChannel, _atr.Current, _vwap, trend));
//Liquidate the portfolio
//Liquidate();
if (_takeprofit == null || _takeprofit.Status == OrderStatus.Filled)
{
_initial = LimitOrder(_symbol, -Portfolio[_symbol].Quantity, entryLimitPrice.SmartRounding());
}
}
if (Portfolio.Invested && Portfolio[_symbol].IsShort && _donchianChannel.LowerBand != renkoBar.Low)
{
if (_initial.Status == OrderStatus.Filled)
{
_takeprofit = LimitOrder(_symbol, -Portfolio[_symbol].Quantity, entryLimitPrice.SmartRounding());
}
}
}
public override void OnOrderEvent(OrderEvent orderEvent)
{
if (orderEvent.Status == OrderStatus.Filled)
{
sendTgNotification(orderEvent.ToString());
}
}
public override void OnEndOfDay(Symbol symbol)
{
foreach (var security in Portfolio)
{
holdings += "|" + Time + "|" + security.Key.ID.Symbol + "|" + security.Key.ID.Market + "|" +
security.Value.Quantity + "|" + security.Value.AveragePrice + "|" + security.Value.Price + "|\n";
}
sendTgNotification("Net P/L for the day: "+Portfolio[_symbol].NetProfit);
}
public override void OnEndOfAlgorithm()
{
// sendTgNotification("## End Of The Day: \n"+
// "**Free Margin Available:**` "+Portfolio.Cash.SmartRounding()+"`\n"+
// "**Holdings:**"+"\n"+
// holdings);
}
private string statsNotification(
RenkoBar renkoBar,
decimal awesomeOscillator,
DonchianChannel donchianChannel,
decimal _atrCurrentPrice,
decimal vwap,
string trend
)
{
return "**DateTime:** `" + Time + "`\n" +
"**RenkoBar Open:** `" + renkoBar.Open.RoundToSignificantDigits(2) + "`\n" +
"**RenkoBar High:** `" + renkoBar.High.RoundToSignificantDigits(2) + "`\n" +
"**RenkoBar Low:** `" + renkoBar.Low.RoundToSignificantDigits(2) + "`\n" +
"**RenkoBar Close:** `" + renkoBar.Close.RoundToSignificantDigits(2) + "`\n" +
"**RenkoBar Direction:** `" + renkoBar.Direction + "`\n" +
"**SuperTrend Direction:** `" + trend + "`\n" +
"**Awesome Oscillator:** `" + awesomeOscillator.RoundToSignificantDigits(2) + "`\n" +
"**Donchian Channel UpperBand:** `" + donchianChannel.UpperBand.Current.Value.RoundToSignificantDigits(2) + "`\n" +
"**Donchian Channel MiddleBand:** `" + donchianChannel.Current.Value.RoundToSignificantDigits(2) + "`\n" +
"**Donchian Channel LowerBand:** `" + donchianChannel.LowerBand.Current.Value.RoundToSignificantDigits(2) + "`\n" +
"**AverageTrueRange:** `" + _atrCurrentPrice.RoundToSignificantDigits(2) + "`\n" +
"**VWAP:** `" + vwap.RoundToSignificantDigits(2) + "`\n";
}
private async void sendTgNotification(string text)
{
if (enableTgNotifications)
{
await botClient.SendTextMessageAsync(
chatId: "", //My TG ChatID
text: text.Replace("#", "\\#").Replace("-", "\\-").Replace("|", "\\|").Replace(".", "\\."),
parseMode: ParseMode.MarkdownV2
);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment