public async Task <ICollection <MarketTrade> > GetNextTrades(ExchangeEnum exchange, SymbolCodeEnum symbolCode, Epoch from, long tradeId, int limit = 1)
        {
            using (var context = ContextFactory.CreateDbContext(null))
            {
                var trades = context.ExchangeTrade
                             .Where(t => t.ExchangeId == (int)exchange && t.SymbolId == (int)symbolCode && t.Timestamp >= from.TimestampMilliseconds && t.TradeId > tradeId)
                             .OrderBy(t => t.TradeId)
                             .Take(limit)
                             .Select(t => new
                {
                    Exchange   = exchange,
                    SymbolCode = symbolCode,
                    Timestamp  = t.Timestamp,
                    TradeId    = (long)t.TradeId,
                    Side       = t.OrderSideId.HasValue ? (OrderSideEnum)t.OrderSideId : (OrderSideEnum?)null,
                    Price      = t.Price,
                    Volume     = t.Volume
                });

                var raw = await trades.ToListAsync();

                return(raw.Select(t => new MarketTrade
                {
                    Exchange = t.Exchange,
                    SymbolCode = t.SymbolCode,
                    Epoch = Epoch.FromMilliseconds(t.Timestamp),
                    TradeId = t.TradeId,
                    Side = t.Side,
                    Price = t.Price,
                    Volume = t.Volume
                }).ToList());
            }
        }
        public async Task <ICollection <MarketTradeStat> > GetNextTradeStats(ExchangeEnum exchange, SymbolCodeEnum symbolCode, ExchangeStatsKeyEnum statKey, long tradeStatId, int limit = 1)
        {
            using (var context = ContextFactory.CreateDbContext(null))
            {
                var tradeStats = context.ExchangeTradeStat
                                 .Where(t => t.ExchangeId == (int)exchange && t.SymbolId == (int)symbolCode && t.StatKeyId == (int)statKey && t.TradeStatId > tradeStatId)
                                 .OrderBy(t => t.TradeStatId)
                                 .Take(limit)
                                 .Select(t => new
                {
                    Exchange    = exchange,
                    SymbolCode  = symbolCode,
                    StatKey     = statKey,
                    Timestamp   = t.Timestamp,
                    TradeStatId = (long)t.TradeStatId,
                    Value       = t.Value
                });

                var raw = await tradeStats.ToListAsync();

                return(raw.Select(t => new MarketTradeStat
                {
                    Exchange = t.Exchange,
                    SymbolCode = t.SymbolCode,
                    StatKey = t.StatKey,
                    Epoch = Epoch.FromMilliseconds(t.Timestamp),
                    TradeStatId = t.TradeStatId,
                    Value = t.Value
                }).ToList());
            }
        }
