Beispiel #1
0
    private void RecordHistory()
    {
        var historyPoint = new HistoryDataPoint(
            LocalTime.Value,
            Owner.transform.position,
            Owner.transform.rotation.eulerAngles.z
            );

        if (history.Count < 2)
        {
            // We added a first point when the recording started. Add a second one.
            history.Add(historyPoint);
        }
        else
        {
            HistoryDataPoint point_n_1 = history[history.Count - 1];
            HistoryDataPoint point_n_2 = history[history.Count - 2];
            if (Mathf.Abs(point_n_1.Time - point_n_2.Time) >= TimeResolution)
            {
                // There is enough gap between the last two measures ; add one more.
                history.Add(historyPoint);
                LogDebug($"Recorded new point at index {history.Count - 1}: {historyPoint}");
            }
            else
            {
                // The last two points were very close; replace the most recent one.
                history[history.Count - 1] = historyPoint;
                LogDebug($"Updated index {history.Count - 1}: {historyPoint}");
            }
        }
    }
Beispiel #2
0
 public static HistoryDataPoint Lerp(HistoryDataPoint p1, HistoryDataPoint p2, float ratio)
 {
     if (ratio < 0 || ratio > 1)
     {
         throw new ArgumentOutOfRangeException($"Interpolation ratio only has meaning in the [0, 1] range ({ratio} given).");
     }
     return(new HistoryDataPoint(
                (1 - ratio) * p1.Time + ratio * p2.Time,
                Vector3.Lerp(p1.Position, p2.Position, ratio),
                (1 - ratio) * p1.Angle + ratio * p2.Angle
                ));
 }
Beispiel #3
0
    /// <summary>
    /// Ratio of the current time in the specified interval. May go beyond [0, 1]
    /// </summary>
    private float GetUnboundedRatioInInterval(HistoryDataPoint p1, HistoryDataPoint p2)
    {
        float p1Time = p1.Time;
        float p2Time = p2.Time;

        if (p1Time != p2Time)
        {
            return(Mathf.Sign(p2Time - p2Time) * (LocalTime.Value - p1Time) / (p2Time - p1Time));
        }
        else if (LocalTime.Value == p1Time)
        {
            // Anything between 0 and 1 would do.
            return(0.5f);
        }
        else
        {
            // What is the ratio if we're outside of a zero-width interval !?
            throw new ArgumentException("Invalid ratio computation using a zero-width interval");
        }
    }
        internal IEnumerable <HistoryDataPoint> PrepareDataPoints(uint contractId, TimeBarReport report)
        {
            if (report.time_bar == null)
            {
                yield break;
            }

            foreach (var bar in report.time_bar)
            {
                var dataPoint = new HistoryDataPoint(
                    adapter.ResolveDateTime(bar.bar_utc_time),
                    instrumentResolver.ConvertPriceBack(contractId, bar.high_price),
                    instrumentResolver.ConvertPriceBack(contractId, bar.low_price),
                    instrumentResolver.ConvertPriceBack(contractId, bar.open_price),
                    instrumentResolver.ConvertPriceBack(contractId, bar.close_price),
                    (int)bar.volume,
                    (int)bar.open_interest);
                yield return(dataPoint);
            }
        }
Beispiel #5
0
    private bool IsCurrentInterval(HistoryDataPoint p1, HistoryDataPoint p2)
    {
        float timeNow = LocalTime.Value;

        return((p1.Time - timeNow) * (p2.Time - timeNow) <= 0);
    }
Beispiel #6
0
    private void DoPlayback()
    {
        int nPoints    = history.Count;
        int ivMinIndex = 0;
        int ivMaxIndex = nPoints - 2; // -1 because indices; -1 because there is one less intervals than points.

        if (ivMaxIndex >= 0)
        {
            float timeNow             = LocalTime.Value;
            int?  properIntervalIndex = null;
            while (true)
            {
                int pivotIndex = (ivMinIndex + ivMaxIndex) / 2;
                HistoryDataPoint pivotBound1 = history[pivotIndex];
                HistoryDataPoint pivotBound2 = history[pivotIndex + 1];

                if (IsCurrentInterval(pivotBound1, pivotBound2))
                {
                    // Check the pivot interval. If it matches, exit the loop
                    properIntervalIndex = pivotIndex;
                    break;
                }
                else if (ivMinIndex != ivMaxIndex)
                {
                    // There are more intervals to explore, let's split the search space either on the left or right
                    bool checkLeft = (TimeDirectionSign * (timeNow - pivotBound1.Time) < 0);
                    if (checkLeft && ivMinIndex == pivotIndex || !checkLeft && ivMaxIndex == pivotIndex)
                    {
                        LogError($"Failed to locate the interval for local time {timeNow} in the history.");
                        break;
                    }
                    else
                    {
                        if (checkLeft)
                        {
                            ivMaxIndex = pivotIndex - 1;
                        }
                        else
                        {
                            ivMinIndex = pivotIndex + 1;
                        }
                    }
                }
                else
                {
                    LogError("Unable to locate the interval where a value should be taken in the history.");
                    break;
                }
            }

            if (properIntervalIndex.HasValue)
            {
                // Get the position and rotation to apply
                HistoryDataPoint p1            = history[properIntervalIndex.Value];
                HistoryDataPoint p2            = history[properIntervalIndex.Value + 1];
                float            intervalRatio = GetUnboundedRatioInInterval(p1, p2);
                HistoryDataPoint interpolation = HistoryDataPoint.Lerp(p1, p2, intervalRatio);

                LogDebug($"Applying saved point: {interpolation}");

                // Apply these to the object
                var rb = GetTargetRigidbody();
                rb.MovePosition(interpolation.Position);
                rb.MoveRotation(interpolation.Angle);

                // Discard things that were played back
                while (history.Count > properIntervalIndex.Value + 2)
                {
                    history.RemoveAt(history.Count - 1);
                }
            }
        }
        else
        {
            LogError(
                "Unable to playback an (almost) empty history. This action should have maybe be completed by now.\n" +
                $"  * History times = [{history.Aggregate("", (s, p) => (string.IsNullOrEmpty(s) ? s : s + ", ") + p.Time.ToString())}], " +
                $"time now = {LocalTime}.");
        }
    }
 public void AddPoint(int tickerId, HistoryDataPoint point) => GetHandler(tickerId, remove: false)?.AddPoint(point);