Esempio n. 1
0
 public void DoTick(string label = "Unlabelled")
 {
     TickTime = Time.time;
     Ticks.Add(new Tick {
         Context = Context, Label = label, Time = TickTime
     });
 }
Esempio n. 2
0
        /// <summary>
        /// Adds the specified <see cref="BaseData"/> instance to the appropriate <see cref="DataDictionary{T}"/>
        /// </summary>
        private static void PopulateDataDictionaries(BaseData baseData, Ticks ticks, TradeBars tradeBars, QuoteBars quoteBars, OptionChains optionChains, FuturesChains futuresChains)
        {
            var symbol = baseData.Symbol;

            // populate data dictionaries
            switch (baseData.DataType)
            {
            case MarketDataType.Tick:
                ticks.Add(symbol, (Tick)baseData);
                break;

            case MarketDataType.TradeBar:
                tradeBars[symbol] = (TradeBar)baseData;
                break;

            case MarketDataType.QuoteBar:
                quoteBars[symbol] = (QuoteBar)baseData;
                break;

            case MarketDataType.OptionChain:
                optionChains[symbol] = (OptionChain)baseData;
                break;

            case MarketDataType.FuturesChain:
                futuresChains[symbol] = (FuturesChain)baseData;
                break;
            }
        }
Esempio n. 3
0
        private void Cast(Actor caster, Actor target)
        {
            //Deal damage
            var damagePerTick = new Damage(_tickDamage, DamageType.Magical, DamageFlags.Ability);
            var damage        = new SourcedDamage(caster, damagePerTick);
            var damageable    = target.GetModule <IDamageable>();


            void InternalTick()
            {
                damageable.TakeDamage(damage);
            }

            var tickWrapper = new TickAction
            {
                Callback     = InternalTick,
                TickCount    = _tickCount,
                TickInterval = _tickInterval
            };

            if (target.TryGetModule <IKillable>(out var killable))
            {
                killable.Died += RemoveTick;
            }

            void RemoveTick(object sender, DeathEventArgs args)
            {
                killable.Died -= RemoveTick;
                Ticks.Remove(tickWrapper);
            }

            Ticks.Add(tickWrapper);
            ApplyFX(target.transform, _tickInterval * _tickCount);
        }
Esempio n. 4
0
        private async Task <bool> ExecuteLoadTickDataAsync(object parameter)
        {
            IsBusy     = true;
            StatusText = "Loading...";

            if (parameter != null)
            {
                _lastLoadedDuration = (DurationEnum)Enum.Parse(typeof(DurationEnum), parameter.ToString());
            }

            Duration = _lastLoadedDuration.ToString();
            var ticks = await _xtbWrapper.LoadData(Name, _lastLoadedDuration);

            Ticks.Clear();
            foreach (var tick in ticks)
            {
                Ticks.Add(tick);
            }

            UpdatePlot(_lastLoadedDuration);

            StatusText = "Ready";
            IsBusy     = false;
            IsLoaded   = true;

            return(true);
        }
Esempio n. 5
0
        public void Recalculate(double min, double max, double fixedSpacingMajor, double fixedSpacingMinor)
        {
            Ticks.Clear();

            double firstMajorTickPosition = min - (min % fixedSpacingMajor);

            if (min > 0)
            {
                firstMajorTickPosition += fixedSpacingMajor;
            }

            for (double i = firstMajorTickPosition; i <= max; i += fixedSpacingMajor)
            {
                Ticks.Add(new Tick(i, Math.Round(i, 8).ToString(), true));
            }
            double[] majorTickPositions = Ticks.Select(x => x.Position).ToArray();


            double firstMinorTickPosition = min - (min % fixedSpacingMinor);

            if (min > 0)
            {
                firstMinorTickPosition += fixedSpacingMinor;
            }

            for (double i = firstMinorTickPosition; i <= max; i += fixedSpacingMinor)
            {
                if (!majorTickPositions.Contains(i))
                {
                    Ticks.Add(new Tick(i));
                }
            }
        }
        /// <summary>
        /// Poll for new tick to refresh conversion rate of non-USD denomination
        /// </summary>
        /// <param name="symbol"></param>
        public void PollTick(Symbol symbol)
        {
            int delay    = 36000000;
            var token    = _canceller.Token;
            var listener = Task.Factory.StartNew(() =>
            {
                OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Information, -1, $"GDAXBrokerage.PollLatestTick: started polling for ticks: {symbol.Value.ToString()}"));
                while (true)
                {
                    var rate = GetConversionRate(symbol.Value.Replace("USD", ""));

                    lock (TickLocker)
                    {
                        var latest = new Tick
                        {
                            Value  = rate,
                            Time   = DateTime.UtcNow,
                            Symbol = symbol
                        };
                        Ticks.Add(latest);
                    }

                    Thread.Sleep(delay);
                    if (token.IsCancellationRequested)
                    {
                        break;
                    }
                }
                OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Information, -1, $"PollLatestTick: stopped polling for ticks: {symbol.Value.ToString()}"));
            }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="symbol"></param>
        /// <param name="entries"></param>
        private void EmitTradeTick(Symbol symbol, string[] entries)
        {
            try
            {
                var time  = Time.UnixTimeStampToDateTime(double.Parse(entries[0], NumberStyles.Float, CultureInfo.InvariantCulture));
                var price = decimal.Parse(entries[1], NumberStyles.Float, CultureInfo.InvariantCulture);
                var amout = decimal.Parse(entries[2], NumberStyles.Float, CultureInfo.InvariantCulture);

                lock (TickLocker)
                {
                    Ticks.Add(new Tick
                    {
                        Value    = price,
                        Time     = time,
                        Symbol   = symbol,
                        TickType = TickType.Trade,
                        Quantity = Math.Abs(amout)
                    });
                }
            }
            catch (Exception e)
            {
                Log.Error(e);
                throw;
            }
        }
        // [[1, 250, 'Unscheduled'], [2, 54, 'Sprint 1'], [3, 20, 'Sprint Banana'], [4, 0, 'Sprint Cross Reference'], [5, 8, 'Sprint Sammy']]
        private List <object> CreateTaskHoursPerSprintJsonList(Product product, int currentSprintId)
        {
            List <object> taskHoursPerSprintJsonList = new List <object>();

            ScrumTimeEntities scrumTimeEntities   = new ScrumTimeEntities();
            TaskService       taskService         = new TaskService(scrumTimeEntities);
            decimal           unassignedTaskHours = taskService.GetUnassignedTaskHours(product.ProductId);

            CheckSetYAxisMax(unassignedTaskHours);
            List <object> unassignedHoursList = new List <object>();

            unassignedHoursList.Add(1);
            unassignedHoursList.Add(unassignedTaskHours);
            unassignedHoursList.Add("Unassigned");
            taskHoursPerSprintJsonList.Add(unassignedHoursList);
            Ticks.Add(" ");

            SprintService sprintService     = new SprintService(scrumTimeEntities);
            List <Sprint> mostRecentSprints = sprintService.GetMostRecentSprints(product.ProductId, currentSprintId, 4);
            int           index             = 2;

            foreach (Sprint recentSprint in mostRecentSprints)
            {
                List <object> sprintHoursList = new List <object>();
                sprintHoursList.Add(index);
                sprintHoursList.Add(CalculateHoursForSprint(recentSprint));
                sprintHoursList.Add(recentSprint.Name);
                taskHoursPerSprintJsonList.Add(sprintHoursList);
                Ticks.Add(" ");
                index++;
            }

            return(taskHoursPerSprintJsonList);
        }