Exemple #3
0
 private async Task <HistorianExchangeSymbolEntity> GetSymbol(ExchangeEnum exchange, SymbolCodeEnum symbolCode)
 {
     using (var context = ContextFactory.CreateDbContext(null))
     {
         return(await context.HistorianExchangeSymbol.FindAsync((int)exchange, (int)symbolCode));
     }
 }
        public async Task <ICollection <MarketAggregate> > GetTradeAggregates(ExchangeEnum exchange, SymbolCodeEnum symbolCode, IntervalKey intervalKey, Epoch from, int dataPoints)
        {
            var intervals = IntervalFactory.GenerateIntervals(intervalKey, from, dataPoints);

            var min = intervals.First();
            var max = intervals.Last();

            var aggs = await GetTradeAggregates(exchange, symbolCode, intervalKey, min.From, max.From, null, null);

            return(aggs.Items);
        }
        public async Task <PagedCollection <MarketTrade> > GetTrades(ExchangeEnum exchange, SymbolCodeEnum symbolCode, Epoch from, Epoch to, int?pageSize, int?pageNumber)
        {
            using (var context = ContextFactory.CreateDbContext(null))
            {
                var query =
                    from
                    t
                    in
                    context.ExchangeTrade
                    where
                    t.ExchangeId == (int)exchange &&
                    t.SymbolId == (int)symbolCode &&
                    t.Timestamp >= @from.TimestampMilliseconds &&
                    t.Timestamp <= to.TimestampMilliseconds
                    select new
                {
                    Exchange   = exchange,
                    SymbolCode = symbolCode,
                    Timestamp  = t.Timestamp,
                    TradeId    = t.TradeId,
                    Side       = t.OrderSideId.HasValue ? (OrderSideEnum)t.OrderSideId : (OrderSideEnum?)null,
                    Price      = t.Price,
                    Volume     = t.Volume
                };

                var totalCount = 0;

                if (pageSize.HasValue)
                {
                    totalCount = await query.CountAsync();

                    query = query.Skip(pageNumber.GetValueOrDefault(0) * pageSize.Value).Take(pageSize.Value);
                }

                var trades = await query.ToListAsync();

                return(new PagedCollection <MarketTrade>()
                {
                    PageNumber = pageNumber.GetValueOrDefault(0),
                    PageSize = pageSize.GetValueOrDefault(0),
                    ItemCount = pageSize.HasValue ? totalCount : trades.Count,
                    Items = trades.Select(t => new MarketTrade
                    {
                        Exchange = t.Exchange,
                        SymbolCode = t.SymbolCode,
                        Epoch = Epoch.FromMilliseconds(t.Timestamp),
                        TradeId = t.TradeId,
                        Side = t.Side,
                        Price = t.Price,
                        Volume = t.Volume
                    }).ToList()
                });
            }
        }
        public async Task <PagedCollection <MarketAggregate> > GetTradeAggregates(ExchangeEnum exchange, SymbolCodeEnum symbolCode, IntervalKey intervalKey, Epoch from, Epoch to, int?pageSize, int?pageNumber)
        {
            var intervals = IntervalFactory.GenerateIntervals(intervalKey, from, to);

            var min = intervals.First();
            var max = intervals.Last();

            using (var context = ContextFactory.CreateDbContext(null))
            {
                var query = context.ExchangeTradeAggregate
                            .Where(a => a.ExchangeId == (int)exchange && a.SymbolId == (int)symbolCode && a.IntervalKey == intervalKey.Key && a.Timestamp >= min.From.TimestampMilliseconds && a.Timestamp <= max.From.TimestampMilliseconds);

                var totalCount = 0;

                if (pageSize.HasValue)
                {
                    totalCount = await query.CountAsync();

                    query = query.Skip(pageNumber.GetValueOrDefault(0) * pageSize.Value).Take(pageSize.Value);
                }

                var aggs = await query.ToListAsync();

                return(new PagedCollection <MarketAggregate>()
                {
                    PageNumber = pageNumber.GetValueOrDefault(0),
                    PageSize = pageSize.GetValueOrDefault(0),
                    ItemCount = pageSize.HasValue ? totalCount : aggs.Count,
                    Items = aggs.Select(a => new MarketAggregate
                    {
                        Exchange = exchange,
                        Symbol = symbolCode,
                        IntervalKey = a.IntervalKey,
                        Epoch = Epoch.FromMilliseconds(a.Timestamp),
                        Open = a.Open,
                        OpenEpoch = Epoch.FromMilliseconds(a.OpenTimestamp),
                        High = a.High,
                        Low = a.Low,
                        Close = a.Close,
                        CloseEpoch = Epoch.FromMilliseconds(a.CloseTimestamp),
                        BuyVolume = a.BuyVolume,
                        SellVolume = a.SellVolume,
                        TotalVolume = a.TotalVolume,
                        BuyCount = a.BuyCount,
                        SellCount = a.SellCount,
                        TotalCount = a.TotalCount
                    }).ToList()
                });
            }
        }
        public async Task <ICollection <BollingerBandsDataPoint> > BollingerBands(ExchangeEnum exchange, SymbolCodeEnum symbolCode, IntervalKey intervalKey, Epoch from, int dataPoints, CandleTypeEnum candleType, int period, MovingAverageTypeEnum maType, double stdDevUp, double stdDevDown)
        {
            var maTypeConverted = maType.ToTaLib();

            var periodOffset = period - 1;

            var fromOffset = IntervalFactory.GetInterval(intervalKey, from, periodOffset * -1);

            var aggValues = await MarketRepository.GetTradeAggregates(exchange, symbolCode, intervalKey, fromOffset.From, periodOffset + dataPoints);

            var values = aggValues.GetValues(candleType);

            int outBegIdx, outNbElement;

            var upperBandValues  = new double[dataPoints];
            var middleBandValues = new double[dataPoints];
            var lowerBandValues  = new double[dataPoints];

            var retCode = Bbands(0, values.Length - 1, values, period, stdDevUp, stdDevDown, maTypeConverted, out outBegIdx, out outNbElement, upperBandValues, middleBandValues, lowerBandValues);

            var validUpperBandValues  = upperBandValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray();
            var validMiddleBandValues = middleBandValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray();
            var validLowerBandValues  = lowerBandValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray();

            var validAggValues = aggValues.Skip(aggValues.Count - dataPoints).Take(dataPoints).ToArray();

            if (retCode == RetCode.Success)
            {
                var dp = new List <BollingerBandsDataPoint>();

                for (var i = 0; i < validAggValues.Length; i++)
                {
                    var agg = validAggValues[i];

                    dp.Add(new BollingerBandsDataPoint
                    {
                        Epoch  = agg.Epoch,
                        Upper  = upperBandValues[i],
                        Middle = middleBandValues[i],
                        Lower  = lowerBandValues[i]
                    });
                }

                return(dp);
            }

            throw new Exception("Unable to calculate Bollinger Bands - " + retCode);
        }
        public async Task <ICollection <StochasticDataPoint> > Stochastic(ExchangeEnum exchange, SymbolCodeEnum symbolCode, IntervalKey intervalKey, Epoch from, int dataPoints, MovingAverageTypeEnum kMaType, int kFastPeriod, int kSlowPeriod, MovingAverageTypeEnum dMaType, int dSlowPeriod)
        {
            var dMaTypeConverted = dMaType.ToTaLib();
            var kMaTypeConverted = kMaType.ToTaLib();

            var periodOffset = kSlowPeriod + 1;

            var fromOffset = IntervalFactory.GetInterval(intervalKey, from, periodOffset * -1);

            var aggValues = await MarketRepository.GetTradeAggregates(exchange, symbolCode, intervalKey, fromOffset.From, periodOffset + dataPoints);

            var highPoints  = aggValues.GetValues(CandleTypeEnum.High);
            var lowPoints   = aggValues.GetValues(CandleTypeEnum.Low);
            var closePoints = aggValues.GetValues(CandleTypeEnum.Close);

            int outBegIdx, outNbElement;

            var kValues = new double[dataPoints];
            var dValues = new double[dataPoints];

            var retCode = Stoch(0, closePoints.Length - 1, highPoints, lowPoints, closePoints, kFastPeriod, kSlowPeriod, kMaTypeConverted, dSlowPeriod, dMaTypeConverted, out outBegIdx, out outNbElement, kValues, dValues);

            var validKValues = kValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray();
            var validDValues = dValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray();

            var validAggValues = aggValues.Skip(aggValues.Count - dataPoints).Take(dataPoints).ToArray();

            if (retCode == RetCode.Success)
            {
                var dp = new List <StochasticDataPoint>();

                for (var i = 0; i < validAggValues.Length; i++)
                {
                    var agg = validAggValues[i];

                    dp.Add(new StochasticDataPoint
                    {
                        Epoch = agg.Epoch,
                        D     = validKValues[i],
                        K     = validDValues[i],
                    });
                }

                return(dp);
            }

            throw new Exception("Unable to calculate Stochastic - " + retCode);
        }
