Ta-Lib ATR function always returns 0 - c#

I am using the Ta-Lib in C# and for the most part it works great. I am using it to calculate a number of moving averages and they calculate perfectly.
When Calling the ATR function it returns 0, always. I use the same parameters (the ones that overlap) as I do for the SMA, but still 0. Here is the code in question. Member variable Period is an integer. I have more data in the queues than the period I am asking it to calculate, and my data in the queues is clean, I've triple checked that. The return code is Success, but 0 return value.
int outbegldx = 0;
int outnbelement = 0;
Queue<double> inputHigh = new Queue<double>();
Queue<double> inputLow = new Queue<double>();
Queue<double> inputClose = new Queue<double>();
//This is in a loop
inputHigh.Enqueue(Convert.ToDouble(rdr.GetDecimal(5)));
inputLow.Enqueue(Convert.ToDouble(rdr.GetDecimal(6)));
inputClose.Enqueue(Convert.ToDouble(rdr.GetDecimal(7)));
double[] outreal = new double[inputHigh.Count];
retCode = TicTacTec.TA.Library.Core.Atr(0, inputHigh.Count - 1, inputHigh.ToArray(), inputLow.ToArray(), inputClose.ToArray(), this.Period, out outbegldx, out outnbelement, outreal);
if (retCode == Core.RetCode.Success)
{
this.Output = new AverageTrueRangeOutput(this.Period, outreal[0], outbegldx, outnbelement);
}

OK I figured it out, finally after many, many hours. In my loop I was checking to make sure the array had the same amount of elements as the Period, if so, I performed the calculation. In fact, the array needs Period + 1 elements to perform the calculation. Here is my entire function.
public override void Calculate()
{
int outbegldx = 0;
int outnbelement = 0;
int marketID = 0;
TicTacTec.TA.Library.Core.RetCode retCode;
//Queue<OHLC> input = new Queue<OHLC>();
Queue<double> inputHigh = new Queue<double>();
Queue<double> inputLow = new Queue<double>();
Queue<double> inputClose = new Queue<double>();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.DB_CONNECTION_STRING))
{
using (SqlCommand cmd = new SqlCommand("[Data].[proc_GetHistoricalData]", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#StartIndex", SqlDbType.Int);
cmd.Parameters.Add("#EndIndex", SqlDbType.Int);
cmd.Parameters.Add("#Weekly", SqlDbType.Bit);
cmd.Parameters["#StartIndex"].Value = this.startIndex;
cmd.Parameters["#EndIndex"].Value = this.endIndex;
cmd.Parameters["#Weekly"].Value = (int)this.TimeFrame;
conn.Open();
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
Console.WriteLine(rdr.GetInt64(0));
if (marketID != rdr.GetInt32(2))
{
marketID = rdr.GetInt32(2);
inputHigh.Clear();
inputLow.Clear();
inputClose.Clear();
}
//input.Enqueue(new OHLC(rdr.GetDecimal(4), rdr.GetDecimal(5), rdr.GetDecimal(6), rdr.GetDecimal(7)));
inputHigh.Enqueue(Convert.ToDouble(rdr.GetDecimal(5)));
inputLow.Enqueue(Convert.ToDouble(rdr.GetDecimal(6)));
inputClose.Enqueue(Convert.ToDouble(rdr.GetDecimal(7)));
//We have enough data to calculate the ATR so do so
if (inputHigh.Count >= this.Period + 1)
{
double[] outreal = new double[inputHigh.Count - 1];
int lookBack = Core.AtrLookback(this.Period);
retCode = Core.Atr(0, inputHigh.Count - 1, inputHigh.ToArray(), inputLow.ToArray(), inputClose.ToArray(), lookBack, out outbegldx, out outnbelement, outreal);
//Calculated the ATR, now write it to the database
if (retCode == Core.RetCode.Success)
{
this.Output = new AverageTrueRangeOutput(this.Period, outreal[0], outbegldx, outnbelement);
//Now insert into db
using (SqlCommand cmdInsert = new SqlCommand("[Data].[proc_InsertHistoricalIndicator]", conn))
{
cmdInsert.CommandType = CommandType.StoredProcedure;
cmdInsert.Parameters.Add("#MarketID", SqlDbType.Int);
cmdInsert.Parameters.Add("#IndicatorID", SqlDbType.Int);
cmdInsert.Parameters.Add("#Date", SqlDbType.Date);
cmdInsert.Parameters.Add("#Value", SqlDbType.Xml);
cmdInsert.Parameters.Add("#Weekly", SqlDbType.Bit);
cmdInsert.Parameters["#MarketID"].Value = rdr.GetInt32(2);
cmdInsert.Parameters["#IndicatorID"].Value = this.Id;
cmdInsert.Parameters["#Weekly"].Value = (int)this.TimeFrame;
cmdInsert.Parameters["#Date"].Value = rdr.GetDateTime(3); //IBLib.Util.GetDate(
cmdInsert.Parameters["#Value"].Value = this.Output.toXML().OuterXml;
cmdInsert.ExecuteNonQuery();
}
}
inputHigh.Dequeue();
inputLow.Dequeue();
inputClose.Dequeue();
}
}
rdr.Close();
}
}
}
}
The line in question is this one - "if (inputHigh.Count >= this.Period + 1)" whereas previously I just had "if (inputHigh.Count >= this.Period)"

