Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从连续出现的数据c#中形成5分钟的打开-高-低-关闭值?_C#_.net_Linq - Fatal编程技术网

如何从连续出现的数据c#中形成5分钟的打开-高-低-关闭值?

如何从连续出现的数据c#中形成5分钟的打开-高-低-关闭值?,c#,.net,linq,C#,.net,Linq,我有一个websocket api,它持续每秒为我提供数据。我的目标是在这些数据的基础上形成一个5分钟的开盘收盘高低点 这是Python代码,它们在Python中的作用相同: 我尝试了如下OnTickmethod每1秒调用一次,每秒钟的数据如下: {"InstrumentToken":260105,"LastPrice":23616.6,"Timestamp":"2020-10-16T16:35:01"} 因此,我

我有一个websocket api,它持续每秒为我提供数据。我的目标是在这些数据的基础上形成一个5分钟的开盘收盘高低点

这是Python代码,它们在Python中的作用相同:

我尝试了如下
OnTick
method每1秒调用一次,每秒钟的数据如下:

{"InstrumentToken":260105,"LastPrice":23616.6,"Timestamp":"2020-10-16T16:35:01"}
因此,我会在每一秒之后得到相同的json,并且具有不同的LastPrice和Timestamp,如:

{"InstrumentToken":260105,"LastPrice":23620,"Timestamp":"2020-10-16T14:38:02"}

{"InstrumentToken":260105,"LastPrice":23622,"Timestamp":"2020-10-16T14:38:03"}
等等,直到:

{"InstrumentToken":260105,"LastPrice":23644,"Timestamp":"2020-10-16T14:39:59"}
现在在下面的object
latestTickData
中,我正在收集所有这些数据,预期的输出是:

open=23616.6,因为这是一个基于“时间戳”的非常起始的价格:“2020-10-16T14:35:01”

close=23644,基于其最后5分钟的价格“时间戳”:“2020-10-16T14:39:59”

高=我可以使用最大值(所有5分钟数据)

低=我可以使用最小值(所有5分钟数据)

C#代码:

现在我将每秒收集一个新数据到
latestTickData

我想在这个数据的基础上形成一个5分钟的开盘收盘高低点

我想用时间戳和minmax函数进行分组来查找低和高,但代码不起作用

我尝试使用此代码,但此代码不适用于计算正在进行的数据的ontick方法:

var resultSet = MydataList.GroupBy(i => i.GetStartOfPeriodByMins(5))
           .Select(gr =>
          new
          {
              StartOfPeriod = gr.Key,
              Low = gr.Min(item => item.Low),
              High = gr.Max(item => item.High),
              Open = gr.OrderBy(item => item.TimeStamp).First().Open,
              Close = gr.OrderBy(item => item.TimeStamp).Last().Close
          });


public DateTime GetStartOfPeriodByMins(int numMinutes)
    {
        int oldMinutes = TimeStamp.Minute;
        int newMinutes = (oldMinutes / numMinutes) * numMinutes;

        DateTime startOfPeriod = new DateTime(TimeStamp.Year, TimeStamp.Month, TimeStamp.Day, TimeStamp.Hour, newMinutes, 0);

        return startOfPeriod;
    }
编辑: 正如@Cid所提到的,第一种方法假设数据以固定的时间间隔出现,但很可能永远不会出现这种情况,并且错误的可能性很大。最好的方法是尝试第二种方法,其中有两个变量并比较时间戳


在这个问题上有多种解决方法。您提到每1s获取一次数据,例如,您可以有一个变量来计算您收集了多少数据:

//before first element has come
int numberOfData=0;
当numberOfData为300(5*60秒)时,假设你每一秒钟得到一次数据,那么五分钟过去了


另一种方法是,您有两个变量firstData和lastData,它们最初设置为null。然后您将第一个TickData分配给firstData,而不仅仅是比较firstData和即将到来的新TickData对象之间的时间戳。当差异为5分钟时,您可以将该对象分配给lastData。

编辑: 正如@Cid所提到的,第一种方法假设数据以固定的时间间隔出现,但很可能永远不会出现这种情况,并且错误的可能性很大。最好的方法是尝试第二种方法,其中有两个变量并比较时间戳


在这个问题上有多种解决方法。您提到每1s获取一次数据,例如,您可以有一个变量来计算您收集了多少数据:

//before first element has come
int numberOfData=0;
当numberOfData为300(5*60秒)时,假设你每一秒钟得到一次数据,那么五分钟过去了



另一种方法是,你有两个变量firstData和lastData,它们最初被设置为null。然后你分配给firstData的第一个数据,而不仅仅是比较firstData和即将到来的新TickData对象之间的时间戳。当差异为5分钟时,您可以将该对象分配给lastData。

有很多方法可以做到这一点,这取决于您需要读取数据的频率,以及是否值得每滴答更新一次缓存,或者您需要一个计时器来保持刷新,或者你只是想在飞行中计算它

无论如何,我已经选择了一个队列来管理这个系列,我还选择了在每个滴答声(正确或错误)时更新缓存。你可以很容易地使用一个列表,并实时过滤/查询,我将把所有这些细节留给你

给定的