Exemple #9
0
        public async Task <IExchange> Get(ExchangeEnum exchange)
        {
            var match = Exchanges.Where(e => e.Name == exchange).FirstOrDefault();

            if (match == null)
            {
                throw new ArgumentException($"Unable to find exchange '{exchange}'");
            }

            if (!match.Initialized)
            {
                await match.Initialize();
            }

            return(match);
        }
Exemple #10
0
 public async Task <ICollection <HistorianExchangeSymbol> > GetSymbols(ExchangeEnum exchange)
 {
     using (var context = ContextFactory.CreateDbContext(null))
     {
         return(await context.HistorianExchangeSymbol
                .Where(s => s.ExchangeId == (int)exchange)
                .Select(s => new HistorianExchangeSymbol
         {
             Exchange = (ExchangeEnum)s.ExchangeId,
             SymbolCode = (SymbolCodeEnum)s.SymbolId,
             TradeFilter = s.TradeFilter,
             LastTradeId = s.LastTradeId,
             LastTradeStatId = s.LastTradeStatId
         })
                .ToListAsync());
     }
 }
        public async Task <ICollection <MacdDataPoint> > Macd(ExchangeEnum exchange, SymbolCodeEnum symbolCode, IntervalKey intervalKey, Epoch from, int dataPoints, CandleTypeEnum candleType, int fastEmaPeriod, int slowEmaPeriod, int signalPeriod)
        {
            var periodOffset = (slowEmaPeriod + signalPeriod) - 2;

            var fromOffset = IntervalFactory.GetInterval(intervalKey, from, periodOffset * -1);

            var aggValues = await MarketRepository.GetTradeAggregates(exchange, symbolCode, intervalKey, fromOffset.From, periodOffset + dataPoints);

            var values = aggValues.GetValues(candleType);

            int outBegIdx, outNbElement;

            var macdValues      = new double[dataPoints];
            var signalValues    = new double[dataPoints];
            var histogramValues = new double[dataPoints];

            var retCode = TicTacTec.TA.Library.Core.Macd(0, values.Length - 1, values, fastEmaPeriod, slowEmaPeriod, signalPeriod, out outBegIdx, out outNbElement, macdValues, signalValues, histogramValues);

            var validMacdValues      = macdValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray();
            var validSignalValues    = signalValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray();
            var validHistogramValues = histogramValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray();
            var validAggValues       = aggValues.Skip(aggValues.Count - dataPoints).Take(dataPoints).ToArray();

            if (retCode == RetCode.Success)
            {
                var dp = new List <MacdDataPoint>();

                for (var i = 0; i < validAggValues.Length; i++)
                {
                    var agg = validAggValues[i];

                    dp.Add(new MacdDataPoint
                    {
                        Epoch     = agg.Epoch,
                        Macd      = validMacdValues[i],
                        Signal    = validSignalValues[i],
                        Histogram = validHistogramValues[i]
                    });
                }

                return(dp);
            }

            throw new Exception("Unable to calculate MACD - " + retCode);
        }
