I have this DataTable:
index | date | open | high | low | close | volume |
---|---|---|---|---|---|---|
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 |
I'm trying to use the Skender.stocks library
https://daveskender.github.io/Stock.Indicators/guide/
The sample in the page only says:
IEnumerable<Quote> quotes = Mycustomfunction();
How can I use a DataTable in a function or cast to return a IEnumerable<Quote>
?
CodePudding user response:
You will need to:
- Iterate over the DataTable rows
- Create a new instance of a Quote
- Input the values from the row into the respective property
- Add the Quote to a
List(Of Quote)
The list would be your IEnumerable from that point.
Here is an example:
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
Live Demo: https://dotnetfiddle.net/LgguWG
This is a quick and dirty method if you know that each row will have a value for every column and every column can be converted to its respective data type.
If you wanted to refine it a bit more, you could setup conditional statements attempting to convert the values prior to setting the property of the Quote being added to the collection.
CodePudding user response:
An option is to derive your own Quote
class and add a constructor which gets its property values from a DataRow
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"];
}
}
or implementing the Interface
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"];
}
}
Then you can use some LINQ to get it from the DataTable (same for derived class and interface)
var quotes = dt.Select().Select(r => new MyQuote(r));
CodePudding user response:
Many, many thanks to David!!, the complete code in c # for if someone else needs it is like this:
Populate the datatable....
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();
}
running the procedure......
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);
}