public class Tick
{
   public int Instrument { get; set; }
   public DateTime TimeStamp { get; set; }
   public decimal LatestPrice { get; set; }
}

public class Data
{
   private readonly Queue<Tick> _queue = new Queue<Tick>();
   public decimal High { get; private set; }
   public decimal Low { get; private set; }
   public decimal Open { get; private set; }
   public decimal Close { get; private set; }

   public void Add(Tick tick)
   {
      _queue.Enqueue(tick);
      Update();
   }

   public void Update()
   {
      var age = DateTime.Now.AddMinutes(-5);
      while (_queue.Any() && _queue.Peek().TimeStamp < age)
         _queue.Dequeue();

      High = _queue.Max(x => x.LatestPrice);
      Low = _queue.Min(x => x.LatestPrice);
      Open = _queue.LastOrDefault()?.LatestPrice ?? 0;
      Close = _queue.FirstOrDefault()?.LatestPrice ?? 0;

   }
}
如果你想快速计算的话

public class Data
{
   private readonly Queue<Tick> _queue = new Queue<Tick>();
   public decimal High => _queue.Max(x => x.LatestPrice);
   public decimal Low => _queue.Min(x => x.LatestPrice);
   public decimal Open => _queue.LastOrDefault()?.LatestPrice ?? 0;
   public decimal Close => _queue.FirstOrDefault()?.LatestPrice ?? 0;

   public void Add(Tick tick)
   {
      _queue.Enqueue(tick);
      Update();
   }

   public void Update()
   {
      var age = DateTime.Now.AddMinutes(-5);
      while (_queue.Any() && _queue.Peek().TimeStamp < age)
         _queue.Dequeue();
   }
}
公共类数据
{
私有只读队列_Queue=new Queue();
public decimal High=>\u queue.Max(x=>x.LatestPrice);
public decimal Low=>_queue.Min(x=>x.LatestPrice);
public decimal Open=>\u queue.LastOrDefault()?.LatestPrice??0;
public decimal Close=>\u queue.FirstOrDefault()?.LatestPrice??0;
公共空白添加(勾选)
{
_排队。排队(勾选);
更新();
}
公共无效更新()
{
var age=DateTime.Now.AddMinutes(-5);
while(_queue.Any()&&&_queue.Peek().TimeStamp

注意:这不是一个完整的解决方案,它缺少健全性检查和一大堆可能与您相关的细节。性能和效率也由您自行决定

有很多方法可以做到这一点,这取决于您需要读取数据的频率,以及是否值得每滴答更新一次缓存,或者您需要一个计时器来保持刷新,或者您只想动态计算

无论如何,我已经选择了一个队列来管理这个系列,我还选择了在每个滴答声(正确或错误)时更新缓存。你可以很容易地使用一个列表,并实时过滤/查询,我将把所有这些细节留给你

给定的

public class Tick
{
   public int Instrument { get; set; }
   public DateTime TimeStamp { get; set; }
   public decimal LatestPrice { get; set; }
}

public class Data
{
   private readonly Queue<Tick> _queue = new Queue<Tick>();
   public decimal High { get; private set; }
   public decimal Low { get; private set; }
   public decimal Open { get; private set; }
   public decimal Close { get; private set; }

   public void Add(Tick tick)
   {
      _queue.Enqueue(tick);
      Update();
   }

   public void Update()
   {
      var age = DateTime.Now.AddMinutes(-5);
      while (_queue.Any() && _queue.Peek().TimeStamp < age)
         _queue.Dequeue();

      High = _queue.Max(x => x.LatestPrice);
      Low = _queue.Min(x => x.LatestPrice);
      Open = _queue.LastOrDefault()?.LatestPrice ?? 0;
      Close = _queue.FirstOrDefault()?.LatestPrice ?? 0;

   }
}
如果你想快速计算的话

public class Data
{
   private readonly Queue<Tick> _queue = new Queue<Tick>();
   public decimal High => _queue.Max(x => x.LatestPrice);
   public decimal Low => _queue.Min(x => x.LatestPrice);
   public decimal Open => _queue.LastOrDefault()?.LatestPrice ?? 0;
   public decimal Close => _queue.FirstOrDefault()?.LatestPrice ?? 0;

   public void Add(Tick tick)
   {
      _queue.Enqueue(tick);
      Update();
   }

   public void Update()
   {
      var age = DateTime.Now.AddMinutes(-5);
      while (_queue.Any() && _queue.Peek().TimeStamp < age)
         _queue.Dequeue();
   }
}
公共类数据
{
私有只读队列_Queue=new Queue();
public decimal High=>\u queue.Max(x=>x.LatestPrice);
public decimal Low=>_queue.Min(x=>x.LatestPrice);
public decimal Open=>\u queue.LastOrDefault()?.LatestPrice??0;
public decimal Close=>\u queue.FirstOrDefault()?.LatestPrice??0;
公共空白添加(勾选)
{
_排队。排队(勾选);
更新();
}
公共无效更新()
{
var age=DateTime.Now.AddMinutes(-5);
while(_queue.Any()&&&_queue.Peek().TimeStamp
注意:这不是一个完整的解决方案,它缺少健全性检查和一大堆可能与您相关的细节。性能和效率也取决于您