Esempio n. 9
0
        /// <summary>
        /// Poll for new tick to refresh conversion rate of non-USD denomination
        /// </summary>
        /// <param name="symbol"></param>
        /// <param name="client"></param>
        public void PollTick(Symbol symbol)
        {
            int delay    = 36000000;
            var token    = _canceller.Token;
            var listener = Task.Factory.StartNew(() =>
            {
                Log.Trace("PollLatestTick: " + "Started polling for ticks: " + symbol.Value.ToString());
                while (true)
                {
                    var rate = GetConversionRate(symbol.Value.Replace("USD", ""));

                    lock (_tickLocker)
                    {
                        var latest = new Tick
                        {
                            Value  = rate,
                            Time   = DateTime.UtcNow,
                            Symbol = symbol
                        };
                        Ticks.Add(latest);
                    }

                    Thread.Sleep(delay);
                    if (token.IsCancellationRequested)
                    {
                        break;
                    }
                }
                Log.Trace("PollLatestTick: " + "Stopped polling for ticks: " + symbol.Value.ToString());
            }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
        }
Esempio n. 10
0
        public void DateTimeConversion()
        {
            UT_INIT();

            Log.SetVerbosity(new ConsoleLogger(), Verbosity.Verbose, "/");
            Log.MapThreadName("UnitTest");
            Log.SetDomain("TickWatch", Scope.Method);

            Log.Info("DateTime.MinValue(): " + (DateTime.MinValue.ToString()));
            Log.Info("DateTime.MaxValue(): " + (DateTime.MaxValue.ToString()));

            Ticks ticksNow = new Ticks();

            // roundtrip 1
            long millisEpochNow = ticksNow.InEpochMillis();

            ticksNow.SetFromEpochMillis(millisEpochNow);
            long ticksNowFromEpoch = ticksNow.Raw();

            UT_TRUE(Math.Abs(ticksNow.Raw() - ticksNowFromEpoch) < 50000);

            // roundtrip 2
            long millis5_1_70_3_51 = 0
                                     + (4L * 24L * 60L * 60L * 1000L)
                                     + (3L * 60L * 60L * 1000L)
                                     + (51L * 60L * 1000L);


            long millis5_1_71_3_51 = millis5_1_70_3_51
                                     + (365L * 24L * 60L * 60L * 1000L);

            Ticks ticks5_1_70_3_51 = new Ticks(); ticks5_1_70_3_51.SetFromEpochMillis(millis5_1_70_3_51);
            Ticks ticks5_1_71_3_51 = new Ticks(); ticks5_1_71_3_51.SetFromEpochMillis(millis5_1_71_3_51);

            UT_TRUE(ticks5_1_70_3_51.Raw() < ticks5_1_71_3_51.Raw());


            long millis5_1_70_3_51_back = ticks5_1_70_3_51.InEpochMillis();
            long millis5_1_71_3_51_back = ticks5_1_71_3_51.InEpochMillis();


            UT_TRUE(millis5_1_70_3_51_back == millis5_1_70_3_51);
            UT_TRUE(millis5_1_71_3_51_back == millis5_1_71_3_51);

            // add 1 day, 2h, 3min and 4sec  days:

            Ticks tomorrow = new Ticks(ticksNow);
            Ticks span     = new Ticks();

            span.FromMillis((long)(new TimeSpan(1, 2, 3, 4)).TotalMilliseconds);
            tomorrow.Add(span);

            Log.Info("Today: is:        " + (DateTime.Now.ToString()));
            Log.Info("Today: is:        " + (ticksNow.InDotNetDateTime().ToString()));
            Log.Info("Today: is:        " + ((new Ticks(ticksNowFromEpoch)).InDotNetDateTime().ToString()));
            Log.Info("+1d, 2h,3m,4s:    " + (tomorrow.InDotNetDateTime().ToString()));
            Log.Info("5.1.70 3:51:00:   " + (ticks5_1_70_3_51.InDotNetDateTime().ToString()));
            Log.Info("5.1.71 3:51:00:   " + (ticks5_1_71_3_51.InDotNetDateTime().ToString()));
        }
Esempio n. 11
0
    internal HistoricalTicks(ResponseReader r)
    {
        RequestId = r.ReadInt();
        int n = r.ReadInt();

        for (int i = 0; i < n; i++)
        {
            Ticks.Add(new HistoricalTick(r));
        }
        Done = r.ReadBool();
    }
        private void HandleBadProductId()
        {
            List <object> taskHoursPerSprintJsonList = new List <object>();

            taskHoursPerSprintJsonList.Add(0);
            taskHoursPerSprintJsonList.Add(0);
            taskHoursPerSprintJsonList.Add("None");
            Data.Add(taskHoursPerSprintJsonList);
            Ticks.Add(" ");
            YAxisMax = 10;
        }
Esempio n. 13
0
        public HistoricalTicks(ResponseComposer c)
        {
            RequestId = c.ReadInt();
            var n = c.ReadInt();

            for (int i = 0; i < n; i++)
            {
                Ticks.Add(new HistoricalTick(c));
            }
            Done = c.ReadBool();
        }
Esempio n. 14
0
        public void InitializeTicks()
        {
            logger.Trace("InitializeTicks()...");

            for (int j = 0; j < 10; j = j + 1)
            {
                DiaryTimeTick dtt = new DiaryTimeTick(this);
                dtt.Top = j * 80;
                Ticks.Add(dtt);
            }
            logger.Trace("InitializeTicks()...Done");
        }
Esempio n. 15
0
        public override void Initialize(LinkedNavigationEvent linkedNavigationEvent)
        {
            var ticks = IoC.Get <IBacktestRepository>().GetBacktestTicks(linkedNavigationEvent.Key);

            Ticks.Clear();
            foreach (var tick in ticks)
            {
                Ticks.Add(tick);
            }

            TickView = CollectionViewSource.GetDefaultView(Ticks);
            base.Initialize(linkedNavigationEvent);
        }
Esempio n. 16
0
        public void AddTest()
        {
            IDataManager data = new OpenWealth.Data.Data();
            //data.Init(); сейчас всё делается в конструкторе, но в будущем может понадобится

            ISymbol symbol = data.GetSymbol("AddTest");
            IScale  scale  = data.GetScale(ScaleEnum.tick, 1);
            Ticks   ticks  = new Ticks(symbol, scale);

            Assert.AreEqual(ticks.Count, 0);
            IBar bar0 = new Bar(DateTime.Now, 10, 1, 1, 1, 1, 1);

            ticks.Add(null, bar0);
            Assert.AreEqual(ticks.Count, 1);
            Assert.AreEqual(ticks[0], bar0);

            IBar bar1 = new Bar(DateTime.Now, 20, 1, 1, 1, 1, 1);

            ticks.Add(null, bar1);
            Assert.AreEqual(ticks.Count, 2);
            Assert.AreEqual(ticks[1], bar1);

            IBar bar2 = new Bar(DateTime.Now, 15, 1, 1, 1, 1, 1);

            ticks.Add(null, bar2);
            Assert.AreEqual(ticks.Count, 3);
            Assert.AreEqual(ticks[0], bar0);
            Assert.AreEqual(ticks[1], bar2);
            Assert.AreEqual(ticks[2], bar1);

            IBar bar3 = new Bar(DateTime.Now, 15, 1, 1, 1, 1, 2);

            ticks.Add(null, bar2);
            Assert.AreEqual(ticks.Count, 3);
            Assert.AreEqual(ticks[0], bar0);
            Assert.AreEqual(ticks[1], bar2);
            Assert.AreEqual(ticks[2], bar1);
        }
Esempio n. 17
0
        public void BarExistsTest()
        {
            IDataManager data = new OpenWealth.Data.Data();
            //data.Init(); сейчас всё делается в конструкторе, но в будущем может понадобится

            ISymbol symbol = data.GetSymbol("BarExistsTest");
            IScale  scale  = data.GetScale(ScaleEnum.tick, 1);
            Ticks   ticks  = new Ticks(symbol, scale);

            int index;

            Assert.AreEqual(ticks.BarExists(777, out index), false);
            Assert.AreEqual(0, index);

            ticks.Add(null, new Bar(DateTime.Now, 10, 1, 1, 1, 1, 1));

            Assert.AreEqual(ticks.BarExists(5, out index), false);
            Assert.AreEqual(0, index);
            Assert.AreEqual(ticks.BarExists(10, out index), true);
            Assert.AreEqual(0, index);
            Assert.AreEqual(ticks.BarExists(20, out index), false);
            Assert.AreEqual(1, index);

            ticks.Add(null, new Bar(DateTime.Now, 20, 1, 1, 1, 1, 1));

            Assert.AreEqual(ticks.BarExists(5, out index), false);
            Assert.AreEqual(0, index);
            Assert.AreEqual(ticks.BarExists(10, out index), true);
            Assert.AreEqual(0, index);
            Assert.AreEqual(ticks.BarExists(15, out index), false);
            Assert.AreEqual(1, index);
            Assert.AreEqual(ticks.BarExists(20, out index), true);
            Assert.AreEqual(1, index);
            Assert.AreEqual(ticks.BarExists(25, out index), false);
            Assert.AreEqual(2, index);
        }
Esempio n. 18
0
        /// <summary>
        /// Emits a new trade tick from a match message
        /// </summary>
        private void EmitTradeTick(Messages.Matched message)
        {
            var symbol = ConvertProductId(message.ProductId);

            lock (TickLocker)
            {
                Ticks.Add(new Tick
                {
                    Value    = message.Price,
                    Time     = DateTime.UtcNow,
                    Symbol   = symbol,
                    TickType = TickType.Trade,
                    Quantity = message.Size
                });
            }
        }
 private void EmitQuoteTick(Symbol symbol, decimal bidPrice, decimal bidSize, decimal askPrice, decimal askSize)
 {
     lock (TickLocker)
     {
         Ticks.Add(new Tick
         {
             AskPrice = askPrice,
             BidPrice = bidPrice,
             Value    = (askPrice + bidPrice) / 2m,
             Time     = DateTime.UtcNow,
             Symbol   = symbol,
             TickType = TickType.Quote,
             AskSize  = Math.Abs(askSize),
             BidSize  = Math.Abs(bidSize)
         });
     }
 }
Esempio n. 20
0
        public void Add(TTick item)
        {
            var periodInstance = Period.CreateInstance();

            if (Ticks.Any())
            {
                var tickEndTime = periodInstance.NextTimestamp(Ticks.Last().DateTime);
                if (item.DateTime < tickEndTime)
                {
                    throw new InvalidTimeFrameException(item.DateTime);
                }

                if (_maxTickCount.HasValue && Ticks.Count >= _maxTickCount.Value)
                {
                    Ticks = Ticks.Skip(Ticks.Count - _maxTickCount.Value + 1).Take(_maxTickCount.Value).ToList();
                }
            }
            Ticks.Add(item);
        }
Esempio n. 21
0
        /// <summary>
        /// Converts a ticker message and emits data as a new quote tick
        /// </summary>
        /// <param name="data"></param>
        private void EmitQuoteTick(string data)
        {
            var message = JsonConvert.DeserializeObject <Messages.Ticker>(data, JsonSettings);

            var symbol = ConvertProductId(message.ProductId);

            lock (_tickLocker)
            {
                Ticks.Add(new Tick
                {
                    AskPrice = message.BestAsk,
                    BidPrice = message.BestBid,
                    Value    = (message.BestAsk + message.BestBid) / 2m,
                    Time     = DateTime.UtcNow,
                    Symbol   = symbol,
                    TickType = TickType.Quote
                               //todo: tick volume
                });
            }
        }
Esempio n. 22
0
        /// <summary>
        /// Event handler for streaming ticks
        /// </summary>
        /// <param name="json">The data object containing the received tick</param>
        private void OnPricingDataReceived(string json)
        {
            var obj  = (JObject)JsonConvert.DeserializeObject(json);
            var type = obj["type"].ToString();

            switch (type)
            {
            case "HEARTBEAT":
                lock (LockerConnectionMonitor)
                {
                    LastHeartbeatUtcTime = DateTime.UtcNow;
                }
                break;

            case "PRICE":
                var data = obj.ToObject <Price>();

                var securityType = SymbolMapper.GetBrokerageSecurityType(data.Instrument);
                var symbol       = SymbolMapper.GetLeanSymbol(data.Instrument, securityType, Market.Oanda);
                var time         = GetTickDateTimeFromString(data.Time);

                // live ticks timestamps must be in exchange time zone
                DateTimeZone exchangeTimeZone;
                if (!_symbolExchangeTimeZones.TryGetValue(symbol, out exchangeTimeZone))
                {
                    exchangeTimeZone = MarketHoursDatabase.FromDataFolder().GetExchangeHours(Market.Oanda, symbol, securityType).TimeZone;
                    _symbolExchangeTimeZones.Add(symbol, exchangeTimeZone);
                }
                time = time.ConvertFromUtc(exchangeTimeZone);

                var bidPrice = Convert.ToDecimal(data.Bids.Last().Price);
                var askPrice = Convert.ToDecimal(data.Asks.Last().Price);
                var tick     = new Tick(time, symbol, bidPrice, askPrice);

                lock (Ticks)
                {
                    Ticks.Add(tick);
                }
                break;
            }
        }
Esempio n. 23
0
        private void LedDeviceThreadProc()
        {
            var lastSentBytes = new byte[0];

            while (!_isClosing)
            {
                Thread.Sleep(5);
                Color[] colors;

                lock (this)
                    colors = _colors.ToArray();

                try
                {
                    var fade  = CurrentFade;
                    var bytes = colors.SelectMany(color => new[] { (byte)Math.Round(color.R * fade), (byte)Math.Round(color.G * fade), (byte)Math.Round(color.B * fade) }).ToArray();

                    if (!lastSentBytes.SequenceEqual(bytes))
                    {
                        _port?.Write("LEDS");
                        WriteByte((byte)colors.Length);
                        Write(bytes);
                        ReadResponse();
                        lastSentBytes = bytes;

                        Ticks.Add();
                        LastUpdated = DateTime.Now;
                        Updated?.Invoke();
                    }
                }
                catch (Exception exception)
                {
                    Error = exception;
                    _port?.Dispose();
                    return;
                }
            }

            _port?.Dispose();
        }
Esempio n. 24
0
        /// <summary>
        /// Event handler for streaming ticks
        /// </summary>
        /// <param name="data">The data object containing the received tick</param>
        private void OnDataReceived(RateStreamResponse data)
        {
            if (data.IsHeartbeat())
            {
                lock (LockerConnectionMonitor)
                {
                    LastHeartbeatUtcTime = DateTime.UtcNow;
                }
                return;
            }

            if (data.tick == null)
            {
                return;
            }

            var securityType = SymbolMapper.GetBrokerageSecurityType(data.tick.instrument);
            var symbol       = SymbolMapper.GetLeanSymbol(data.tick.instrument, securityType, Market.Oanda);
            var time         = OandaBrokerage.GetDateTimeFromString(data.tick.time);

            // live ticks timestamps must be in exchange time zone
            DateTimeZone exchangeTimeZone;

            if (!_symbolExchangeTimeZones.TryGetValue(symbol, out exchangeTimeZone))
            {
                exchangeTimeZone = MarketHoursDatabase.FromDataFolder().GetExchangeHours(Market.Oanda, symbol, securityType).TimeZone;
                _symbolExchangeTimeZones.Add(symbol, exchangeTimeZone);
            }
            time = time.ConvertFromUtc(exchangeTimeZone);

            var bidPrice = Convert.ToDecimal(data.tick.bid);
            var askPrice = Convert.ToDecimal(data.tick.ask);
            var tick     = new Tick(time, symbol, bidPrice, askPrice);

            lock (Ticks)
            {
                Ticks.Add(tick);
            }
        }
Esempio n. 25
0
        private void ReCalculateTimelineTicks()
        {
            // for now
            Ticks.Clear();

            // do a tick for each hour
            var hours = (int)(TickEndDateTime - TickStartDateTime).TotalHours;

            // round up to the nearest hour
            // need to get the tick based rounding code
            DateTime baseHourTick = TickStartDateTime.AddHours(1).AddMinutes(TickStartDateTime.Minute * -1);

            for (int i = 0; i < hours; i++)
            {
                Ticks.Add(
                    new TimelineTick()
                {
                    Time = baseHourTick.AddHours(i)
                }
                    );
            }
        }
Esempio n. 26
0
        /// <summary>
        /// Launch the algorithm manager to run this strategy
        /// </summary>
        /// <param name="job">Algorithm job</param>
        /// <param name="algorithm">Algorithm instance</param>
        /// <param name="feed">Datafeed object</param>
        /// <param name="transactions">Transaction manager object</param>
        /// <param name="results">Result handler object</param>
        /// <param name="realtime">Realtime processing object</param>
        /// <param name="token">Cancellation token</param>
        /// <remarks>Modify with caution</remarks>
        public void Run(AlgorithmNodePacket job, IAlgorithm algorithm, IDataFeed feed, ITransactionHandler transactions, IResultHandler results, IRealTimeHandler realtime, CancellationToken token)
        {
            //Initialize:
            _dataPointCount = 0;
            var startingPortfolioValue = algorithm.Portfolio.TotalPortfolioValue;
            var backtestMode           = (job.Type == PacketType.BacktestNode);
            var methodInvokers         = new Dictionary <Type, MethodInvoker>();
            var marginCallFrequency    = TimeSpan.FromMinutes(5);
            var nextMarginCallTime     = DateTime.MinValue;
            var delistingTickets       = new List <OrderTicket>();

            //Initialize Properties:
            _algorithmId    = job.AlgorithmId;
            _algorithmState = AlgorithmStatus.Running;
            _previousTime   = algorithm.StartDate.Date;

            //Create the method accessors to push generic types into algorithm: Find all OnData events:

            // Algorithm 2.0 data accessors
            var hasOnDataTradeBars = AddMethodInvoker <TradeBars>(algorithm, methodInvokers);
            var hasOnDataTicks     = AddMethodInvoker <Ticks>(algorithm, methodInvokers);

            // dividend and split events
            var hasOnDataDividends  = AddMethodInvoker <Dividends>(algorithm, methodInvokers);
            var hasOnDataSplits     = AddMethodInvoker <Splits>(algorithm, methodInvokers);
            var hasOnDataDelistings = AddMethodInvoker <Delistings>(algorithm, methodInvokers);

            // Algorithm 3.0 data accessors
            var hasOnDataSlice = algorithm.GetType().GetMethods()
                                 .Where(x => x.Name == "OnData" && x.GetParameters().Length == 1 && x.GetParameters()[0].ParameterType == typeof(Slice))
                                 .FirstOrDefault(x => x.DeclaringType == algorithm.GetType()) != null;

            //Go through the subscription types and create invokers to trigger the event handlers for each custom type:
            foreach (var config in feed.Subscriptions)
            {
                //If type is a tradebar, combine tradebars and ticks into unified array:
                if (config.Type.Name != "TradeBar" && config.Type.Name != "Tick")
                {
                    //Get the matching method for this event handler - e.g. public void OnData(Quandl data) { .. }
                    var genericMethod = (algorithm.GetType()).GetMethod("OnData", new[] { config.Type });

                    //If we already have this Type-handler then don't add it to invokers again.
                    if (methodInvokers.ContainsKey(config.Type))
                    {
                        continue;
                    }

                    //If we couldnt find the event handler, let the user know we can't fire that event.
                    if (genericMethod == null && !hasOnDataSlice)
                    {
                        algorithm.RunTimeError = new Exception("Data event handler not found, please create a function matching this template: public void OnData(" + config.Type.Name + " data) {  }");
                        _algorithmState        = AlgorithmStatus.RuntimeError;
                        return;
                    }
                    if (genericMethod != null)
                    {
                        methodInvokers.Add(config.Type, genericMethod.DelegateForCallMethod());
                    }
                }
            }

            //Loop over the queues: get a data collection, then pass them all into relevent methods in the algorithm.
            Log.Trace("AlgorithmManager.Run(): Begin DataStream - Start: " + algorithm.StartDate + " Stop: " + algorithm.EndDate);
            foreach (var timeSlice in feed.Bridge.GetConsumingEnumerable(token))
            {
                // reset our timer on each loop
                _currentTimeStepTime = DateTime.UtcNow;

                //Check this backtest is still running:
                if (_algorithmState != AlgorithmStatus.Running)
                {
                    Log.Error(string.Format("AlgorithmManager.Run(): Algorthm state changed to {0} at {1}", _algorithmState, timeSlice.Time));
                    break;
                }

                //Execute with TimeLimit Monitor:
                if (token.IsCancellationRequested)
                {
                    Log.Error("AlgorithmManager.Run(): CancellationRequestion at " + timeSlice.Time);
                    return;
                }

                var time    = timeSlice.Time;
                var newData = timeSlice.Data;

                //If we're in backtest mode we need to capture the daily performance. We do this here directly
                //before updating the algorithm state with the new data from this time step, otherwise we'll
                //produce incorrect samples (they'll take into account this time step's new price values)
                if (backtestMode)
                {
                    //On day-change sample equity and daily performance for statistics calculations
                    if (_previousTime.Date != time.Date)
                    {
                        //Sample the portfolio value over time for chart.
                        results.SampleEquity(_previousTime, Math.Round(algorithm.Portfolio.TotalPortfolioValue, 4));

                        //Check for divide by zero
                        if (startingPortfolioValue == 0m)
                        {
                            results.SamplePerformance(_previousTime.Date, 0);
                        }
                        else
                        {
                            results.SamplePerformance(_previousTime.Date, Math.Round((algorithm.Portfolio.TotalPortfolioValue - startingPortfolioValue) * 100 / startingPortfolioValue, 10));
                        }
                        startingPortfolioValue = algorithm.Portfolio.TotalPortfolioValue;
                    }
                }

                //Update algorithm state after capturing performance from previous day

                //Set the algorithm and real time handler's time
                algorithm.SetDateTime(time);
                realtime.SetTime(algorithm.Time);

                //On each time step push the real time prices to the cashbook so we can have updated conversion rates
                algorithm.Portfolio.CashBook.Update(newData);

                //Update the securities properties: first before calling user code to avoid issues with data
                algorithm.Securities.Update(time, newData);

                // process fill models on the updated data before entering algorithm, applies to all non-market orders
                transactions.ProcessSynchronousEvents();

                if (delistingTickets.Count != 0)
                {
                    for (int i = 0; i < delistingTickets.Count; i++)
                    {
                        var ticket = delistingTickets[i];
                        if (ticket.Status == OrderStatus.Filled)
                        {
                            algorithm.Securities.Remove(ticket.Symbol);
                            delistingTickets.RemoveAt(i--);
                            Log.Trace("AlgorithmManager.Run(): Security removed: " + ticket.Symbol);
                        }
                    }
                }

                //Check if the user's signalled Quit: loop over data until day changes.
                if (algorithm.GetQuit())
                {
                    _algorithmState = AlgorithmStatus.Quit;
                    Log.Trace("AlgorithmManager.Run(): Algorithm quit requested.");
                    break;
                }
                if (algorithm.RunTimeError != null)
                {
                    _algorithmState = AlgorithmStatus.RuntimeError;
                    Log.Trace(string.Format("AlgorithmManager.Run(): Algorithm encountered a runtime error at {0}. Error: {1}", timeSlice.Time, algorithm.RunTimeError));
                    break;
                }

                // perform margin calls, in live mode we can also use realtime to emit these
                if (time >= nextMarginCallTime || (_liveMode && nextMarginCallTime > DateTime.Now))
                {
                    // determine if there are possible margin call orders to be executed
                    bool issueMarginCallWarning;
                    var  marginCallOrders = algorithm.Portfolio.ScanForMarginCall(out issueMarginCallWarning);
                    if (marginCallOrders.Count != 0)
                    {
                        try
                        {
                            // tell the algorithm we're about to issue the margin call
                            algorithm.OnMarginCall(marginCallOrders);
                        }
                        catch (Exception err)
                        {
                            algorithm.RunTimeError = err;
                            _algorithmState        = AlgorithmStatus.RuntimeError;
                            Log.Error("AlgorithmManager.Run(): RuntimeError: OnMarginCall: " + err.Message + " STACK >>> " + err.StackTrace);
                            return;
                        }

                        // execute the margin call orders
                        var executedTickets = algorithm.Portfolio.MarginCallModel.ExecuteMarginCall(marginCallOrders);
                        foreach (var ticket in executedTickets)
                        {
                            algorithm.Error(string.Format("{0} - Executed MarginCallOrder: {1} - Quantity: {2} @ {3}", algorithm.Time, ticket.Symbol, ticket.Quantity, ticket.OrderEvents.Last().FillPrice));
                        }
                    }
                    // we didn't perform a margin call, but got the warning flag back, so issue the warning to the algorithm
                    else if (issueMarginCallWarning)
                    {
                        try
                        {
                            algorithm.OnMarginCallWarning();
                        }
                        catch (Exception err)
                        {
                            algorithm.RunTimeError = err;
                            _algorithmState        = AlgorithmStatus.RuntimeError;
                            Log.Error("AlgorithmManager.Run(): RuntimeError: OnMarginCallWarning: " + err.Message + " STACK >>> " + err.StackTrace);
                        }
                    }

                    nextMarginCallTime = time + marginCallFrequency;
                }

                //Trigger the data events: Invoke the types we have data for:
                var newBars       = new TradeBars(algorithm.Time);
                var newTicks      = new Ticks(algorithm.Time);
                var newDividends  = new Dividends(algorithm.Time);
                var newSplits     = new Splits(algorithm.Time);
                var newDelistings = new Delistings(algorithm.Time);

                //Invoke all non-tradebars, non-ticks methods and build up the TradeBars and Ticks dictionaries
                // --> i == Subscription Configuration Index, so we don't need to compare types.
                foreach (var i in newData.Keys)
                {
                    //Data point and config of this point:
                    var dataPoints = newData[i];
                    var config     = feed.Subscriptions[i];

                    //Keep track of how many data points we've processed
                    _dataPointCount += dataPoints.Count;

                    //We don't want to pump data that we added just for currency conversions
                    if (config.IsInternalFeed)
                    {
                        continue;
                    }

                    //Create TradeBars Unified Data --> OR --> invoke generic data event. One loop.
                    //  Aggregate Dividends and Splits -- invoke portfolio application methods
                    foreach (var dataPoint in dataPoints)
                    {
                        var dividend = dataPoint as Dividend;
                        if (dividend != null)
                        {
                            Log.Trace("AlgorithmManager.Run(): Applying Dividend for " + dividend.Symbol);
                            // if this is a dividend apply to portfolio
                            algorithm.Portfolio.ApplyDividend(dividend);
                            if (hasOnDataDividends)
                            {
                                // and add to our data dictionary to pump into OnData(Dividends data)
                                newDividends.Add(dividend);
                            }
                            continue;
                        }

                        var split = dataPoint as Split;
                        if (split != null)
                        {
                            Log.Trace("AlgorithmManager.Run(): Applying Split for " + split.Symbol);
                            // if this is a split apply to portfolio
                            algorithm.Portfolio.ApplySplit(split);
                            if (hasOnDataSplits)
                            {
                                // and add to our data dictionary to pump into OnData(Splits data)
                                newSplits.Add(split);
                            }
                            continue;
                        }

                        var delisting = dataPoint as Delisting;
                        if (delisting != null)
                        {
                            if (hasOnDataDelistings)
                            {
                                // add to out data dictonary to pump into OnData(Delistings data)
                                newDelistings.Add(delisting);
                            }
                        }

                        //Update registered consolidators for this symbol index
                        try
                        {
                            for (var j = 0; j < config.Consolidators.Count; j++)
                            {
                                config.Consolidators[j].Update(dataPoint);
                            }
                        }
                        catch (Exception err)
                        {
                            algorithm.RunTimeError = err;
                            _algorithmState        = AlgorithmStatus.RuntimeError;
                            Log.Error("AlgorithmManager.Run(): RuntimeError: Consolidators update: " + err.Message);
                            return;
                        }

                        // TRADEBAR -- add to our dictionary
                        if (dataPoint.DataType == MarketDataType.TradeBar)
                        {
                            var bar = dataPoint as TradeBar;
                            if (bar != null)
                            {
                                newBars[bar.Symbol] = bar;
                                continue;
                            }
                        }

                        // TICK -- add to our dictionary
                        if (dataPoint.DataType == MarketDataType.Tick)
                        {
                            var tick = dataPoint as Tick;
                            if (tick != null)
                            {
                                List <Tick> ticks;
                                if (!newTicks.TryGetValue(tick.Symbol, out ticks))
                                {
                                    ticks = new List <Tick>(3);
                                    newTicks.Add(tick.Symbol, ticks);
                                }
                                ticks.Add(tick);
                                continue;
                            }
                        }

                        // if it was nothing else then it must be custom data

                        // CUSTOM DATA -- invoke on data method
                        //Send data into the generic algorithm event handlers
                        try
                        {
                            MethodInvoker methodInvoker;
                            if (methodInvokers.TryGetValue(config.Type, out methodInvoker))
                            {
                                methodInvoker(algorithm, dataPoint);
                            }
                        }
                        catch (Exception err)
                        {
                            algorithm.RunTimeError = err;
                            _algorithmState        = AlgorithmStatus.RuntimeError;
                            Log.Error("AlgorithmManager.Run(): RuntimeError: Custom Data: " + err.Message + " STACK >>> " + err.StackTrace);
                            return;
                        }
                    }
                }

                try
                {
                    // fire off the dividend and split events before pricing events
                    if (hasOnDataDividends && newDividends.Count != 0)
                    {
                        methodInvokers[typeof(Dividends)](algorithm, newDividends);
                    }
                    if (hasOnDataSplits && newSplits.Count != 0)
                    {
                        methodInvokers[typeof(Splits)](algorithm, newSplits);
                    }
                    if (hasOnDataDelistings && newDelistings.Count != 0)
                    {
                        methodInvokers[typeof(Delistings)](algorithm, newDelistings);
                    }
                }
                catch (Exception err)
                {
                    algorithm.RunTimeError = err;
                    _algorithmState        = AlgorithmStatus.RuntimeError;
                    Log.Error("AlgorithmManager.Run(): RuntimeError: Dividends/Splits/Delistings: " + err.Message + " STACK >>> " + err.StackTrace);
                    return;
                }

                // run the delisting logic after firing delisting events
                HandleDelistedSymbols(algorithm, newDelistings, delistingTickets);

                //After we've fired all other events in this second, fire the pricing events:
                try
                {
                    if (hasOnDataTradeBars && newBars.Count > 0)
                    {
                        methodInvokers[typeof(TradeBars)](algorithm, newBars);
                    }
                    if (hasOnDataTicks && newTicks.Count > 0)
                    {
                        methodInvokers[typeof(Ticks)](algorithm, newTicks);
                    }
                }
                catch (Exception err)
                {
                    algorithm.RunTimeError = err;
                    _algorithmState        = AlgorithmStatus.RuntimeError;
                    Log.Error("AlgorithmManager.Run(): RuntimeError: New Style Mode: " + err.Message + " STACK >>> " + err.StackTrace);
                    return;
                }

                // EVENT HANDLER v3.0 -- all data in a single event
                var slice = new Slice(algorithm.Time, newData.Values.SelectMany(x => x),
                                      newBars.Count == 0 ? null : newBars,
                                      newTicks.Count == 0 ? null : newTicks,
                                      newSplits.Count == 0 ? null : newSplits,
                                      newDividends.Count == 0 ? null : newDividends,
                                      newDelistings.Count == 0 ? null : newDelistings
                                      );

                try
                {
                    algorithm.OnData(slice);
                }
                catch (Exception err)
                {
                    algorithm.RunTimeError = err;
                    _algorithmState        = AlgorithmStatus.RuntimeError;
                    Log.Error("AlgorithmManager.Run(): RuntimeError: Slice: " + err.Message + " STACK >>> " + err.StackTrace);
                    return;
                }

                //If its the historical/paper trading models, wait until market orders have been "filled"
                // Manually trigger the event handler to prevent thread switch.
                transactions.ProcessSynchronousEvents();

                //Save the previous time for the sample calculations
                _previousTime = time;

                // Process any required events of the results handler such as sampling assets, equity, or stock prices.
                results.ProcessSynchronousEvents();
            } // End of ForEach feed.Bridge.GetConsumingEnumerable

            // stop timing the loops
            _currentTimeStepTime = DateTime.MinValue;

            //Stream over:: Send the final packet and fire final events:
            Log.Trace("AlgorithmManager.Run(): Firing On End Of Algorithm...");
            try
            {
                algorithm.OnEndOfAlgorithm();
            }
            catch (Exception err)
            {
                _algorithmState        = AlgorithmStatus.RuntimeError;
                algorithm.RunTimeError = new Exception("Error running OnEndOfAlgorithm(): " + err.Message, err.InnerException);
                Log.Error("AlgorithmManager.OnEndOfAlgorithm(): " + err.Message + " STACK >>> " + err.StackTrace);
                return;
            }

            // Process any required events of the results handler such as sampling assets, equity, or stock prices.
            results.ProcessSynchronousEvents(forceProcess: true);

            //Liquidate Holdings for Calculations:
            if (_algorithmState == AlgorithmStatus.Liquidated && _liveMode)
            {
                Log.Trace("AlgorithmManager.Run(): Liquidating algorithm holdings...");
                algorithm.Liquidate();
                results.LogMessage("Algorithm Liquidated");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Liquidated);
            }

            //Manually stopped the algorithm
            if (_algorithmState == AlgorithmStatus.Stopped)
            {
                Log.Trace("AlgorithmManager.Run(): Stopping algorithm...");
                results.LogMessage("Algorithm Stopped");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Stopped);
            }

            //Backtest deleted.
            if (_algorithmState == AlgorithmStatus.Deleted)
            {
                Log.Trace("AlgorithmManager.Run(): Deleting algorithm...");
                results.DebugMessage("Algorithm Id:(" + job.AlgorithmId + ") Deleted by request.");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Deleted);
            }

            //Algorithm finished, send regardless of commands:
            results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Completed);

            //Take final samples:
            results.SampleRange(algorithm.GetChartUpdates());
            results.SampleEquity(_previousTime, Math.Round(algorithm.Portfolio.TotalPortfolioValue, 4));
            results.SamplePerformance(_previousTime, Math.Round((algorithm.Portfolio.TotalPortfolioValue - startingPortfolioValue) * 100 / startingPortfolioValue, 10));
        } // End of Run();