Exemple #12
0
        public async Task AddSymbol(ExchangeEnum exchange, SymbolCodeEnum symbolCode)
        {
            using (var context = ContextFactory.CreateDbContext(null))
            {
                var entity = new ExchangeSymbolEntity
                {
                    ExchangeId = (int)exchange,
                    SymbolId   = (int)symbolCode
                };

                if (await context.ExchangeSymbol.FindAsync(entity.ExchangeId, entity.SymbolId) == null)
                {
                    await context.ExchangeSymbol.AddAsync(entity);

                    await context.SaveChangesAsync();
                }
            }
        }
Exemple #13
0
        public async Task SetLastTradeStatId(IStorageTransaction transaction, ExchangeEnum exchange, SymbolCodeEnum symbolCode, long lastTradeStatId)
        {
            var context = (HistorianDbContext)transaction.GetContext();

            var history = await context.HistorianExchangeSymbol.FindAsync((int)exchange, (int)symbolCode);

            if (history == null)
            {
                history = new HistorianExchangeSymbolEntity
                {
                    ExchangeId = (int)exchange,
                    SymbolId   = (int)symbolCode
                };

                await context.HistorianExchangeSymbol.AddAsync(history);
            }

            history.LastTradeStatId = lastTradeStatId;
        }
        public async Task <ICollection <MovingAverageDataPoint> > Ema(ExchangeEnum exchange, SymbolCodeEnum symbolCode, IntervalKey intervalKey, Epoch from, int dataPoints, CandleTypeEnum candleType, int period)
        {
            var periodOffset = period - 1;

            var fromOffset = IntervalFactory.GetInterval(intervalKey, from, periodOffset * -1);

            var aggValues = await MarketRepository.GetTradeAggregates(exchange, symbolCode, intervalKey, fromOffset.From, periodOffset + dataPoints);

            var values = aggValues.GetValues(candleType);

            int outBegIdx, outNbElement;

            var smaValues = new double[dataPoints];

            var retCode = TicTacTec.TA.Library.Core.Ema(0, values.Length - 1, values, period, out outBegIdx, out outNbElement, smaValues);

            var validSmaValues = smaValues.Skip(outNbElement - dataPoints).Take(dataPoints).ToArray();

            var validAggValues = aggValues.Skip(aggValues.Count - dataPoints).Take(dataPoints).ToArray();

            if (retCode == RetCode.Success)
            {
                var dp = new List <MovingAverageDataPoint>();

                for (var i = 0; i < validAggValues.Length; i++)
                {
                    var agg = validAggValues[i];

                    dp.Add(new MovingAverageDataPoint
                    {
                        Epoch = agg.Epoch,
                        Value = validSmaValues[i]
                    });
                }

                return(dp);
            }

            throw new Exception("Unable to calculate EMA - " + retCode);
        }