Related

Why it always shows the error index is out of array bounds?

I'm crafting an app in c#, here is a problem that stopped me. My database table has 7 columns and it takes 7 while running application. But in the line SingleRow[c] = data[0].ToString();
it shows me an error telling me the index is out of bounds of array. Please suggest. My code is below.
public string[] RowOnly()
{
string[] SingleRow = new string[] { };
conn = new OleDbConnection(connStr);
conn.Open();
cmd = new OleDbCommand(query, conn);
data = cmd.ExecuteReader();
MessageBox.Show(data.HasRows.ToString());
int i = data.FieldCount;
while (data.Read())
{
for (int c = 0; c < i; c++)
{
SingleRow[c] = data[0].ToString();
}
}
conn.Close();
return SingleRow;
}
string[] SingleRow = new string[] { };
Is creating an array of length 0
Do this:
string[] SingleRow = new string[i];
(You'll have to move it to after the line that initializes i)
i.e:
int i = data.FieldCount;
string[] SingleRow = new string[i];
Tip: Only use {} when you want to initalize the collection:
e.g. new string[]{"abc", "def"};
This solved the problem thanks #Maximilian Ast
public string[] RowOnly()
{
conn = new OleDbConnection(connStr);
conn.Open();
cmd = new OleDbCommand(query, conn);
data = cmd.ExecuteReader();
MessageBox.Show(data.HasRows.ToString());
int i = data.FieldCount;
List<string> SingleRow = new List<string>();
while (data.Read())
{
for (int c = 0; c < i; c++)
{
SingleRow.Add(data[c].ToString());
}
}
conn.Close();
return SingleRow.ToArray();
}

SQL Transaction not committing to database

I am writing my first SQL transaction code and have scoured stackoverflow to make sure I've done it right. The basic idea of the project is to get an email, parse it into a RawDatum object, then write the contents of the object to the SQL database. I was hoping to commit the new rows in batches of 100.
I have the code running without errors, but nothing is being actually written to the database.
I have a local DB (MS SQL Server Express). I have a few things commented out for testing purposes. What am I doing wrong?
using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.MissionMetricsConnectionString))
{
connection.Open();
SqlCommand command = connection.CreateCommand();
command.CommandType = CommandType.Text;
command.CommandText = #"INSERT INTO RawData (MessageUID, DateTime, Attribute, DigitalValue, AnalogValue) VALUES (#MessageUID, #DateTime, #Attribute, #DigitalValue, #AnalogValue)";
command.Parameters.Add("#MessageUID", SqlDbType.Int);
command.Parameters.Add("#DateTime", SqlDbType.DateTime);
command.Parameters.Add("#Attribute", SqlDbType.Text);
command.Parameters.Add("#DigitalValue", SqlDbType.Bit);
command.Parameters.Add("#AnalogValue", SqlDbType.Float);
command.Connection = connection;
RawDatum currentDatum = null;
int uid;
List<int> uidsToDelete = new List<int>();
int numLoops = 1;//(int)(ids.Length / loopSize) + 1;
for (var loopIndex = 0; loopIndex < numLoops; loopIndex++)
{
int startIndex = loopIndex * loopSize;
int endIndex = 10;// Math.Min((loopIndex + 1) * loopSize, ids.Length);
using (SqlTransaction transaction = connection.BeginTransaction())
{
try
{
command.Transaction = transaction;
for (int i = startIndex; i < endIndex; i++)
{
msg = inbox.Fetch.MessageObject(ids[i]);
uid = inbox.Fetch.Uid(ids[i]);
if (msg.Subject == "[METRICS]")
{
currentDatum = new RawDatum(uid, msg.Date, msg.BodyText.TextStripped);
command.Parameters["#MessageUID"].Value = currentDatum.MessageUid;
command.Parameters["#DateTime"].Value = currentDatum.DateTime;
command.Parameters["#Attribute"].Value = currentDatum.Attribute;
command.Parameters["#DigitalValue"].Value = currentDatum.DigitalValue;
command.Parameters["#AnalogValue"].Value = currentDatum.AnalogValue;
int queryResult = command.ExecuteNonQuery();
if (queryResult != 1)
{
throw new InvalidProgramException();
}
}
uidsToDelete.Add(uid);
}
transaction.Commit();
//Delete(uidsToDelete);
output[1] += uidsToDelete.Count;
uidsToDelete.Clear();
}
catch
{
transaction.Rollback();
output[0] += 1;
output[2] += endIndex - startIndex;
}
}
}
connection.Close();
}

