public async Task TestBacktestWithValidationAsync() { var candles = await ImportIOhlcvDatasAsync(); var buyRule = Rule.Create(ic => ic.IsEmaBullishCross(21, 55)); var sellRule = Rule.Create(ic => ic.IsEmaBearishCross(21, 55)); var runner = new Builder() .Add(candles) .Buy(buyRule) .Sell(sellRule) .Build(); var result = await runner.RunAsync(1000); var transactionIndexes = result.Transactions.Select(t => t.Index); //var indexString = string.Join(",", transactionIndexes); foreach (var transactionIndex in transactionIndexes) { var ic = new IndexedCandle(candles, transactionIndex - 1); bool isBuyRuleValid = buyRule(ic); bool isSellRuleValid = sellRule(ic); Assert.IsTrue(isBuyRuleValid || isSellRuleValid); } }
public async Task TestRuleExecutorWithVerifyAsync() { var candles = await ImportIOhlcvDatasAsync(); void Verify(Predicate <IIndexedOhlcv> rule) { IReadOnlyList <IIndexedOhlcv> list; // Get all indexed candle who fulfill the rule using (var ctx = new AnalyzeContext(candles)) { var executor = new SimpleRuleExecutor(ctx, rule); list = executor.Execute(); } var indexList = list.Select(l => l.Index); //var indexString = string.Join(",", indexList); // Verify if fulfilled indexed candle is true or not foreach (var index in indexList) { var ic = new IndexedCandle(candles, index); Assert.IsTrue(rule(ic)); } } bool buyRule(IIndexedOhlcv ic) => ic.IsEmaBullishCross(21, 55); Verify(buyRule); bool sellRule(IIndexedOhlcv ic) => ic.IsEmaBearishCross(21, 55); Verify(sellRule); }
public bool BearishScan(Symbol symbol, IEnumerable <Candle> candles) { //Bearish Strategy var fiveEma = candles.Ema(5)[candles.Count() - 1]; var twentyEma = candles.Ema(20)[candles.Count() - 1]; var twentySma = candles.Sma(20)[candles.Count() - 1]; var macdHist = candles.MacdHist(12, 26, 9)[candles.Count() - 1]; var indexedCandle = new IndexedCandle(candles, candles.Count() - 1); var macdBearOsc = indexedCandle.IsMacdOscBearish(12, 26, 9); if (fiveEma.Tick.Value < twentyEma.Tick.Value && fiveEma.Tick.Value < twentySma.Tick.Value && (macdHist.Tick.Value >= _MinNegativeMacdMHist && macdHist.Tick.Value <= _MaxNegativeMacdHist) && macdBearOsc) { var currentCandle = candles.LastOrDefault(); //EMA and MACD Satisfied _zeropdhaService.PlaceOrder(new BrokerOrderModel() { JobId = _jobId, SymbolId = symbol.Id, Exchange = symbol.Exchange, TradingSymbol = symbol.TradingSymbol, InstrumentToken = symbol.InstrumentToken, TransactionType = Constants.TRANSACTION_TYPE_SELL, Quantity = _MinQuantity, OrderType = Constants.ORDER_TYPE_MARKET, Product = Constants.PRODUCT_MIS, Variety = Constants.VARIETY_CO, Validity = Constants.VALIDITY_DAY, TriggerPrice = Convert.ToInt32(((currentCandle.Close + (currentCandle.Close * Convert.ToDecimal(_RiskPercentage))) / symbol.TickSize)) * symbol.TickSize }); return(true); } return(false); }
public bool SquareOffOpenPosition(Symbol symbol, IEnumerable <Candle> candles, Position position, Order order, Order parentOrder) { var indexedCandle = new IndexedCandle(candles, candles.Count() - 1); var rewardAmount = parentOrder.Price * _RewardPercentage; if (position.Quantity < 0) { //close sell position if (indexedCandle.Close <= parentOrder.Price - (rewardAmount) || indexedCandle.IsMacdOscBearish(12, 26, 9) == false) { _zeropdhaService._kite.CancelOrder(order.OrderId, Constants.VARIETY_CO, order.ParentOrderId); return(true); } } else { //close buy position if (indexedCandle.Close >= parentOrder.Price + (rewardAmount) || indexedCandle.IsMacdOscBullish(12, 26, 9) == false) { _zeropdhaService._kite.CancelOrder(order.OrderId, Constants.VARIETY_CO, order.ParentOrderId); return(true); } } return(false); }
public static bool IsBullishExt(this IndexedCandle indexedCandle) { if (indexedCandle.Open <= indexedCandle.Close) { return(true); } return(false); }
public async Task TestIsBearish() { var candles = await ImportCandlesAsync(); var indexedCandle = new IndexedCandle(candles, 1); var result = indexedCandle.IsBearish(); Assert.IsTrue(result); }
private void BuyAsset(IndexedCandle indexedCandle, decimal premium, IDictionary <IEnumerable <Candle>, decimal> assetCashMap, IList <Transaction> transactions) { if (assetCashMap.TryGetValue(indexedCandle.BackingList, out decimal cash)) { var nextCandle = indexedCandle.Next; int quantity = Convert.ToInt32(Math.Floor((cash - premium) / nextCandle.Open)); decimal cashOut = nextCandle.Open * quantity + premium; assetCashMap[indexedCandle.BackingList] -= cashOut; transactions.Add(new Transaction(indexedCandle.BackingList, nextCandle.Index, nextCandle.DateTime, TransactionType.Buy, quantity, cashOut)); OnBought?.Invoke(indexedCandle.BackingList, nextCandle.Index, nextCandle.DateTime, nextCandle.Open, quantity, cashOut, assetCashMap[indexedCandle.BackingList]); } }
private void SellAsset(IndexedCandle indexedCandle, decimal premium, IDictionary <IEnumerable <Candle>, decimal> assetCashMap, IList <Transaction> transactions) { if (assetCashMap.TryGetValue(indexedCandle.BackingList, out _)) { var nextCandle = indexedCandle.Next; var lastTransaction = transactions.LastOrDefault(t => t.Candles.Equals(indexedCandle.BackingList)); decimal cashIn = nextCandle.Open * lastTransaction.Quantity - premium; decimal plRatio = (cashIn - lastTransaction.AbsoluteCashFlow) / lastTransaction.AbsoluteCashFlow; assetCashMap[indexedCandle.BackingList] += cashIn; transactions.Add(new Transaction(indexedCandle.BackingList, nextCandle.Index, nextCandle.DateTime, TransactionType.Sell, lastTransaction.Quantity, cashIn)); OnSold?.Invoke(indexedCandle.BackingList, nextCandle.Index, nextCandle.DateTime, nextCandle.Open, lastTransaction.Quantity, cashIn, assetCashMap[indexedCandle.BackingList], plRatio); } }
public bool SquareOffOpenPosition(Symbol symbol, IEnumerable <Candle> candles, Position position, Order order) { var indexedCandle = new IndexedCandle(candles, candles.Count() - 1); bool macdResult = false; if (position.Quantity < 0) { macdResult = indexedCandle.IsMacdBullishCross(12, 26, 9); } else { macdResult = indexedCandle.IsMacdBearishCross(12, 26, 9); } if (macdResult) { _zeropdhaService._kite.CancelOrder(order.OrderId, Constants.VARIETY_CO, order.ParentOrderId); return(true); } return(false); }
public bool BearishScan(Symbol symbol, IEnumerable <Candle> candles) { //Bearish Strategy var fiveEma = candles.Ema(5)[candles.Count() - 1]; var twentyEma = candles.Ema(20)[candles.Count() - 1]; var twentySma = candles.Sma(20)[candles.Count() - 1]; if (fiveEma.Tick.Value < twentyEma.Tick.Value && fiveEma.Tick.Value < twentySma.Tick.Value) { //EMA Satisfied for (var bar = 1; bar <= _MacdBackscanNoOfCandles; bar++) { var indexedCandle = new IndexedCandle(candles, candles.Count() - bar); var macdResult = indexedCandle.IsMacdBearishCross(12, 26, 9); if (macdResult) { //if macd is crossover in last 5 candles then place order _zeropdhaService.PlaceOrder(new BrokerOrderModel() { JobId = _jobId, SymbolId = symbol.Id, Exchange = symbol.Exchange, TradingSymbol = symbol.TradingSymbol, InstrumentToken = symbol.InstrumentToken, TransactionType = Constants.TRANSACTION_TYPE_SELL, Quantity = _MinQuantity, OrderType = Constants.ORDER_TYPE_MARKET, Product = Constants.PRODUCT_MIS, Variety = Constants.VARIETY_CO, Validity = Constants.VALIDITY_DAY, TriggerPrice = candles.LastOrDefault().High + (candles.LastOrDefault().High *Convert.ToDecimal(_RiskPercentage)) }); return(true); } } } return(false); }
public bool BullishScan(Symbol symbol, IEnumerable <Candle> candles) { var fiveEma = candles.Ema(5)[candles.Count() - 1]; var twentyEma = candles.Ema(20)[candles.Count() - 1]; var twentySma = candles.Sma(20)[candles.Count() - 1]; var macdHist = candles.MacdHist(12, 26, 9)[candles.Count() - 1]; var indexedCandle = new IndexedCandle(candles, candles.Count() - 8); var macdBullOsc = indexedCandle.IsMacdOscBullish(12, 26, 9); var macdHist1 = new MovingAverageConvergenceDivergenceHistogram(candles, 12, 26, 9); var diff = macdHist1.ComputeNeighbourDiff(candles.Count() - 1); var diffPc = macdHist1.ComputeNeighbourPcDiff(candles.Count() - 1); var abcd = macdHist1.ComputeDiff(candles.Count() - 4, candles.Count() - 1); if (fiveEma.Tick.Value > twentyEma.Tick.Value && fiveEma.Tick.Value > twentySma.Tick.Value && (macdHist.Tick.Value >= _MinPositiveMacdHist && macdHist.Tick.Value <= _MaxPositiveMacdHist) && macdBullOsc) { var currentCandle = candles.LastOrDefault(); // //EMA Satisfied //_zeropdhaService.PlaceOrder(new BrokerOrderModel() //{ // JobId = _jobId, // SymbolId = symbol.Id, // Exchange = symbol.Exchange, // TradingSymbol = symbol.TradingSymbol, // InstrumentToken = symbol.InstrumentToken, // TransactionType = Constants.TRANSACTION_TYPE_BUY, // Quantity = _MinQuantity, // OrderType = Constants.ORDER_TYPE_MARKET, // Product = Constants.PRODUCT_MIS, // Variety = Constants.VARIETY_CO, // Validity = Constants.VALIDITY_DAY, // TriggerPrice = Convert.ToInt32(((currentCandle.Close - (currentCandle.Close * Convert.ToDecimal(_RiskPercentage))) / symbol.TickSize)) * symbol.TickSize //}); return(true); } return(false); }
private void BData_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add) { var candle = (BinanceCandle)e.NewItems[0]; var TPC = (candle.Candle.High + candle.Candle.Low + candle.Candle.Close) / 3; var TPVM = TPC * candle.Candle.Volume; var RawData = Starter.core.Candles.Select(y => y.Candle).ToList(); int countIndex = RawData.Count - 1; var indexdcandles = new IndexedCandle(RawData, RawData.Count() - 1); //public static class OhlcvExtension //zone to update with TA - Node (temporary here) try { var rsi = RawData.Rsi(12, 0, countIndex); var bb = RawData.BbWidth(20, 2); var macd = RawData.Macd(7, 10, 12); var chandelier = RawData.Chandlr(14, 22); var ichimoku = RawData.Ichimoku(9, 26, 52); var KAMA = RawData.Kama(21, 12, 32); var Median = RawData.Median(12); var PSAR = RawData.Sar(0.2m, 0.2m); var DM = new DownMomentum(RawData); var bbw = new BollingerBands(RawData, 20, 2); var UM = new UpMomentum(RawData); var Bullish = new Bullish(RawData); var Bearish = new Bearish(RawData); var trendup = new UpTrend(RawData); var trenddown = new DownTrend(RawData); var dmi = new DynamicMomentumIndex(RawData, 14, 30, 12, 70, 30); var minusDI = new MinusDirectionalIndicator(RawData, 12); var truerange = new TrueRange(RawData); var efratio = new EfficiencyRatio(RawData, 12); var obv = new OnBalanceVolume(RawData); var sthrsi = new StochasticsRsiOscillator(RawData, 12); if (rsi.Count() > 0) { //TA candle.Properties.Add("RSI", rsi.Last().Tick); candle.Properties.Add("DOWNMOMENTUM", DM.Compute(12).Last().Tick); candle.Properties.Add("UPMOMENTUM", UM.Compute(12).Last().Tick); candle.Properties.Add("MACD", macd.Last().Tick); candle.Properties.Add("BB", bb.Last().Tick); candle.Properties.Add("bbw", bbw.Compute().Last().Tick); candle.Properties.Add("PSAR", PSAR.Last().Tick); candle.Properties.Add("CHANDELIEREXIT", chandelier.Last().Tick); candle.Properties.Add("ichimoku", ichimoku.Last().Tick); candle.Properties.Add("KAMA", KAMA.Last().Tick); candle.Properties.Add("Median", Median.Last().Tick); candle.Properties.Add("DynamicMomentumIndex", dmi.Compute(12).Last().Tick); candle.Properties.Add("MinusDirectionalIndicator", minusDI.Compute(12).Last().Tick); candle.Properties.Add("TrueRange", truerange.Compute(12).Last().Tick); candle.Properties.Add("EfficiencyRatio", efratio.Compute(12).Last().Tick); candle.Properties.Add("OnBalanceVolume", obv.Compute(12).Last().Tick); candle.Properties.Add("StochasticsRsiOscillator", sthrsi.Compute(12).Last().Tick); //Pattern Periodic candle.Properties.Add("BullishPeriodic_L1", Bullish.Compute(12).Last().Tick); candle.Properties.Add("BearishPeriodic_L1", Bearish.Compute(12).Last().Tick); candle.Properties.Add("UptrendPeriodic_L1", trendup.Compute(12).Last().Tick); candle.Properties.Add("DowntrendPeriodic_L1", trenddown.Compute(12).Last().Tick); Console.WriteLine(candle.ToString()); //candle.Properties.Add("BullishPeriodic_L2", Bullish.Compute(24).Last().Tick); //candle.Properties.Add("BearishPeriodic_L2", Bearish.Compute(24).Last().Tick); //candle.Properties.Add("UptrendPeriodic_L2", trendup.Compute(24).Last().Tick); //candle.Properties.Add("DowntrendPeriodic_L2", trenddown.Compute(24).Last().Tick); //candle.Properties.Add("BullishPeriodic_L3", Bullish.Compute(36).Last().Tick); //candle.Properties.Add("BearishPeriodic_L3", Bearish.Compute(36).Last().Tick); //candle.Properties.Add("UptrendPeriodic_L3", trendup.Compute(36).Last().Tick); //candle.Properties.Add("DowntrendPeriodic_L3", trenddown.Compute(36).Last().Tick); //PatternInject candle.Properties.Add("bearish", indexdcandles.IsBearish()); candle.Properties.Add("isbullish", indexdcandles.IsBullish()); candle.Properties.Add("isaccumdistbearish", indexdcandles.IsAccumDistBearish()); candle.Properties.Add("isaccumdistbullish", indexdcandles.IsAccumDistBullish()); candle.Properties.Add("closepricepercentagechange", indexdcandles.ClosePricePercentageChange()); candle.Properties.Add("closepricechange", indexdcandles.ClosePriceChange()); candle.Properties.Add("isbreakinghistoricalhighestclose", indexdcandles.IsBreakingHistoricalHighestClose()); candle.Properties.Add("isbreakinghistoricalhighesthigh", indexdcandles.IsBreakingHistoricalHighestHigh()); candle.Properties.Add("isbreakinghistoricallowestlow", indexdcandles.IsBreakingHistoricalLowestLow()); candle.Properties.Add("isobvbearish", indexdcandles.IsObvBearish()); candle.Properties.Add("isobvbullish", indexdcandles.IsObvBullish()); candle.UpdateContainer(); } } catch { } var LastBinanceCandle = (BinanceCandle)e.NewItems[0]; Console.WriteLine("Market Node - Sending candle : {0} to suscribers", LastBinanceCandle.UID); Messages Content = new Messages(); Content.Content = candle.Jscontainer; Content.MessageType = TypeOfContent.Binance_Candles; Content.RootType = candle.TypeOfData; Content.TargetObject = "BinanceCandle"; try { Send(Content.ToString()); this.Starter.core.Candles.Clear(); } catch { } } }
public static bool IsSma50BearishCrossSma200(this IndexedCandle ic) => ic.Get <SimpleMovingAverage>(50, 200).ComputeNeighbour(ic.Index).IsTrue( (prev, current, next) => prev.Tick.IsPositive() && current.Tick.IsNegative());
public BrokerOrderModel Scan(Symbol symbol, IEnumerable <Candle> candles, bool isPlaceOrder = true) { BrokerOrderModel brokerOrderModel = null; try { var currentCandle = new IndexedCandle(candles, candles.Count() - 1); var rsi = candles.Rsi(9)[candles.Count() - 1]; var buySellRiseValue = currentCandle.Close * Convert.ToDecimal(_BuySellOnRisePercentage); var riskValue = currentCandle.Close * Convert.ToDecimal(_RiskPercentage); var rewardValue = (currentCandle.Close * Convert.ToDecimal(_RewardPercentage)); if (currentCandle.Prev.IsEmaBullishCross(_EmaShortPeriod, _EmaLongPeriod) && currentCandle.IsBullishExt() && currentCandle.Prev.IsBullishExt() //&& currentCandle.Prev.Close <= currentCandle.Open //&& currentCandle.Prev.GetBody() < currentCandle.GetBody() && rsi.Tick > 50) { brokerOrderModel = new BrokerOrderModel() { JobId = _jobId, SymbolId = symbol.Id, TickSize = symbol.TickSize, Exchange = symbol.Exchange, TradingSymbol = symbol.TradingSymbol, TransactionType = Constants.TRANSACTION_TYPE_BUY, Quantity = Convert.ToInt32(_MinInvestmentPerOrder / currentCandle.Close) > 0 ? Convert.ToInt32(_MinInvestmentPerOrder / currentCandle.Close) : 1, //Price = currentCandle.Close - buySellRiseValue, Price = currentCandle.Close, Product = Constants.PRODUCT_MIS, OrderType = Constants.ORDER_TYPE_LIMIT, Validity = Constants.VALIDITY_DAY, Variety = Constants.VARIETY_BO, //TriggerPrice = (currentCandle.Close - (riskValue + buySellRiseValue)), TriggerPrice = currentCandle.Close - (riskValue), SquareOffValue = rewardValue, StoplossValue = riskValue, TrailingStoploss = (riskValue) < 1 ? 1 : (riskValue) }; if (isPlaceOrder) { _zeropdhaService.PlaceOrder(brokerOrderModel); } //Log Candle ApplicationLogger.LogJob(_jobId, GlobalConfigurations.IndianTime + " Buying Current Candles [" + symbol.TradingSymbol + "]" + JsonConvert.SerializeObject(candles.ElementAt(candles.Count() - 1)) + Environment.NewLine + GlobalConfigurations.IndianTime + " Buying Previous Candles [" + symbol.TradingSymbol + "]" + JsonConvert.SerializeObject(candles.ElementAt(candles.Count() - 2))); } else if (currentCandle.Prev.IsEmaBearishCross(_EmaShortPeriod, _EmaLongPeriod) && currentCandle.IsBearishExt() && currentCandle.Prev.IsBearishExt() //&& currentCandle.Prev.Close >= currentCandle.Open //&& currentCandle.Prev.GetBody() < currentCandle.GetBody() && rsi.Tick < 50) { brokerOrderModel = new BrokerOrderModel() { JobId = _jobId, SymbolId = symbol.Id, TickSize = symbol.TickSize, Exchange = symbol.Exchange, TradingSymbol = symbol.TradingSymbol, TransactionType = Constants.TRANSACTION_TYPE_SELL, Quantity = Convert.ToInt32(_MinInvestmentPerOrder / currentCandle.Close) > 0 ? Convert.ToInt32(_MinInvestmentPerOrder / currentCandle.Close) : 1, //Price = currentCandle.Close + buySellRiseValue, Price = currentCandle.Close, Product = Constants.PRODUCT_MIS, OrderType = Constants.ORDER_TYPE_LIMIT, Validity = Constants.VALIDITY_DAY, Variety = Constants.VARIETY_BO, //TriggerPrice = (currentCandle.Close + (riskValue + buySellRiseValue)), TriggerPrice = (currentCandle.Close + (riskValue)), SquareOffValue = rewardValue, StoplossValue = riskValue, TrailingStoploss = (riskValue) < 1 ? 1 : (riskValue) }; if (isPlaceOrder) { _zeropdhaService.PlaceOrder(brokerOrderModel); } //Log Candle ApplicationLogger.LogJob(_jobId, GlobalConfigurations.IndianTime + " Selling Current Candles [" + symbol.TradingSymbol + "]" + JsonConvert.SerializeObject(candles.ElementAt(candles.Count() - 1)) + Environment.NewLine + GlobalConfigurations.IndianTime + " Selling Previous Candles [" + symbol.TradingSymbol + "]" + JsonConvert.SerializeObject(candles.ElementAt(candles.Count() - 2))); } } catch (Exception ex) { } return(brokerOrderModel); }