Exemple #15
0
        public async Task <HistorianTradeCatchup> GetNextTradeCatchup(ExchangeEnum exchange, SymbolCodeEnum symbolCode)
        {
            using (var context = ContextFactory.CreateDbContext(null))
            {
                var next = await context.HistorianTradeCatchup
                           .Where(c => c.ExchangeId == (int)exchange && c.SymbolId == (int)symbolCode)
                           .OrderByDescending(c => c.TimestampTo)
                           .OrderBy(c => c.Priority)
                           .FirstOrDefaultAsync();

                return(next != null ?
                       new HistorianTradeCatchup
                {
                    Exchange = (ExchangeEnum)next.ExchangeId,
                    SymbolCode = (SymbolCodeEnum)next.SymbolId,
                    TradeFilter = next.TradeFilter,
                    EpochTo = Epoch.FromMilliseconds(next.TimestampTo),
                    CurrentTradeFilter = next.CurrentTradeFilter,
                    Priority = next.Priority
                } : null);
            }
        }
Exemple #16
0
        public async Task SetTradeFilter(IStorageTransaction transaction, ExchangeEnum exchange, SymbolCodeEnum symbolCode, string filter)
        {
            var context = (HistorianDbContext)transaction.GetContext();

            var entity = await context.HistorianExchangeSymbol.FindAsync((int)exchange, (int)symbolCode);

            if (entity == null)
            {
                entity = new HistorianExchangeSymbolEntity
                {
                    ExchangeId  = (int)exchange,
                    SymbolId    = (int)symbolCode,
                    TradeFilter = filter
                };

                await context.HistorianExchangeSymbol.AddAsync(entity);
            }
            else
            {
                entity.TradeFilter = filter;

                context.Update(entity);
            }
        }
        public static IServiceProvider Init(ExchangeEnum exchange, string strategyName, bool isBacktest = false)
        {
            var configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
                                .AddJsonFile("Configs/config.json", optional: false)
                                .AddEnvironmentVariables()
                                .Build();

            var serviceCollection = new ServiceCollection();

            serviceCollection.AddOptions();

            switch (exchange)
            {
            case ExchangeEnum.Kraken:
                serviceCollection.Configure <KrakenOptions>(configuration.GetSection("Kraken"));
                serviceCollection.AddTransient <IExchangeProvider, KrakenExchangeProvider>();
                break;

            case ExchangeEnum.Poloniex:
                serviceCollection.Configure <PoloniexOptions>(configuration.GetSection("Poloniex"));
                serviceCollection.AddTransient <IExchangeProvider, PoloniexExchangeProvider>();
                break;

            case ExchangeEnum.Bitfinex:
                serviceCollection.Configure <BitfinexOptions>(configuration.GetSection("Bitfinex"));
                serviceCollection.AddTransient <IExchangeProvider, BitfinexExchangeProvider>();
                break;

            case ExchangeEnum.Binance:
                serviceCollection.Configure <BinanceOptions>(configuration.GetSection("Binance"));
                serviceCollection.AddTransient <IExchangeProvider, BinanceExchangeProvider>();
                break;
            }

            serviceCollection.Configure <EmaStrategyOptions>(configuration.GetSection("EmaStrategy"));
            serviceCollection.Configure <MfiStrategyOptions>(configuration.GetSection("MfiStrategy"));
            serviceCollection.Configure <MacdStrategyOptions>(configuration.GetSection("MacdStrategy"));
            serviceCollection.Configure <CryptoTradingOptions>(configuration.GetSection("CryptoTrading"));
            serviceCollection.Configure <EmailOptions>(configuration.GetSection("Email"));
            serviceCollection.AddMemoryCache();
            serviceCollection.AddDbContext <TradingDbContext>(
                // ReSharper disable once AssignNullToNotNullAttribute
                opt => opt.UseMySql(configuration.GetSection("Database")?.Get <DatabaseOptions>()?.ConnectionString)
                );

            serviceCollection.AddSingleton <IUserBalanceService, UserBalanceService>();
            serviceCollection.AddTransient <ITradingDbContext, TradingDbContext>();
            serviceCollection.AddTransient <ICandleRepository, CandleDbRepository>();
            serviceCollection.AddTransient <IImportRepository, ImportRepository>();

            if (isBacktest)
            {
                serviceCollection.AddTransient <ITraderService, BacktestTraderService>();
            }
            else
            {
                serviceCollection.AddTransient <ITraderService, RealTimeTraderService>();
            }

            serviceCollection.AddTransient <ICandleService, CandleDbService>();
            serviceCollection.AddTransient <IEmailService, EmailService>();
            serviceCollection.AddTransient <IIndicatorFactory, IndicatorFactory>();
            serviceCollection.AddTransient <IIndicator, EmaIndicator>();
            serviceCollection.AddTransient <IIndicator, TsiIndicator>();
            serviceCollection.AddTransient <IIndicator, RsiIndicator>();
            serviceCollection.AddTransient <IIndicator, TdiIndicator>();
            serviceCollection.AddTransient <IIndicator, CandleSticksIndicator>();
            serviceCollection.AddTransient <IIndicator, IchimokuCloudIndicator>();

            RegisterStrategy(serviceCollection, strategyName);

            return(serviceCollection.BuildServiceProvider());
        }