C# search method

I'm having trouble coming up with the following search method:
public override List<Team> Search(Dictionary<string, string> prms, int pageSize, int page, out int results)
{
var tresults = new List<Team>();
string temp1 = "";
string temp2 = "";
using (SqlConnection conn = DB.GetSqlConnection())
{
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = #"Search";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
foreach (KeyValuePair<string, string> pair in prms)
{
temp1 = pair.Key;
temp2 = pair.Value;
}
if (temp1 == "TeamName")
{
SqlParameter p1 = new SqlParameter("TeamName", System.Data.SqlDbType.VarChar);
p1.Value = temp2;
cmd.Parameters.Add(p1);
SqlParameter p2 = new SqlParameter("CityName", System.Data.SqlDbType.VarChar);
p2.Value = null;
cmd.Parameters.Add(p2);
}
else if (temp1 == "CityName")
{
SqlParameter p1 = new SqlParameter("TeamName", System.Data.SqlDbType.VarChar);
p1.Value = null;
cmd.Parameters.Add(p1);
SqlParameter p2 = new SqlParameter("CityName", System.Data.SqlDbType.VarChar);
p2.Value = temp2;
cmd.Parameters.Add(p2);
}
SqlDataReader reader = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
}
}
//results = 1 + 1;
throw new NotImplementedException("Must be implemented by class. ");
}
What I'm trying to do is basically what this test is doing:
[TestMethod]
public void SearchForTeam()
{
var dic = new Dictionary<string, string>();
int total = 0;
dic.Add("TeamName", "Patriots");
var nd = new TeamRepository();
var teams = nd.Search(dic, 100, 1, out total);
Assert.IsTrue(teams.Find(p => p.TeamName == "Patriots") != null);
}
What I'm trying to do is have my method search by either Team Name (SQL column "TeamName", value "Patriots") or by City Name (SQL column "CityName" value "Chicago", etc. I think my issues mainly are that I'm not entirely sure if I'm understanding how the dictionary works.
Also, I'm not sure how the value I'm returning should work because I am both returning an int (from the out parameter) and type List. This is all pretty new to me, so its the basics that I don't quite understand I suppose.
How about this?
public override List<Team> Search(Dictionary<string, string> prms, int pageSize, int page)
{
var tresults = new List<Team>();
using (SqlConnection conn = DB.GetSqlConnection())
{
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = #"Search";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
foreach (KeyValuePair<string, string> pair in prms)
cmd.Parameters.Add(new SqlParameter(pair.Key, System.Data.SqlDbType.VarChar) { Value = pair.Value });
SqlDataReader reader = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
// I assume you'll use pageSize and page here?
}
}
return tresults; // I assume this is what you want to return.
}
If you don't want to use a specific column for your search, then there's no need to create a SqlParameter for that column and sets its Value to null -- just don't use that column!
Also, there's no need to have out int results. If you're returning the list of teams, then the invoker can just get the team count from the list (teams.Count). (If you are doing something else with results, then by all means ignore this paragraph.)
it's kind of hard to see what you are getting at here, I am unsure that you need a dictionary at all (would you pass in multiple records?)
personally I would do the below, the assumption is the stored procedure could handle the possibility of both parameters being populated if both are passed in completed.
public override List<Team> Search(string teamName,string cityName, int pageSize, int page)
{
var tresults = new List<Team>();
using (SqlConnection conn = DB.GetSqlConnection())
{
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = #"Search";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
SqlParameter p1 = new SqlParameter("TeamName", System.Data.SqlDbType.VarChar);
p1.Value = teamName;
cmd.Parameters.Add(p1);
SqlParameter p2 = new SqlParameter("CityName", System.Data.SqlDbType.VarChar);
p2.Value = cityName;
cmd.Parameters.Add(p2);
SqlDataReader reader = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
while(reader.Read())
{
tresults.Add(BuildTeamFromReader(reader));
}
}
}
return tresults;
}
private Team BuildTeamFromReader(SqlDataReader reader)
{
var team = new Team();
team.TeamName = reader["TeamName"];//or whatever your column name is for team name
//ToDo other mappings
return team;
}