Esempio n. 27
0
 public void AddTick()
 {
     Ticks.Add(MockUtilities.GenerateTicks("backtestidToImplement", 1)[0]);
 }
Esempio n. 28
0
        /********************************************************
         * CLASS METHODS
         *********************************************************/
        /// <summary>
        /// Launch the algorithm manager to run this strategy
        /// </summary>
        /// <param name="job">Algorithm job</param>
        /// <param name="algorithm">Algorithm instance</param>
        /// <param name="feed">Datafeed object</param>
        /// <param name="transactions">Transaction manager object</param>
        /// <param name="results">Result handler object</param>
        /// <param name="setup">Setup handler object</param>
        /// <param name="realtime">Realtime processing object</param>
        /// <remarks>Modify with caution</remarks>
        public static void Run(AlgorithmNodePacket job, IAlgorithm algorithm, IDataFeed feed, ITransactionHandler transactions, IResultHandler results, ISetupHandler setup, IRealTimeHandler realtime)
        {
            //Initialize:
            var backwardsCompatibilityMode = false;
            var tradebarsType       = typeof(TradeBars);
            var ticksType           = typeof(Ticks);
            var startingPerformance = setup.StartingCapital;
            var backtestMode        = (job.Type == PacketType.BacktestNode);
            var methodInvokers      = new Dictionary <Type, MethodInvoker>();

            //Initialize Properties:
            _frontier       = setup.StartingDate;
            _runtimeError   = null;
            _algorithmId    = job.AlgorithmId;
            _algorithmState = AlgorithmStatus.Running;
            _previousTime   = setup.StartingDate.Date;

            //Create the method accessors to push generic types into algorithm: Find all OnData events:

            //Algorithm 1.0 Data Accessors.
            //If the users defined these methods, add them in manually. This allows keeping backwards compatibility to algorithm 1.0.
            var oldTradeBarsMethodInfo = (algorithm.GetType()).GetMethod("OnTradeBar", new[] { typeof(Dictionary <string, TradeBar>) });
            var oldTicksMethodInfo     = (algorithm.GetType()).GetMethod("OnTick", new[] { typeof(Dictionary <string, List <Tick> >) });

            //Algorithm 2.0 Data Generics Accessors.
            //New hidden access to tradebars with custom type.
            var newTradeBarsMethodInfo = (algorithm.GetType()).GetMethod("OnData", new[] { tradebarsType });
            var newTicksMethodInfo     = (algorithm.GetType()).GetMethod("OnData", new[] { ticksType });

            if (newTradeBarsMethodInfo == null && newTicksMethodInfo == null)
            {
                backwardsCompatibilityMode = true;
                if (oldTradeBarsMethodInfo != null)
                {
                    methodInvokers.Add(tradebarsType, oldTradeBarsMethodInfo.DelegateForCallMethod());
                }
                if (oldTradeBarsMethodInfo != null)
                {
                    methodInvokers.Add(ticksType, oldTicksMethodInfo.DelegateForCallMethod());
                }
            }
            else
            {
                backwardsCompatibilityMode = false;
                if (newTradeBarsMethodInfo != null)
                {
                    methodInvokers.Add(tradebarsType, newTradeBarsMethodInfo.DelegateForCallMethod());
                }
                if (newTicksMethodInfo != null)
                {
                    methodInvokers.Add(ticksType, newTicksMethodInfo.DelegateForCallMethod());
                }
            }

            //Go through the subscription types and create invokers to trigger the event handlers for each custom type:
            foreach (var config in feed.Subscriptions)
            {
                //If type is a tradebar, combine tradebars and ticks into unified array:
                if (config.Type.Name != "TradeBar" && config.Type.Name != "Tick")
                {
                    //Get the matching method for this event handler - e.g. public void OnData(Quandl data) { .. }
                    var genericMethod = (algorithm.GetType()).GetMethod("OnData", new[] { config.Type });

                    //Is we already have this Type-handler then don't add it to invokers again.
                    if (methodInvokers.ContainsKey(config.Type))
                    {
                        continue;
                    }

                    //If we couldnt find the event handler, let the user know we can't fire that event.
                    if (genericMethod == null)
                    {
                        _runtimeError   = new Exception("Data event handler not found, please create a function matching this template: public void OnData(" + config.Type.Name + " data) {  }");
                        _algorithmState = AlgorithmStatus.RuntimeError;
                        return;
                    }
                    methodInvokers.Add(config.Type, genericMethod.DelegateForCallMethod());
                }
            }

            //Loop over the queues: get a data collection, then pass them all into relevent methods in the algorithm.
            Log.Debug("AlgorithmManager.Run(): Algorithm initialized, launching time loop.");
            foreach (var newData in DataStream.GetData(feed, setup.StartingDate))
            {
                //Check this backtest is still running:
                if (_algorithmState != AlgorithmStatus.Running)
                {
                    break;
                }

                //Go over each time stamp we've collected, pass it into the algorithm in order:
                foreach (var time in newData.Keys)
                {
                    //Set the time frontier:
                    _frontier = time;

                    //Execute with TimeLimit Monitor:
                    if (Isolator.IsCancellationRequested)
                    {
                        return;
                    }

                    //Refresh the realtime event monitor:
                    realtime.SetTime(time);

                    //Fire EOD if the time packet we just processed is greater
                    if (backtestMode && _previousTime.Date != time.Date)
                    {
                        //Sample the portfolio value over time for chart.
                        results.SampleEquity(_previousTime, Math.Round(algorithm.Portfolio.TotalPortfolioValue, 4));

                        if (startingPerformance == 0)
                        {
                            results.SamplePerformance(_previousTime.Date, 0);
                        }
                        else
                        {
                            results.SamplePerformance(_previousTime.Date, Math.Round((algorithm.Portfolio.TotalPortfolioValue - startingPerformance) * 100 / startingPerformance, 10));
                        }

                        startingPerformance = algorithm.Portfolio.TotalPortfolioValue;
                    }

                    //Check if the user's signalled Quit: loop over data until day changes.
                    if (algorithm.GetQuit())
                    {
                        _algorithmState = AlgorithmStatus.Quit;
                        break;
                    }

                    //Pass in the new time first:
                    algorithm.SetDateTime(time);

                    //Trigger the data events: Invoke the types we have data for:
                    var oldBars  = new Dictionary <string, TradeBar>();
                    var oldTicks = new Dictionary <string, List <Tick> >();
                    var newBars  = new TradeBars(time);
                    var newTicks = new Ticks(time);

                    //Invoke all non-tradebars, non-ticks methods:
                    // --> i == Subscription Configuration Index, so we don't need to compare types.
                    foreach (var i in newData[time].Keys)
                    {
                        //Data point and config of this point:
                        var dataPoints = newData[time][i];
                        var config     = feed.Subscriptions[i];

                        //Create TradeBars Unified Data --> OR --> invoke generic data event. One loop.
                        foreach (var dataPoint in dataPoints)
                        {
                            //Update the securities properties: first before calling user code to avoid issues with data
                            algorithm.Securities.Update(time, dataPoint);

                            //Update registered consolidators for this symbol index
                            for (var j = 0; j < config.Consolidators.Count; j++)
                            {
                                config.Consolidators[j].Update(dataPoint);
                            }

                            switch (config.Type.Name)
                            {
                            case "TradeBar":
                                var bar = dataPoint as TradeBar;
                                try
                                {
                                    if (bar != null)
                                    {
                                        if (backwardsCompatibilityMode)
                                        {
                                            if (!oldBars.ContainsKey(bar.Symbol))
                                            {
                                                oldBars.Add(bar.Symbol, bar);
                                            }
                                        }
                                        else
                                        {
                                            if (!newBars.ContainsKey(bar.Symbol))
                                            {
                                                newBars.Add(bar.Symbol, bar);
                                            }
                                        }
                                    }
                                }
                                catch (Exception err)
                                {
                                    Log.Error(time.ToLongTimeString() + " >> " + bar.Time.ToLongTimeString() + " >> " + bar.Symbol + " >> " + bar.Value.ToString("C"));
                                    Log.Error("AlgorithmManager.Run(): Failed to add TradeBar (" + bar.Symbol + ") Time: (" + time.ToLongTimeString() + ") Count:(" + newBars.Count + ") " + err.Message);
                                }
                                break;

                            case "Tick":
                                var tick = dataPoint as Tick;
                                if (tick != null)
                                {
                                    if (backwardsCompatibilityMode)
                                    {
                                        if (!oldTicks.ContainsKey(tick.Symbol))
                                        {
                                            oldTicks.Add(tick.Symbol, new List <Tick>());
                                        }
                                        oldTicks[tick.Symbol].Add(tick);
                                    }
                                    else
                                    {
                                        if (!newTicks.ContainsKey(tick.Symbol))
                                        {
                                            newTicks.Add(tick.Symbol, new List <Tick>());
                                        }
                                        newTicks[tick.Symbol].Add(tick);
                                    }
                                }
                                break;

                            default:
                                //Send data into the generic algorithm event handlers
                                try
                                {
                                    methodInvokers[config.Type](algorithm, dataPoint);
                                }
                                catch (Exception err)
                                {
                                    _runtimeError   = err;
                                    _algorithmState = AlgorithmStatus.RuntimeError;
                                    Log.Error("AlgorithmManager.Run(): RuntimeError: Custom Data: " + err.Message + " STACK >>> " + err.StackTrace);
                                    return;
                                }
                                break;
                            }
                        }
                    }

                    //After we've fired all other events in this second, fire the pricing events:
                    if (backwardsCompatibilityMode)
                    {
                        //Log.Debug("AlgorithmManager.Run(): Invoking v1.0 Event Handlers...");
                        try
                        {
                            if (oldTradeBarsMethodInfo != null && oldBars.Count > 0)
                            {
                                methodInvokers[tradebarsType](algorithm, oldBars);
                            }
                            if (oldTicksMethodInfo != null && oldTicks.Count > 0)
                            {
                                methodInvokers[ticksType](algorithm, oldTicks);
                            }
                        }
                        catch (Exception err)
                        {
                            _runtimeError   = err;
                            _algorithmState = AlgorithmStatus.RuntimeError;
                            Log.Error("AlgorithmManager.Run(): RuntimeError: Backwards Compatibility Mode: " + err.Message + " STACK >>> " + err.StackTrace);
                            return;
                        }
                    }
                    else
                    {
                        //Log.Debug("AlgorithmManager.Run(): Invoking v2.0 Event Handlers...");
                        try
                        {
                            if (newTradeBarsMethodInfo != null && newBars.Count > 0)
                            {
                                methodInvokers[tradebarsType](algorithm, newBars);
                            }
                            if (newTicksMethodInfo != null && newTicks.Count > 0)
                            {
                                methodInvokers[ticksType](algorithm, newTicks);
                            }
                        }
                        catch (Exception err)
                        {
                            _runtimeError   = err;
                            _algorithmState = AlgorithmStatus.RuntimeError;
                            Log.Error("AlgorithmManager.Run(): RuntimeError: New Style Mode: " + err.Message + " STACK >>> " + err.StackTrace);
                            return;
                        }
                    }

                    //If its the historical/paper trading models, wait until market orders have been "filled"
                    // Manually trigger the event handler to prevent thread switch.
                    transactions.ProcessSynchronousEvents();

                    //Save the previous time for the sample calculations
                    _previousTime = time;
                } // End of Time Loop

                // Process any required events of the results handler such as sampling assets, equity, or stock prices.
                results.ProcessSynchronousEvents();
            } // End of ForEach DataStream

            //Stream over:: Send the final packet and fire final events:
            Log.Trace("AlgorithmManager.Run(): Firing On End Of Algorithm...");
            try
            {
                algorithm.OnEndOfAlgorithm();
            }
            catch (Exception err)
            {
                _runtimeError   = new Exception("Error running OnEndOfAlgorithm(): " + err.Message, err.InnerException);
                _algorithmState = AlgorithmStatus.RuntimeError;
                return;
            }

            // Process any required events of the results handler such as sampling assets, equity, or stock prices.
            results.ProcessSynchronousEvents();

            //Liquidate Holdings for Calculations:
            if (_algorithmState == AlgorithmStatus.Liquidated || !Engine.LiveMode)
            {
                Log.Trace("AlgorithmManager.Run(): Liquidating algorithm holdings...");
                algorithm.Liquidate();
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Liquidated);
            }

            //Manually stopped the algorithm
            if (_algorithmState == AlgorithmStatus.Stopped)
            {
                Log.Trace("AlgorithmManager.Run(): Stopping algorithm...");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Stopped);
            }

            //Backtest deleted.
            if (_algorithmState == AlgorithmStatus.Deleted)
            {
                Log.Trace("AlgorithmManager.Run(): Deleting algorithm...");
                results.DebugMessage("Algorithm Id:(" + job.AlgorithmId + ") Deleted by request.");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Deleted);
            }

            //Algorithm finished, send regardless of commands:
            results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Completed);

            //Take final samples:
            results.SampleRange(algorithm.GetChartUpdates());
            results.SampleEquity(_frontier, Math.Round(algorithm.Portfolio.TotalPortfolioValue, 4));
            results.SamplePerformance(_frontier, Math.Round((algorithm.Portfolio.TotalPortfolioValue - startingPerformance) * 100 / startingPerformance, 10));
        } // End of Run();