Exemple #18
0
 public static IDisposable BeginExchangeScope(this ILogger logger, ExchangeEnum exchange)
 {
     return(logger.BeginScope(new { Exchange = exchange }));
 }
        public async Task SaveTradeStatAggregates(IStorageTransaction transaction, ExchangeEnum exchange, SymbolCodeEnum symbolCode, ICollection <MarketTradeStat> tradeStats)
        {
            var min = tradeStats.Min(t => t.Epoch);
            var max = tradeStats.Max(t => t.Epoch);

            var expanded = new List <TradeStatCartesian>();

            foreach (var group in IntervalFactory.ListGroups())
            {
                foreach (var ik in IntervalFactory.ListIntervalKeys(group.IntervalGroup))
                {
                    foreach (var tradeStat in tradeStats)
                    {
                        var period = IntervalFactory.GenerateIntervals(ik, tradeStat.Epoch, tradeStat.Epoch).FirstOrDefault();

                        expanded.Add(new TradeStatCartesian
                        {
                            IntervalKey   = period.IntervalKey,
                            IntervalEpoch = period.From,
                            Exchange      = tradeStat.Exchange,
                            SymbolCode    = symbolCode,
                            StatKey       = tradeStat.StatKey,
                            Epoch         = tradeStat.Epoch,
                            Value         = tradeStat.Value
                        });
                    }
                }
            }

            using (var context = ContextFactory.CreateDbContext(null))
            {
                using (var cmd = context.Database.GetDbConnection().CreateCommand())
                {
                    var sql = @"insert into `exchange_trade_aggregate`
                    (`exchange_id`,
                    `symbol_id`,
                    `interval_key`,
                    `timestamp`,
                    `open`,
                    `open_timestamp`,
                    `high`,
                    `low`,
                    `close`,
                    `close_timestamp`,
                    `total_count`) values ";

                    sql += string.Join(",\r\n", expanded.Select(t => $"(" +
                                                                $"{(int)t.Exchange}," +
                                                                $"{(int)t.SymbolCode}," +
                                                                $"'{t.IntervalKey.Key}'," +
                                                                $"{t.IntervalEpoch.TimestampMilliseconds}," +
                                                                $"{t.Value}," +
                                                                $"{t.Epoch.TimestampMilliseconds}," +
                                                                $"{t.Value}," +
                                                                $"{t.Value}," +
                                                                $"{t.Value}," +
                                                                $"{t.Epoch.TimestampMilliseconds}," +
                                                                $"1)"));

                    sql += @"
                    on duplicate key update
	                    `open` = case when values(`open_timestamp`) < `open_timestamp` then values(`open`) else `open` end,
	                    `open_timestamp` = case when values(`open_timestamp`) < `open_timestamp` then values(`open_timestamp`) else `open_timestamp` end,
                        `high` = case when values(`high`) > `high` then values(`high`) else `high` end,
                        `low` = case when values(`low`) < `low` then values(`low`) else `low` end,
                        `close` = case when values(`close_timestamp`) > `close_timestamp` then values(`close`) else `close` end,
	                    `close_timestamp` = case when values(`close_timestamp`) > `close_timestamp` then values(`close_timestamp`) else `close_timestamp` end,
	                    `total_count` = `total_count` + values(`total_count`)"    ;

                    cmd.CommandText = sql;

                    await cmd.Connection.OpenAsync();

                    await cmd.ExecuteNonQueryAsync();

                    cmd.Connection.Close();
                }
            }
        }
        public async Task <MarketTick> GetTick(ExchangeEnum exchange, SymbolCodeEnum symbolCode, Epoch at)
        {
            using (var context = ContextFactory.CreateDbContext(null))
            {
                var minAt = at.AddSeconds((int)TimeSpan.FromDays(-1).TotalSeconds);

                var buyTradeQuery =
                    from
                    t
                    in
                    context.ExchangeTrade
                    where
                    t.ExchangeId == (int)exchange &&
                    t.SymbolId == (int)symbolCode &&
                    t.Timestamp >= minAt.TimestampMilliseconds &&
                    t.Timestamp <= at.TimestampMilliseconds &&
                    t.OrderSideId == (int)OrderSideEnum.Buy
                    orderby
                    t.ExchangeId,
                    t.SymbolId,
                    t.Timestamp descending
                select
                    t;

                var buyTrade = await buyTradeQuery.FirstOrDefaultAsync();

                var sellTradeQuery =
                    from
                    t
                    in
                    context.ExchangeTrade
                    where
                    t.ExchangeId == (int)exchange &&
                    t.SymbolId == (int)symbolCode &&
                    t.Timestamp >= minAt.TimestampMilliseconds &&
                    t.Timestamp <= at.TimestampMilliseconds &&
                    t.OrderSideId == (int)OrderSideEnum.Sell
                    orderby
                    t.ExchangeId,
                    t.SymbolId,
                    t.Timestamp descending
                select
                    t;

                var sellTrade = await sellTradeQuery.FirstOrDefaultAsync();

                ExchangeTradeEntity lastTrade = null;

                if (buyTrade != null && sellTrade != null)
                {
                    lastTrade = buyTrade.Timestamp <= sellTrade.Timestamp ? buyTrade : sellTrade;
                }
                else
                {
                    var lastTradeQuery =
                        from
                        t
                        in
                        context.ExchangeTrade
                        where
                        t.ExchangeId == (int)exchange &&
                        t.SymbolId == (int)symbolCode &&
                        t.Timestamp >= minAt.TimestampMilliseconds &&
                        t.Timestamp <= at.TimestampMilliseconds
                        orderby
                        t.ExchangeId,
                        t.SymbolId,
                        t.Timestamp descending
                    select
                        t;

                    lastTrade = await lastTradeQuery.FirstOrDefaultAsync();
                }

                if (lastTrade == null)
                {
                    return(null);
                }

                return(new MarketTick
                {
                    Exchange = exchange,
                    SymbolCode = symbolCode,
                    Epoch = at,
                    BuyPrice = buyTrade != null ? buyTrade.Price : lastTrade.Price,
                    SellPrice = sellTrade != null ? sellTrade.Price : lastTrade.Price,
                    LastPrice = lastTrade.Price
                });
            }
        }