How to display atleast x and y axis when c-sharp chart control has no data in case of data binding?

I am having the following code which creates a chart with three series, first series being column bar, second and third line. The chart is being created when there is data returned from the sqlcommand but it should atleast display x and y axis when there are no rows returned.
C# Code:
string DatabaseConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["AVISConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(DatabaseConnectionString);
conn.Open();
DataTable dtSr = new DataTable();
SqlCommand cmd = null;
SqlDataReader reader = null;
cmd = new SqlCommand("Select case when KWmittel is null then '0' else KWmittel end as [KWmittel], case when YTD is null then '0' else YTD end as [YTD], case when soll is null then '0' else soll end as [soll] from dbo.Ausbringung_Wiegen_2013 a inner join dbo.ytd y on a.weekID = y.weekID inner join dbo.sollno s on y.weekID = s.weekID where a.weekID < datepart(week,getdate())", conn);
reader = cmd.ExecuteReader();
if (!reader.Read())
{
//I don't know how to handle here, I just gave a try but doesn't work
Chart4.ChartAreas["Chartarea1"].AxisX.Minimum = 0;
Chart4.ChartAreas["Chartarea1"].AxisY.Minimum = 0;
Chart4.Series["s1"].YValueMembers = null;
Chart4.Series["s2"].YValueMembers = null;
Chart4.Series["s3"].YValueMembers = null;
}
dtSr.Load(reader);
Chart4.DataSource = dtSr;
Chart4.Series["s1"].YValueMembers = "KWmittel";
Chart4.Series["s2"].YValueMembers = "YTD";
Chart4.Series["s3"].YValueMembers = "soll";
Chart4.DataBind();
cmd = null;
dtSr.Clear();
I would really appreciate any help, ideas. Thank you :)
I found the answer myself somehow for this question, the code is as follows:
dtSr.Load(reader);
if(dtSr.Columns==null)
{
for (int i = 0; i < seriesa.Length; i++)
{
Chart3.Series[seriesa[i]].Points.AddY(0);
}
}
else
{
Chart3.DataSource = dtSr;
Chart3.Series["s2"].YValueMembers = "YTD";
Chart3.Series["s3"].YValueMembers = "soll";
Chart3.Series["s1"].YValueMembers = "KW_Mittel";
Chart3.DataManipulator.InsertEmptyPoints(1, System.Web.UI.DataVisualization.Charting.IntervalType.Number, Chart3.Series["s3"]);
Chart3.DataManipulator.InsertEmptyPoints(1, System.Web.UI.DataVisualization.Charting.IntervalType.Number, Chart3.Series["s2"]);
Chart3.Series["s3"].EmptyPointStyle.Color = System.Drawing.Color.Transparent;
Chart3.Series["s2"].EmptyPointStyle.Color = System.Drawing.Color.DarkGreen;
Chart3.Series["s2"].BorderWidth = 2;
Chart3.DataBind();
}

Webservice method that returns objects of struct

