Example #1
0
        /// <summary>Return the chart X axis value for a given time</summary>
        public double ChartXValue(TFTime time)
        {
            //' X-Axis: -ve --- 0 ---- +ve   '
            //' Idx:    <0      0      >0    '
            //'        past    now     future'

            // If the time is a point in the future, return the number of candles assuming no gaps
            if (time.ExactTicks >= Latest.Timestamp)
            {
                return(new TFTime(time.ExactTicks - Latest.Timestamp, TimeFrame).ExactTF);                // positive number, cos it's in the future
            }
            // If the time is a point in the past beyond our history, return the number of candles assuming no gaps
            if (time.ExactTicks <= Oldest.Timestamp)
            {
                return(-(Count + new TFTime(Oldest.Timestamp - time.ExactTicks, TimeFrame).ExactTF));                // negative, cos it's in the past
            }
            // Get the index into the past
            var idx = IndexAt(time);

            // Lerp between the timestamps of the candles on either side of 'idx'
            // Candles should exist because we know we're in the time range of the candle data.
            var c0 = this[idx]; Debug.Assert(c0 != null);
            var c1 = this[idx + 1]; Debug.Assert(c1 != null);

            var frac = Maths.Frac(c0.Timestamp, time.ExactTicks, c1.Timestamp);

            Debug.Assert(frac >= 0.0 && frac <= 1.0);
            return(idx + frac);
        }
Example #2
0
        /// <summary>Convert a time frame time range to an index range. (Indices in the range (-Count, 0])</summary>
        public Range TimeToIndexRange(TFTime time_min, TFTime time_max)
        {
            Debug.Assert(time_min <= time_max);
            var idx_min = IndexAt(time_min);
            var idx_max = IndexAt(time_max);

            return(new Range(idx_min, idx_max));
        }
Example #3
0
        /// <summary>Return the index of the candle at or immediately before 'time_stamp'. Note: the returned indices will be in the range (-Count, 0]</summary>
        public int IndexAt(TFTime time_stamp)
        {
            var ticks = time_stamp.ExactTicks;

            // If the time stamp is within the cached range, binary search the cache for the index position
            if (CachedTimeRange.Contains(ticks))
            {
                var idx = m_cache.BinarySearch(x => x.Timestamp.CompareTo(ticks));
                if (idx < 0)
                {
                    idx = ~idx;
                }
                return((m_index_range.Begi + idx) + FirstIdx);
            }
            // Otherwise use database queries to determine the index
            else
            {
                var sql = Str.Build("select count(*)-1 from ", TimeFrame, " where [", nameof(Candle.Timestamp), "] <= ? order by [", nameof(Candle.Timestamp), "]");
                var idx = m_db.ExecuteScalar(sql, 1, new object[] { ticks });
                return(idx + FirstIdx);
            }
        }