Exemple #21
0
        public async Task <TradeResult> ReceiveTradesHttp(IStorageTransaction transaction, ILogger logger, ExchangeEnum exchange, ISymbol symbol, IExchangeHttpClient httpClient, int limit, string lastTradeFilter)
        {
            logger.LogInformation($"Requesting trades from filter '{lastTradeFilter}'");

            var response = await httpClient.GetTrades(symbol, limit, lastTradeFilter);

            var tradeResult = response.Data;

            if (response.StatusCode != WrappedResponseStatusCode.Ok)
            {
                var errorCode = !string.IsNullOrEmpty(response.ErrorCode) ? $"Error Code: {response.ErrorCode} Message: " : "";

                logger.LogWarning($"Unable to get trades: {errorCode}{response.ErrorMessage}");

                return(null);
            }

            if (tradeResult.Trades.Count > 0)
            {
                await AddTrades(transaction, logger, tradeResult);
            }

            return(tradeResult);
        }
        public async Task SaveTradeAggregates(IStorageTransaction transaction, ExchangeEnum exchange, SymbolCodeEnum symbolCode, ICollection <MarketTrade> trades)
        {
            var min = trades.Min(t => t.Epoch);
            var max = trades.Max(t => t.Epoch);

            var expanded = new List <TradeCartesian>();

            foreach (var group in IntervalFactory.ListGroups())
            {
                foreach (var ik in IntervalFactory.ListIntervalKeys(group.IntervalGroup))
                {
                    foreach (var trade in trades)
                    {
                        var period = IntervalFactory.GenerateIntervals(ik, trade.Epoch, trade.Epoch).FirstOrDefault();

                        expanded.Add(new TradeCartesian
                        {
                            IntervalKey   = period.IntervalKey,
                            IntervalEpoch = period.From,
                            Exchange      = trade.Exchange,
                            SymbolCode    = trade.SymbolCode,
                            Epoch         = trade.Epoch,
                            TradeId       = trade.TradeId,
                            Price         = trade.Price,
                            Volume        = trade.Volume,
                            Side          = trade.Side
                        });
                    }
                }
            }

            var context = (HistorianDbContext)transaction.GetContext();

            using (var cmd = context.Database.GetDbConnection().CreateCommand())
            {
                cmd.Transaction = context.Database.CurrentTransaction.GetDbTransaction();

                var sql = @"insert into `exchange_trade_aggregate`
                (`exchange_id`,
                `symbol_id`,
                `interval_key`,
                `timestamp`,
                `open`,
                `open_timestamp`,
                `high`,
                `low`,
                `close`,
                `close_timestamp`,
                `buy_volume`,
                `sell_volume`,
                `total_volume`,
                `buy_count`,
                `sell_count`,
                `total_count`) values ";

                sql += string.Join(",\r\n", expanded.Select(t => $"(" +
                                                            $"{(int)t.Exchange}," +
                                                            $"{(int)t.SymbolCode}," +
                                                            $"'{t.IntervalKey.Key}'," +
                                                            $"{t.IntervalEpoch.TimestampMilliseconds}," +
                                                            $"{t.Price}," +
                                                            $"{t.Epoch.TimestampMilliseconds}," +
                                                            $"{t.Price}," +
                                                            $"{t.Price}," +
                                                            $"{t.Price}," +
                                                            $"{t.Epoch.TimestampMilliseconds}," +
                                                            $"{(t.Side == OrderSideEnum.Buy ? t.Volume.ToString() : "NULL")}," +
                                                            $"{(t.Side == OrderSideEnum.Sell ? t.Volume.ToString() : "NULL")}," +
                                                            $"{t.Volume}," +
                                                            $"{(t.Side == OrderSideEnum.Buy ? "1" : "NULL")}," +
                                                            $"{(t.Side == OrderSideEnum.Sell ? "1" : "NULL")}," +
                                                            $"1)"));

                sql += @"
                on duplicate key update
	                `open` = case when values(`open_timestamp`) < `open_timestamp` then values(`open`) else `open` end,
	                `open_timestamp` = case when values(`open_timestamp`) < `open_timestamp` then values(`open_timestamp`) else `open_timestamp` end,
                    `high` = case when values(`high`) > `high` then values(`high`) else `high` end,
                    `low` = case when values(`low`) < `low` then values(`low`) else `low` end,
                    `close` = case when values(`close_timestamp`) > `close_timestamp` then values(`close`) else `close` end,
	                `close_timestamp` = case when values(`close_timestamp`) > `close_timestamp` then values(`close_timestamp`) else `close_timestamp` end,
	                `buy_volume` = case when values(`buy_volume`) is not null then ifnull(`buy_volume`, 0) + values(`buy_volume`) else `buy_volume` end,
                    `sell_volume` = case when values(`sell_volume`) is not null then ifnull(`sell_volume`, 0) + values(`sell_volume`) else `sell_volume` end,
                    `total_volume` = `total_volume` + values(`total_volume`),
                    `buy_count` = case when values(`buy_count`) is not null then ifnull(`buy_count`, 0) + values(`buy_count`) else `buy_count` end,
                    `sell_count` = case when values(`sell_count`) is not null then ifnull(`sell_count`, 0) + values(`sell_count`) else `sell_count` end,
                    `total_count` = `total_count` + values(`total_count`)";

                cmd.CommandText = sql;

                await cmd.ExecuteNonQueryAsync();
            }
        }
Exemple #23
0
        public async Task <string> GetTradeFilter(ExchangeEnum exchange, SymbolCodeEnum symbolCode)
        {
            var history = await GetSymbol(exchange, symbolCode);

            return(history != null ? history.TradeFilter : null);
        }
Exemple #24
0
        public async Task <long?> GetLastTradeStatId(ExchangeEnum exchange, SymbolCodeEnum symbolCode)
        {
            var history = await GetSymbol(exchange, symbolCode);

            return(history != null ? history.LastTradeStatId : null);
        }