-
-
Save itsbalamurali/3126706e77ced6845debfab6e02ec272 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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