Example #4
0
        protected override void UpdateGfxCore()
        {
            // Find the index range in the Instrument history that 'Order' maps to
            var t0    = new TFTime(Order.EntryTimeUTC.Ticks, Instrument.TimeFrame);
            var t1    = new TFTime(Order.ExitTimeUTC.Ticks, Instrument.TimeFrame);
            var range = Instrument.TimeToIndexRange(t0, t1);

            // If the expiry is in the future, add on the expected number of candles
            var t2 = t1.ExactUTC > Instrument.Latest.TimestampUTC
                                ? (int)new TFTime(t1.ExactUTC - Instrument.Latest.TimestampUTC, Instrument.TimeFrame).IntgTF : 0;

            // Determine the width and position of the order
            var x = (float)(range.Begi - range.Endi);
            var w = (float)(range.Sizei + t2);

            // Get the entry price, stop loss, and take profit values
            var ep = (float)Order.EntryPrice;
            var sl = (float)Order.StopLossRel;
            var tp = (float)Order.TakeProfitRel;

            // Create graphics for the order
            switch (Order.TradeType)
            {
            default:
            {
                Debug.Assert(false, "Unknown trade type");
                Gfx = null;
                break;
            }

            case ETradeType.None:
            {
                Gfx = null;
                break;
            }

            case ETradeType.Short:
            case ETradeType.Long:
            {
                var sign     = Order.TradeType == ETradeType.Long ? +1 : -1;
                var selected = Selected || Hovered;
                var alpha    = selected ? 0.5f : 0.25f;
                var z        = ChartUI.Z.Trades + (selected ? 0.0001f : 0f);
                var sl_col   = Settings.Chart.TradeLossColour.Alpha(alpha);
                var tp_col   = Settings.Chart.TradeProfitColour.Alpha(alpha);
                var ep_col   = Color.DarkBlue;
                var line_col = Order.TradeType == ETradeType.Long ? Settings.UI.BullishColour.Alpha(0x60) : Settings.UI.BearishColour.Alpha(0x60);
                var xmin     = selected ? (float)Chart.XAxis.Min : x - 0;
                var xmax     = selected ? (float)Chart.XAxis.Max : x + w;

                m_vbuf.Clear();
                m_ibuf.Clear();
                m_nbuf.Clear();
                var V = 0U;
                var I = 0U;

                // Take profit area
                if (tp > 0)
                {
                    var v  = m_vbuf.Count;
                    var y0 = sign > 0 ? Math.Max(ep, ep - sl) : ep - tp;
                    var y1 = sign > 0 ? ep + tp : Math.Min(ep, ep + sl);
                    m_vbuf.Add(new View3d.Vertex(new v4(x, y0, z, 1), tp_col.ToArgbU()));
                    m_vbuf.Add(new View3d.Vertex(new v4(x + w, y0, z, 1), tp_col.ToArgbU()));
                    m_vbuf.Add(new View3d.Vertex(new v4(x, y1, z, 1), tp_col.ToArgbU()));
                    m_vbuf.Add(new View3d.Vertex(new v4(x + w, y1, z, 1), tp_col.ToArgbU()));
                    m_ibuf.AddRange(new[] { (ushort)v, (ushort)(v + 1), (ushort)(v + 3), (ushort)(v + 3), (ushort)(v + 2), (ushort)v });
                }
                // Stop loss area
                if (sl > 0)
                {
                    var v  = m_vbuf.Count;
                    var y0 = sign > 0 ? ep - sl : Math.Max(ep, ep - tp);
                    var y1 = sign > 0 ? Math.Min(ep, ep + tp) : ep + sl;
                    m_vbuf.Add(new View3d.Vertex(new v4(x, y0, z, 1), sl_col.ToArgbU()));
                    m_vbuf.Add(new View3d.Vertex(new v4(x + w, y0, z, 1), sl_col.ToArgbU()));
                    m_vbuf.Add(new View3d.Vertex(new v4(x, y1, z, 1), sl_col.ToArgbU()));
                    m_vbuf.Add(new View3d.Vertex(new v4(x + w, y1, z, 1), sl_col.ToArgbU()));
                    m_ibuf.AddRange(new[] { (ushort)v, (ushort)(v + 1), (ushort)(v + 3), (ushort)(v + 3), (ushort)(v + 2), (ushort)v });
                }
                m_nbuf.Add(new View3d.Nugget(View3d.EPrim.TriList, View3d.EGeom.Vert | View3d.EGeom.Colr, V, (uint)m_vbuf.Count, I, (uint)m_ibuf.Count, true));
                V = (uint)m_vbuf.Count;
                I = (uint)m_ibuf.Count;

                // Entry Price line
                {
                    var v = m_vbuf.Count;
                    m_vbuf.Add(new View3d.Vertex(new v4(xmin, ep, z, 1), Color.DarkBlue.ToArgbU()));
                    m_vbuf.Add(new View3d.Vertex(new v4(xmax, ep, z, 1), Color.DarkBlue.ToArgbU()));
                    m_ibuf.AddRange(new[] { (ushort)v, (ushort)(v + 1) });
                }
                // Take Profit line
                {
                    var v = m_vbuf.Count;
                    m_vbuf.Add(new View3d.Vertex(new v4(xmin, ep + sign * tp, z, 1), Color.DarkGreen.ToArgbU()));
                    m_vbuf.Add(new View3d.Vertex(new v4(xmax, ep + sign * tp, z, 1), Color.DarkGreen.ToArgbU()));
                    m_ibuf.AddRange(new[] { (ushort)v, (ushort)(v + 1) });
                }
                // Stop Loss line
                {
                    var v = m_vbuf.Count;
                    m_vbuf.Add(new View3d.Vertex(new v4(xmin, ep - sign * sl, z, 1), Color.DarkRed.ToArgbU()));
                    m_vbuf.Add(new View3d.Vertex(new v4(xmax, ep - sign * sl, z, 1), Color.DarkRed.ToArgbU()));
                    m_ibuf.AddRange(new[] { (ushort)v, (ushort)(v + 1) });
                }
                m_nbuf.Add(new View3d.Nugget(View3d.EPrim.LineList, View3d.EGeom.Vert | View3d.EGeom.Colr, V, (uint)m_vbuf.Count, I, (uint)m_ibuf.Count, true));

                // Create the geometry
                Gfx = new View3d.Object("Order", 0xFFFFFFFF, m_vbuf.Count, m_ibuf.Count, m_nbuf.Count, m_vbuf.ToArray(), m_ibuf.ToArray(), m_nbuf.ToArray());
                break;
            }
            }
            base.UpdateGfxCore();
        }
Example #5
0
        /// <summary>Enumerate the candles within a time range (given in time-frame units)</summary>
        public IEnumerable <Candle> CandleRange(TFTime time_min, TFTime time_max)
        {
            var range = TimeToIndexRange(time_min, time_max);

            return(CandleRange(range.Begi, range.Endi));
        }
Example #6
0
 public TFTime(TFTime tft, ETimeFrame tf)
     : this(tft.m_ticks, tf)
 {
 }
Example #7
0
 public bool Equals(TFTime rhs)
 {
     return(m_ticks == rhs.m_ticks && m_time_frame == rhs.m_time_frame);
 }