Как я могу заполнить IEnumerable класс индикаторов skender.stock.?

#c# #.net #vb.net #datatable #ienumerable

Вопрос:

У меня есть эти данные:

Указатель Дата Открыть высокий низкий Закрыть объем
1 01/03/17 $212.61 $213.35 $211.52 $212.80 96,708,880
2 01/04/17 $213.16 $214.22 $213.15 $214.06 83,348,752
3 01/05/17 $213.77 $214.06 $213.02 $213.89 82,961,968

Я пытаюсь использовать библиотеку Skender.stocks

https://daveskender.github.io/Stock.Индикаторы/руководство/

В образце на странице говорится только:

IEnumerable<Цитата> кавычки = <Цитата>Функция Mycustom();

Как я могу использовать DataTable в функции или приведении для возврата a IEnumerable<Quote> ?

Ответ №1:

Вам нужно будет:

  1. Выполните итерацию по строкам, доступным для данных
  2. Создайте новый экземпляр предложения
  3. Введите значения из строки в соответствующее свойство
  4. Добавьте цитату в List(Of Quote)

С этого момента список будет вашим IEnumerable.

Вот пример:

 Dim quotes As New List(Of Quote)()
For Each row As DataRow In MyDataTable.Rows
    quotes.Add(New Quote() With {
        .Date = Convert.ToDateTime(row.Item("Date")),
        .Open = Convert.ToDecimal(row.Item("Open")),
        .High = Convert.ToDecimal(row.Item("High")),
        .Low = Convert.ToDecimal(row.Item("Low")),
        .Close = Convert.ToDecimal(row.Item("Close")),
        .Volume = Convert.ToDecimal(row.Item("Volume"))
    })
Next
 

Живая демонстрация: https://dotnetfiddle.net/LgguWG

Это быстрый и грязный метод, если вы знаете, что каждая строка будет иметь значение для каждого столбца и каждый столбец может быть преобразован в соответствующий тип данных.

Если вы хотите немного уточнить его, вы можете настроить условные операторы, пытающиеся преобразовать значения, прежде чем устанавливать свойство цитаты, добавляемой в коллекцию.

Ответ №2:

Один из вариантов-создать свой собственный Quote класс и добавить конструктор, который получает значения своих свойств из потока данных

 private class MyQuote : Quote
{
    public MyQuote(DataRow dr)
    {
        this.Date = (DateTime)dr["date"];
        this.Open = (decimal)dr["open"];
        this.High = (decimal)dr["high"];
        this.Low = (decimal)dr["low"];
        this.Close = (decimal)dr["close"];
        this.Volume = (decimal)dr["volume"];
    }
}
 

или реализация интерфейса

 private class MyQuote : IQuote
{
    public DateTime Date { get; set; }
    public decimal Open { get; set; }
    public decimal High { get; set; }
    public decimal Low { get; set; }
    public decimal Close { get; set; }
    public decimal Volume { get; set; }
    public MyQuote(DataRow dr)
    {
        this.Date = (DateTime)dr["date"];
        this.Open = (decimal)dr["open"];
        this.High = (decimal)dr["high"];
        this.Low = (decimal)dr["low"];
        this.Close = (decimal)dr["close"];
        this.Volume = (decimal)dr["volume"];
    }
}
 

Затем вы можете использовать некоторый LINQ, чтобы получить его из базы данных (то же самое для производного класса и интерфейса).

 var quotes = dt.Select().Select(r => new MyQuote(r));
 

Комментарии:

1. Согласно документации по использованию пользовательских классов ( daveskender.github.io/Stock. Индикаторы/руководство/… ), рекомендуется реализовать интерфейс IQuote , а не наследовать Quote класс.

2. @David не читал, спасибо, добавлена опция интерфейса

Ответ №3:

Огромное, огромное спасибо Дэвиду!!, полный код на c#, если он кому-то еще нужен, выглядит так:

Заполните таблицу данных….

 using Skender.Stock.Indicators;




void makedt ()
    {
        dt = new DataTable();
        dt.Clear();
        dt.Columns.Add("Date");
        dt.Columns.Add("Open");
        dt.Columns.Add("High");
        dt.Columns.Add("Low");
        dt.Columns.Add("Close");
        dt.Columns.Add("Volume");

        DataRow _ravi = dt.NewRow();
        _ravi["Date"] = DateTime.Now;
        _ravi["Open"] = "500";
        _ravi["High"] = "500";
        _ravi["Low"] = "500";
        _ravi["Close"] = "500";
        _ravi["Volume"] = "500";
        dt.Rows.Add(_ravi);
        //_ravi.Delete();

        _ravi = dt.NewRow();
        _ravi["Date"] = DateTime.Now;
        _ravi["Open"] = "600";
        _ravi["High"] = "600";
        _ravi["Low"] = "600";
        _ravi["Close"] = "600";
        _ravi["Volume"] = "600";
        dt.Rows.Add(_ravi);
        //_ravi.Delete();

        _ravi = dt.NewRow();
        _ravi["Date"] = DateTime.Now;
        _ravi["Open"] = "700";
        _ravi["High"] = "700";
        _ravi["Low"] = "700";
        _ravi["Close"] = "700";
        _ravi["Volume"] = "700";
        dt.Rows.Add(_ravi);
        //_ravi.Delete();

        _ravi = dt.NewRow();
        _ravi["Date"] = DateTime.Now;
        _ravi["Open"] = "800";
        _ravi["High"] = "800";
        _ravi["Low"] = "800";
        _ravi["Close"] = "800";
        _ravi["Volume"] = "800";
        dt.Rows.Add(_ravi);
        //_ravi.Delete();

        _ravi = dt.NewRow();
        _ravi["Date"] = DateTime.Now;
        _ravi["Open"] = "900";
        _ravi["High"] = "900";
        _ravi["Low"] = "900";
        _ravi["Close"] = "900";
        _ravi["Volume"] = "900";
        dt.Rows.Add(_ravi);
        //_ravi.Delete();
    }
 

запуск процедуры……

 void method()
    {
        
        List<Quote> _quotes = new List<Quote>();
        foreach (DataRow row in dt.Rows)
            _quotes.Add(new Quote()
            {
                Date = Convert.ToDateTime(row["Date"]),
                Open = Convert.ToDecimal(row["Open"]),
                High = Convert.ToDecimal(row["High"]),
                Low = Convert.ToDecimal(row["Low"]),
                Close = Convert.ToDecimal(row["Close"]),
                Volume = Convert.ToDecimal(row["Volume"])
            });

        string s = "";
        foreach (var quote in _quotes)
        {
            s = s   quote.Date.ToString()   quote.Open.ToString()   quote.High.ToString()   quote.Low.ToString()   quote.Close.ToString();
        } // this for if only for check values

        IEnumerable<Quote> quotes = _quotes;
        IEnumerable<SmaResult> results = quotes.GetSma(2);


    }
 

Комментарии:

1. Плохая практика кодирования, связанная с этим ответом

2. @Chestera, Возможно, было бы более полезно указать на то, что вы считаете неправильным.

3. Лучший способ поблагодарить кого-либо за переполнение стека-принять его ответ, щелкнув галочку (галочку) слева от его ответа. Это принесло бы Дэвиду несколько очков, помогло бы будущим читателям и даже дало бы вам 2 балла.

4. @Mary ops, я просматривал в очереди этот ответ и не заметил, что он собирался опубликовать здесь. Хорошо, я имею в виду, что на плохой практике в этом ответе много дублирования кода, и он нуждается в некотором рефакторинге