コード例 #1
0
        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);
            }
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
 public static bool IsBullishExt(this IndexedCandle indexedCandle)
 {
     if (indexedCandle.Open <= indexedCandle.Close)
     {
         return(true);
     }
     return(false);
 }
コード例 #6
0
ファイル: IndexedCandleTest.cs プロジェクト: lnaie/Trady
        public async Task TestIsBearish()
        {
            var candles = await ImportCandlesAsync();

            var indexedCandle = new IndexedCandle(candles, 1);
            var result        = indexedCandle.IsBearish();

            Assert.IsTrue(result);
        }
コード例 #7
0
        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]);
            }
        }
コード例 #8
0
        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);
            }
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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);
        }
コード例 #12
0
        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
                {
                }
            }
        }
コード例 #13
0
 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());
コード例 #14
0
        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);
        }