Esempio n. 29
0
 public static TimeSpan Add(TimeSpan timeout1, TimeSpan timeout2)
 {
     return(Ticks.ToTimeSpan(Ticks.Add(Ticks.FromTimeSpan(timeout1), Ticks.FromTimeSpan(timeout2))));
 }
Esempio n. 30
0
 protected override void AddTrade(TradeEvent tradeEvent)
 {
     Ticks.Add(tradeEvent.Tick);
 }
Esempio n. 31
0
        /********************************************************
        * CLASS METHODS
        *********************************************************/
        /// <summary>
        /// Launch the algorithm manager to run this strategy
        /// </summary>
        /// <param name="job">Algorithm job</param>
        /// <param name="algorithm">Algorithm instance</param>
        /// <param name="feed">Datafeed object</param>
        /// <param name="transactions">Transaction manager object</param>
        /// <param name="results">Result handler object</param>
        /// <param name="setup">Setup handler object</param>
        /// <param name="realtime">Realtime processing object</param>
        /// <remarks>Modify with caution</remarks>
        public static void Run(AlgorithmNodePacket job, IAlgorithm algorithm, IDataFeed feed, ITransactionHandler transactions, IResultHandler results, ISetupHandler setup, IRealTimeHandler realtime)
        {
            //Initialize:
            var backwardsCompatibilityMode = false;
            var tradebarsType = typeof (TradeBars);
            var ticksType = typeof(Ticks);
            var startingPerformance = setup.StartingCapital;
            var backtestMode = (job.Type == PacketType.BacktestNode);
            var methodInvokers = new Dictionary<Type, MethodInvoker>();

            //Initialize Properties:
            _frontier = setup.StartingDate;
            _runtimeError = null;
            _algorithmId = job.AlgorithmId;
            _algorithmState = AlgorithmStatus.Running;
            _previousTime = setup.StartingDate.Date;

            //Create the method accessors to push generic types into algorithm: Find all OnData events:

            //Algorithm 1.0 Data Accessors.
            //If the users defined these methods, add them in manually. This allows keeping backwards compatibility to algorithm 1.0.
            var oldTradeBarsMethodInfo = (algorithm.GetType()).GetMethod("OnTradeBar",   new[] { typeof(Dictionary<string, TradeBar>) });
            var oldTicksMethodInfo = (algorithm.GetType()).GetMethod("OnTick", new[] { typeof(Dictionary<string, List<Tick>>) });

            //Algorithm 2.0 Data Generics Accessors.
            //New hidden access to tradebars with custom type.
            var newTradeBarsMethodInfo = (algorithm.GetType()).GetMethod("OnData", new[] { tradebarsType });
            var newTicksMethodInfo = (algorithm.GetType()).GetMethod("OnData", new[] { ticksType });

            if (newTradeBarsMethodInfo == null && newTicksMethodInfo == null)
            {
                backwardsCompatibilityMode = true;
                if (oldTradeBarsMethodInfo != null) methodInvokers.Add(tradebarsType, oldTradeBarsMethodInfo.DelegateForCallMethod());
                if (oldTradeBarsMethodInfo != null) methodInvokers.Add(ticksType, oldTicksMethodInfo.DelegateForCallMethod());
            }
            else
            {
                backwardsCompatibilityMode = false;
                if (newTradeBarsMethodInfo != null) methodInvokers.Add(tradebarsType, newTradeBarsMethodInfo.DelegateForCallMethod());
                if (newTicksMethodInfo != null) methodInvokers.Add(ticksType, newTicksMethodInfo.DelegateForCallMethod());
            }

            //Go through the subscription types and create invokers to trigger the event handlers for each custom type:
            foreach (var config in feed.Subscriptions)
            {
                //If type is a tradebar, combine tradebars and ticks into unified array:
                if (config.Type.Name != "TradeBar" && config.Type.Name != "Tick")
                {
                    //Get the matching method for this event handler - e.g. public void OnData(Quandl data) { .. }
                    var genericMethod = (algorithm.GetType()).GetMethod("OnData", new[] { config.Type });

                    //Is we already have this Type-handler then don't add it to invokers again.
                    if (methodInvokers.ContainsKey(config.Type)) continue;

                    //If we couldnt find the event handler, let the user know we can't fire that event.
                    if (genericMethod == null)
                    {
                        _runtimeError = new Exception("Data event handler not found, please create a function matching this template: public void OnData(" + config.Type.Name + " data) {  }");
                        _algorithmState = AlgorithmStatus.RuntimeError;
                        return;
                    }
                    methodInvokers.Add(config.Type, genericMethod.DelegateForCallMethod());
                }
            }

            //Loop over the queues: get a data collection, then pass them all into relevent methods in the algorithm.
            Log.Debug("AlgorithmManager.Run(): Algorithm initialized, launching time loop.");
            foreach (var newData in DataStream.GetData(feed, setup.StartingDate))
            {
                //Check this backtest is still running:
                if (_algorithmState != AlgorithmStatus.Running) break;

                //Go over each time stamp we've collected, pass it into the algorithm in order:
                foreach (var time in newData.Keys)
                {
                    //Set the time frontier:
                    _frontier = time;

                    //Execute with TimeLimit Monitor:
                    if (Isolator.IsCancellationRequested) return;

                    //Refresh the realtime event monitor:
                    realtime.SetTime(time);

                    //Fire EOD if the time packet we just processed is greater
                    if (backtestMode && _previousTime.Date != time.Date)
                    {
                        //Sample the portfolio value over time for chart.
                        results.SampleEquity(_previousTime, Math.Round(algorithm.Portfolio.TotalPortfolioValue, 4));

                        if (startingPerformance == 0)
                        {
                            results.SamplePerformance(_previousTime.Date, 0);
                        }
                        else
                        {
                            results.SamplePerformance(_previousTime.Date, Math.Round((algorithm.Portfolio.TotalPortfolioValue - startingPerformance) * 100 / startingPerformance, 10));
                        }

                        startingPerformance = algorithm.Portfolio.TotalPortfolioValue;
                    }

                    //Check if the user's signalled Quit: loop over data until day changes.
                    if (algorithm.GetQuit())
                    {
                        _algorithmState = AlgorithmStatus.Quit;
                        break;
                    }

                    //Pass in the new time first:
                    algorithm.SetDateTime(time);

                    //Trigger the data events: Invoke the types we have data for:
                    var oldBars = new Dictionary<string, TradeBar>();
                    var oldTicks = new Dictionary<string, List<Tick>>();
                    var newBars = new TradeBars(time);
                    var newTicks = new Ticks(time);

                    //Invoke all non-tradebars, non-ticks methods:
                    // --> i == Subscription Configuration Index, so we don't need to compare types.
                    foreach (var i in newData[time].Keys)
                    {
                        //Data point and config of this point:
                        var dataPoints = newData[time][i];
                        var config = feed.Subscriptions[i];

                        //Create TradeBars Unified Data --> OR --> invoke generic data event. One loop.
                        foreach (var dataPoint in dataPoints)
                        {
                            //Update the securities properties: first before calling user code to avoid issues with data
                            algorithm.Securities.Update(time, dataPoint);

                            //Update registered consolidators for this symbol index
                            for (var j = 0; j < config.Consolidators.Count; j++)
                            {
                                config.Consolidators[j].Update(dataPoint);
                            }

                            switch (config.Type.Name)
                            {
                                case "TradeBar":
                                    var bar = dataPoint as TradeBar;
                                    try
                                    {
                                        if (bar != null)
                                        {
                                            if (backwardsCompatibilityMode)
                                            {
                                                if (!oldBars.ContainsKey(bar.Symbol)) oldBars.Add(bar.Symbol, bar);
                                            }
                                            else
                                            {
                                                if (!newBars.ContainsKey(bar.Symbol)) newBars.Add(bar.Symbol, bar);
                                            }
                                        }
                                    }
                                    catch (Exception err)
                                    {
                                        Log.Error(time.ToLongTimeString() + " >> " + bar.Time.ToLongTimeString() + " >> " + bar.Symbol + " >> " + bar.Value.ToString("C"));
                                        Log.Error("AlgorithmManager.Run(): Failed to add TradeBar (" + bar.Symbol + ") Time: (" + time.ToLongTimeString() + ") Count:(" + newBars.Count + ") " + err.Message);
                                    }
                                    break;

                                case "Tick":
                                    var tick = dataPoint as Tick;
                                    if (tick != null)
                                    {
                                         if (backwardsCompatibilityMode) {
                                             if (!oldTicks.ContainsKey(tick.Symbol)) { oldTicks.Add(tick.Symbol, new List<Tick>()); }
                                             oldTicks[tick.Symbol].Add(tick);
                                         }
                                         else
                                         {
                                             if (!newTicks.ContainsKey(tick.Symbol)) { newTicks.Add(tick.Symbol, new List<Tick>()); }
                                             newTicks[tick.Symbol].Add(tick);
                                         }
                                    }
                                    break;

                                default:
                                    //Send data into the generic algorithm event handlers
                                    try
                                    {
                                        methodInvokers[config.Type](algorithm, dataPoint);
                                    }
                                    catch (Exception err)
                                    {
                                        _runtimeError = err;
                                        _algorithmState = AlgorithmStatus.RuntimeError;
                                        Log.Debug("AlgorithmManager.Run(): RuntimeError: Custom Data: " + err.Message + " STACK >>> " + err.StackTrace);
                                        return;
                                    }
                                    break;
                            }
                        }
                    }

                    //After we've fired all other events in this second, fire the pricing events:
                    if (backwardsCompatibilityMode)
                    {
                        //Log.Debug("AlgorithmManager.Run(): Invoking v1.0 Event Handlers...");
                        try
                        {
                            if (oldTradeBarsMethodInfo != null && oldBars.Count > 0) methodInvokers[tradebarsType](algorithm, oldBars);
                            if (oldTicksMethodInfo != null && oldTicks.Count > 0) methodInvokers[ticksType](algorithm, oldTicks);
                        }
                        catch (Exception err)
                        {
                            _runtimeError = err;
                            _algorithmState = AlgorithmStatus.RuntimeError;
                            Log.Debug("AlgorithmManager.Run(): RuntimeError: Backwards Compatibility Mode: " + err.Message + " STACK >>> " + err.StackTrace);
                            return;
                        }
                    }
                    else
                    {
                        //Log.Debug("AlgorithmManager.Run(): Invoking v2.0 Event Handlers...");
                        try
                        {
                            if (newTradeBarsMethodInfo != null && newBars.Count > 0) methodInvokers[tradebarsType](algorithm, newBars);
                            if (newTicksMethodInfo != null && newTicks.Count > 0) methodInvokers[ticksType](algorithm, newTicks);
                        }
                        catch (Exception err)
                        {
                            _runtimeError = err;
                            _algorithmState = AlgorithmStatus.RuntimeError;
                            Log.Debug("AlgorithmManager.Run(): RuntimeError: New Style Mode: " + err.Message + " STACK >>> " + err.StackTrace);
                            return;
                        }
                    }

                    //If its the historical/paper trading models, wait until market orders have been "filled"
                    // Manually trigger the event handler to prevent thread switch.
                    transactions.ProcessSynchronousEvents();

                    //Save the previous time for the sample calculations
                    _previousTime = time;

                } // End of Time Loop

                // Process any required events of the results handler such as sampling assets, equity, or stock prices.
                results.ProcessSynchronousEvents();
            } // End of ForEach DataStream

            //Stream over:: Send the final packet and fire final events:
            Log.Trace("AlgorithmManager.Run(): Firing On End Of Algorithm...");
            try
            {
                algorithm.OnEndOfAlgorithm();
            }
            catch (Exception err)
            {
                _algorithmState = AlgorithmStatus.RuntimeError;
                _runtimeError = new Exception("Error running OnEndOfAlgorithm(): " + err.Message, err.InnerException);
                Log.Debug("AlgorithmManager.OnEndOfAlgorithm(): " + err.Message + " STACK >>> " + err.StackTrace);
                return;
            }

            // Process any required events of the results handler such as sampling assets, equity, or stock prices.
            results.ProcessSynchronousEvents(forceProcess: true);

            //Liquidate Holdings for Calculations:
            if (_algorithmState == AlgorithmStatus.Liquidated || !Engine.LiveMode)
            {
                Log.Trace("AlgorithmManager.Run(): Liquidating algorithm holdings...");
                algorithm.Liquidate();
                results.LogMessage("Algorithm Liquidated");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Liquidated);
            }

            //Manually stopped the algorithm
            if (_algorithmState == AlgorithmStatus.Stopped)
            {
                Log.Trace("AlgorithmManager.Run(): Stopping algorithm...");
                results.LogMessage("Algorithm Stopped");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Stopped);
            }

            //Backtest deleted.
            if (_algorithmState == AlgorithmStatus.Deleted)
            {
                Log.Trace("AlgorithmManager.Run(): Deleting algorithm...");
                results.DebugMessage("Algorithm Id:(" + job.AlgorithmId + ") Deleted by request.");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Deleted);
            }

            //Algorithm finished, send regardless of commands:
            results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Completed);

            //Take final samples:
            results.SampleRange(algorithm.GetChartUpdates());
            results.SampleEquity(_frontier, Math.Round(algorithm.Portfolio.TotalPortfolioValue, 4));
            results.SamplePerformance(_frontier, Math.Round((algorithm.Portfolio.TotalPortfolioValue - startingPerformance) * 100 / startingPerformance, 10));
        }
Esempio n. 32
0
        /// <summary>
        /// Adds the specified <see cref="BaseData"/> instance to the appropriate <see cref="DataDictionary{T}"/>
        /// </summary>
        private static void PopulateDataDictionaries(BaseData baseData, Ticks ticks, TradeBars tradeBars, QuoteBars quoteBars, OptionChains optionChains)
        {
            var symbol = baseData.Symbol;

            // populate data dictionaries
            switch (baseData.DataType)
            {
                case MarketDataType.Tick:
                    ticks.Add(symbol, (Tick)baseData);
                    break;

                case MarketDataType.TradeBar:
                    tradeBars[symbol] = (TradeBar) baseData;
                    break;

                case MarketDataType.QuoteBar:
                    quoteBars[symbol] = (QuoteBar) baseData;
                    break;

                case MarketDataType.OptionChain:
                    optionChains[symbol] = (OptionChain) baseData;
                    break;
            }
        }