I have a webservice with two methods 1 that returns a struct with two arrays:
public struct GetWeatherItemDataStruct
{
//public DateTime[] TimeStamp;
public double[] Value;
public string[] TimeStamp;
}
[WebMethod]
public GetWeatherItemDataStruct GetWeatherItemData(string parameterName,string fromTime,string toTime)
{
GetWeatherItemDataStruct gwiDataStructObj = new GetWeatherItemDataStruct();
SqlConnection conn = null;
SqlDataReader rdr = null;
int prameterID = GetParameterID(parameterName);
int tblSize = GetTableSize(parameterName, fromTime, toTime, prameterID);
double[] result = new double[tblSize];
int i = 0;
string[] tStamp = new string[tblSize];
String source = "Data Source=MASTER-PC\\SQLEXPRESS;Initial Catalog=WeatherDatabase;Integrated Security=True";
try
{
using (conn = new SqlConnection(source))// create and open a connection object
{
// 1. create a command object identifying
// the stored procedure
SqlCommand cmd = new SqlCommand("GetWeatherItemData", conn);
// 2. set the command object so it knows
// to execute a stored procedure
cmd.CommandType = CommandType.StoredProcedure;
// 3. add parameter to command, which
// will be passed to the stored procedure
//cmd.Parameters.Add(new SqlParameter("#WeatherParameterID", "1"));
cmd.Parameters.Add("#WeatherParameter", SqlDbType.VarChar).Value = parameterName;
cmd.Parameters.Add("#FromTimeStamp", SqlDbType.VarChar).Value = fromTime;
cmd.Parameters.Add("#ToTimeStamp", SqlDbType.VarChar).Value = toTime;
conn.Open();
// execute the command
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
result[i] = (double)rdr["MeasurementValue"];
tStamp[i] = rdr["Recieved"].ToString();
i++;
}
gwiDataStructObj.Value = result;
gwiDataStructObj.TimeStamp = tStamp;
int b = gwiDataStructObj.Value.Length;
}
}
catch (SqlException e)
{
//Log exception
//Display Error message
}
return gwiDataStructObj;
}
[WebMethod]
public int[] stringTest(string[] tString)
{
int numberOfStrings = tString.Length;
int[] returnS = new int[numberOfStrings];
for (int i = 0; i <= numberOfStrings; i++)
{
returnS[i] = 1;
}
return returnS;
}
On the Client program i can read from the struct tabels as following:
string dtFrom = "2012-10-04 19:05:57:190";
string dtTo = "2012-10-05 21:50:05:197";
double[] paramValue;
string[] timeStamp;
var client = new WebServiceSample.WebService1SoapClient();
paramValue = client.GetWeatherItemData(paramName, dtFrom, dtTo).Value.ToArray();
timeStamp = client.GetWeatherItemData(paramName, dtFrom, dtTo).TimeStamp.ToArray();
This seems to work fine. But i have annother method that returns an array of the same struct:
public struct GetWeatherItemDataStruct
{
//public DateTime[] TimeStamp;
public double[] Value;
public string[] TimeStamp;
}
[WebMethod]
public GetWeatherItemDataStruct[] GetSelectedWeatherItemsData(string[] parameterName, string fromTime, string toTime)
{
int numbeOfParameters = parameterName.Length;
GetWeatherItemDataStruct[] getSelectedItemsStructObj = new GetWeatherItemDataStruct[numbeOfParameters];
SqlConnection conn = null;
SqlDataReader rdr = null;
int prameterID = 0;
int tblSize = 0;
double[] result;
int i = 0;
int counter = 0;
for (counter = 0; counter < numbeOfParameters; numbeOfParameters++)
{
prameterID = GetParameterID(parameterName[counter]);
tblSize = GetTableSize(parameterName[counter], fromTime, toTime, prameterID);
result = new double[tblSize];
string[] tStamp = new string[tblSize];
String source = "Data Source=MASTER-PC\\SQLEXPRESS;Initial Catalog=WeatherDatabase;Integrated Security=True";
try
{
using (conn = new SqlConnection(source))// create and open a connection object
{
// 1. create a command object identifying
// the stored procedure
SqlCommand cmd = new SqlCommand("GetWeatherItemData", conn);
// 2. set the command object so it knows
// to execute a stored procedure
cmd.CommandType = CommandType.StoredProcedure;
// 3. add parameter to command, which
// will be passed to the stored procedure
//cmd.Parameters.Add(new SqlParameter("#WeatherParameterID", "1"));
cmd.Parameters.Add("#WeatherParameter", SqlDbType.VarChar).Value = parameterName;
cmd.Parameters.Add("#FromTimeStamp", SqlDbType.VarChar).Value = fromTime;
cmd.Parameters.Add("#ToTimeStamp", SqlDbType.VarChar).Value = toTime;
conn.Open();
// execute the command
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
result[i] = (double)rdr["MeasurementValue"];
tStamp[i] = rdr["Recieved"].ToString();
i++;
}
getSelectedItemsStructObj[counter].Value = result;
getSelectedItemsStructObj[counter].TimeStamp = tStamp;
}
}
catch (SqlException e)
{
//Log exception
//Display Error message
}
}
return getSelectedItemsStructObj;
}
Here im stuck. How do i read the tables for each object?
Based on the comments above.
To get data from a struct inside an array, you retrieve it just like you were setting it.
myArrayOfStruct[0].myStructProperty
If it's an array IN the struct, it's just:
myArrayOfStruct[0].myArrayProperty[0]
If you wanted to loop through all structures in the array and all of the items in an array property, you'd next two loops:
for (int i = 0; i < myArrayOfStruct.length; i++){
for (int j = 0; j < myArrayProperty.length; j++){
myData = myArrayOfStruct[i].myArrayProperty[j];
// do something with the data
}
}
Basically, myArrayOfStruct[0].myProperty is the same as accessing it like this:
MyStruct myStruct = myArrayOfStruct[0];
myStruct.myProperty
Does this answer your question? You set it correctly above. You retrieve it in a similar fashion.

Categories

Resources