API Support Forum
OEC API > Advanced Order Management > Requesting Historic data from a contract with RequestHistory
Author Topic: Requesting Historic data from a contract with RequestHistory
(6 messages, Page 1 of 1)
Moderators: VPfau
CWest88
Posts: 3
Joined: Oct 03, 2007


Posted: Oct 03, 2007 @ 10:48 AM             Msg. 1 of 6
We are working on an app which will display current ticks for a Future Contract, as well as historic data. We are already displaying current prices an volumes, but we are trying to get historic data by using the RequestHistory function.

As stated in documentation we are sending the right values:
public Subscription RequestHistory(
Contract contract,
DateTime StartDate,
DateTime EndDate
);
Parameters
contract
Contract to request bars
StartDate
Start of time range
EndDate
End of time range



But we are getting values without timestamp for each bar.

IE: if we send this:

Contract: ESZ7
StartDate: 2007-09-27
EndDate: 2007-09-28
StartTime: 16:30
EndTime: 16:15
(because we want to know the bars for the 09/27/2007 journal for ESZ7)

After sending those values we are getting these:

<Bar>
<High>1545</High>
<Low>1542.25</Low>
<Open>1544</Open>
<Volume>0</Volume>
<Timestamp>9/27/2007 12:00:00 AM</Timestamp>
<Close>1544.5</Close>
</Bar>
<Bar>
<High>1545.5</High>
<Low>1533</Low>
<Open>1544</Open>
<Volume>1456085</Volume>
<Timestamp>9/28/2007 12:00:00 AM</Timestamp>
<Close>1538</Close>
</Bar>


So, how do we know the timestamp for the highest, lowest, open and close values?

What are we doing wrong?

Thank you
SergeK
-Developer-
Posts: 475
Joined: Jan 26, 2007


Posted: Oct 03, 2007 @ 02:43 PM             Msg. 2 of 6
RequestHistory is intended for daily bars - so timestamp fiels contrains only date information. Please use RequestBars for intraday bars, and RequestTicks for tick data.
CWest88
Posts: 3
Joined: Oct 03, 2007


Posted: Oct 12, 2007 @ 01:10 PM             Msg. 3 of 6
Well, i did what you told me to do.
Below is the call I make to retrieve the bars and the method that handles the event when the bars are received.

Below is the event registration

TimeSpan interval = contract.EndDate.Subtract(contract.BeginDate);
theClient.RequestBars(theClient.Contracts[contract.Symbol], contract.BeginDate, contract.EndDate, interval);


Below is the code that handles the bars once they are received


void theClient_OnBarsReceived(Subscription Subscription, Bar[] Bars) {
StringBuilder sb = new StringBuilder(); sb.Append("<RequestHistory>");
sb.Append("<Symbol>" + Subscription.Contract.Symbol + "</Symbol>");
foreach (Bar bar in Bars) {
sb.Append("<Bar>");
sb.Append("<High>" + bar.High.ToString() + "</High>"); sb.Append("<Low>" + bar.Low.ToString() + "</Low>"); sb.Append("<Open>" + bar.Open.ToString() + "</Open>"); sb.Append("<Volume>" + bar.Volume.ToString() + "</Volume>");
sb.Append("<Timestamp>" + bar.Timestamp.ToString() + "</Timestamp>");
sb.Append("<Close>" + bar.Close.ToString() + "</Close>"); sb.Append("</Bar>");
}
sb.Append("</RequestHistory>");
SendPost(sb.ToString(), System.Configuration.ConfigurationSettings.AppSettings["HISTORYQUOTEURL"]);
}



What I am returning comprises all of the bars that oec is returning to me.

This is an example of current returning:


<?xml version="1.0" encoding="utf-8"?>
<RequestHistory>
<Symbol>ESZ7</Symbol>
<Bar>
<High>1576</High>
<Low>1565,25</Low>
<Open>1574,25</Open>
<Volume>1300151</Volume>
<Timestamp>10/10/2007 12:45:00 a.m.</Timestamp>
<Close>1574</Close>
</Bar>
<Bar>
<High>1584,25</High>
<Low>1573,25</Low>
<Open>1574,25</Open>
<Volume>586344</Volume>
<Timestamp>11/10/2007 12:30:00 a.m.</Timestamp>
<Close>1579,75</Close>
</Bar>
</RequestHistory>



But what I want is to get timestamps and values for each bar (open, close, high, low) on a given date (ie: previous session).

as this:


<?xml version="1.0" encoding="utf-8"?>
<RequestHistory>
<Symbol>ESZ7</Symbol>
<Volume>1300151</Volume>
<Bar>
<High>1576</High>
<Timestamp>xx/xx/xxxx xx:xx:xx x.x.</Timestamp>
</Bar>
<Bar> <Low>1573,25</Low>
<Timestamp>xx/xx/xxxx xx:xx:xx x.x.</Timestamp>
</Bar>
<Bar>
<Open>1574,25</Open>
<Timestamp> xx/xx/xxxx xx:xx:xx x.x.</Timestamp>
</Bar>
<Bar>
<Close>1575,25</Close>
<Timestamp>xx/xx/xxxx xx:xx:xx x.x.</Timestamp>
</Bar>
</RequestHistory>


Is this possible? I will appreciate so much if someone could give any clue or sample code on how to do that because currently I'm stuck on this part.

Thank you in advance.

Cordially,

Chris West.

--------------------------------------------------------------

PS: here is the complete code of our little app (don't get mad with me pls):



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Reflection;
using OEC.API;
using System.Net;
using System.IO;
using System.Xml;

namespace Quoter
{
public partial class Form1 : Form
{

struct XMLContract
{
public string Symbol;
public bool ShowBars;
public DateTime BeginDate;
public DateTime EndDate;
}



Timer Clock;
public int count = 0;
OEC.API.OECClient theClient;
public Form1()
{
InitializeComponent();
theClient = new OEC.API.OECClient();
this.theClient.EventBatchInterval = 0;
this.theClient.OnAccountSummaryChanged += new OEC.API.OnAccountSummaryChangedEvent(theClient_OnAccountSummaryChanged);
this.theClient.OnOrderFilled += new OEC.API.OnOrderFilledEvent(theClient_OnOrderFilled);
this.theClient.OnCommandUpdated += new OEC.API.OnCommandUpdatedEvent(theClient_OnCommandUpdated);
this.theClient.OnLoginComplete += new OEC.API.OnLoginCompleteEvent(theClient_OnLoginComplete);
this.theClient.OnAvgPositionChanged += new OEC.API.OnPositionChangedEvent(theClient_OnAvgPositionChanged);
this.theClient.OnDisconnected += new OEC.API.OnDisconnectedEvent(theClient_OnDisconnected);
this.theClient.OnOrderConfirmed += new OEC.API.OnOrderConfirmedEvent(theClient_OnOrderConfirmed);
this.theClient.OnLoginFailed += new OEC.API.OnLoginFailedEvent(theClient_OnLoginFailed);
this.theClient.OnOrderStateChanged += new OEC.API.OnOrderStateChangedEvent(theClient_OnOrderStateChanged);
this.theClient.OnPriceChanged += new OEC.API.OnPriceChangedEvent(theClient_OnPriceChanged);
this.theClient.OnBalanceChanged += new OEC.API.OnBalanceChangedEvent(theClient_OnBalanceChanged);
this.theClient.OnHistoryReceived += new OnHistoryReceivedEvent(theClient_OnHistoryReceived);
this.theClient.OnBarsReceived += new OnBarsReceivedEvent(theClient_OnBarsReceived);
this.theClient.OnTicksReceived += new OnTicksReceivedEvent(theClient_OnTicksReceived);
login();

}

void theClient_OnTicksReceived(Subscription Subscription, Ticks Ticks)
{

MessageBox.Show(Ticks.Prices.LongLength.ToString());
}

void theClient_OnBarsReceived(Subscription Subscription, Bar[] Bars)
{
StringBuilder sb = new StringBuilder();
sb.Append("<RequestHistory>");
sb.Append("<Symbol>" + Subscription.Contract.Symbol + "</Symbol>");
foreach (Bar bar in Bars)
{
sb.Append("<Bar>");
sb.Append("<High>" + bar.High.ToString() + "</High>");
sb.Append("<Low>" + bar.Low.ToString() + "</Low>");
sb.Append("<Open>" + bar.Open.ToString() + "</Open>");
sb.Append("<Volume>" + bar.Volume.ToString() + "</Volume>");
sb.Append("<Timestamp>" + bar.Timestamp.ToString() + "</Timestamp>");
sb.Append("<Close>" + bar.Close.ToString() + "</Close>");
sb.Append("</Bar>");
}
sb.Append("</RequestHistory>");
SendPost(sb.ToString(), System.Configuration.ConfigurationSettings.AppSettings["HISTORYQUOTEURL"]);

}

void theClient_OnHistoryReceived(Subscription Subscription, Bar[] Bars)
{
StringBuilder sb = new StringBuilder();
sb.Append("<RequestHistory>");
sb.Append("<Symbol>" + Subscription.Contract.Symbol + "</Symbol>");
foreach (Bar bar in Bars)
{
sb.Append("<Bar>");
sb.Append("<High>" + bar.High.ToString() + "</High>");
sb.Append("<Low>" + bar.Low.ToString() + "</Low>");
sb.Append("<Open>" + bar.Open.ToString() + "</Open>");
sb.Append("<Volume>" + bar.Volume.ToString() + "</Volume>");
sb.Append("<Timestamp>" + bar.Timestamp.ToString() + "</Timestamp>");
sb.Append("<StartTime>" + Subscription.Start.ToString() + "</StartTime>");
sb.Append("<EndTime>" + Subscription.Start.Add(Subscription.Interval).ToString() + "</EndTime>");
sb.Append("<Close>" + bar.Close.ToString() + "</Close>");
sb.Append("</Bar>");
}
sb.Append("</RequestHistory>");
SendPost(sb.ToString(), System.Configuration.ConfigurationSettings.AppSettings["HISTORYQUOTEURL"]);

}

void theClient_OnBalanceChanged(OEC.API.Account Account, OEC.API.Currency Currency)
{
//throw new Exception("The method or operation is not implemented.");
}

void theClient_OnPriceChanged(OEC.API.Contract Contract, OEC.API.Price Price)
{
UpdatePrice(Contract);
}

void UpdatePrice(OEC.API.Contract Contract)
{

string itemtext = string.Format("{0} Last {1}, Ask {2}, Bid {3} Time{4}",
Contract.Symbol,
Contract.PriceToString(Contract.CurrentPrice.LastPrice),
Contract.PriceToString(Contract.CurrentPrice.AskPrice),
Contract.PriceToString(Contract.CurrentPrice.BidPrice),
DateTime.Now.ToLongTimeString()
);

if (lstResults.Items.Count >= 25)
lstResults.Items.RemoveAt(24);

lstResults.Items.Insert(0,itemtext);

lstResults.Refresh();

SendPost(GetContractXml(Contract), System.Configuration.ConfigurationSettings.AppSettings["QUOTEURL"]);
}


void SendPost(string xml, string URL)
{

if (URL != "")
{
try
{
WebRequest req;
req = WebRequest.Create(URL);
req.Method = "POST";

byte[] bytes = Encoding.ASCII.GetBytes(xml);

req.Timeout = -1;
req.ContentType = "text/xml";
req.ContentLength = bytes.Length;

Stream dataStream = req.GetRequestStream();
dataStream.Write(bytes, 0, bytes.Length);
dataStream.Close();

WebResponse response = req.GetResponse();
Stream responseStream = response.GetResponseStream();

StreamReader reader = new StreamReader(responseStream);
this.txtResponse.Text = reader.ReadToEnd();
this.txtResponse.Refresh();

this.txtXml.Text = xml;

response.Close();
this.txtXml.Refresh();
count++;
this.lblCount.Text = count.ToString();
this.lblCount.Refresh();
}
catch (Exception Ex)
{
this.txtXml.Text = Ex.Message;
}
}

}

void theClient_OnOrderStateChanged(OEC.API.Order Order, OEC.Data.OrderState OldOrderState)
{
//throw new Exception("The method or operation is not implemented.");
}

void theClient_OnLoginFailed(OEC.Data.FailReason Reason)
{
PostError("Error Connecting" + Reason.ToString());
}

void theClient_OnOrderConfirmed(OEC.API.Order Order, int OldOrderID)
{
//throw new Exception("The method or operation is not implemented.");
}

void theClient_OnDisconnected(bool Unexpected)
{
Clock.Stop();
lblMessages.Text = "Disconnected";
SendPost(GetInformationMessageXml(lblMessages.Text), System.Configuration.ConfigurationSettings.AppSettings["INFORURL"]);
lblMessages.Refresh();
}

void theClient_OnAvgPositionChanged(OEC.API.Account Account, OEC.API.Position ContractPosition)
{
//throw new Exception("The method or operation is not implemented.");
}

List<XMLContract> GetSymbols(string URL)
{
List<XMLContract> returnCollection = new List<XMLContract>();
if (URL != "")
{
try
{
WebRequest req;
req = WebRequest.Create(URL);
req.Method = "Get";
req.Timeout = -1;
req.ContentType = "text/xml";


WebResponse response = req.GetResponse();
Stream responseStream = response.GetResponseStream();

StreamReader reader = new StreamReader(responseStream);
string ResponseText = reader.ReadToEnd();

System.Xml.XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(ResponseText);

XmlNodeList nodelist = xdoc.SelectNodes("/entries/entry");
foreach (XmlNode node in nodelist)
{
XMLContract xmlcontract = new XMLContract();
xmlcontract.Symbol = node["future_exchangesymbol"].InnerText;
if (node["ShowBars"] != null)
{
if (node["ShowBars"].InnerText == "True")
{
xmlcontract.ShowBars = true;
xmlcontract.BeginDate = DateTime.Parse(node["StartTime"].InnerText + " " + node["StartDate"].InnerText);
xmlcontract.EndDate = DateTime.Parse(node["EndTime"].InnerText + " " + node["EndDate"].InnerText);
}
}
else
xmlcontract.ShowBars = false;

returnCollection.Add(xmlcontract);
}


}
catch (Exception Ex)
{
this.txtXml.Text = Ex.Message;
}
}

return returnCollection;

}


bool isAlreadySubscribed(string symbol)
{
List<Contract> subcontracts = new List<Contract>();

foreach (Subscription subscription in theClient.Subscriptions)
subcontracts.Add(subscription.Contract);

foreach (Contract contract in subcontracts)
{
if (contract.Symbol == symbol)
return true;
}

return false;

}

bool SymbolFound(string symbol, List<XMLContract> newContracts)
{
foreach (XMLContract tmpsymbol in newContracts)
{
if (symbol == tmpsymbol.Symbol)
return true;
}
return false;

}


void SubscriptionUpdates()
{

List<XMLContract> newContracts = GetSymbols(System.Configuration.ConfigurationSettings.AppSettings["SYMBOLURL"]);

//Add only the new contracts that are not already subscribed to
foreach (XMLContract contract in newContracts)
{
if (isAlreadySubscribed(contract.Symbol))
{
//Do nothing
}
else
{
AddContract(contract.Symbol);
}

if (contract.ShowBars)
{

TimeSpan interval = contract.EndDate.Subtract(contract.BeginDate);
theClient.RequestBars(theClient.Contracts[contract.Symbol], contract.BeginDate, contract.EndDate, interval);

//theClient.RequestTicks(theClient.Contracts[contract.Symbol], contract.BeginDate, contract.EndDate);

//theClient.RequestHistory(theClient.Contracts[contract.Symbol], contract.BeginDate, contract.EndDate);
}
}

List<Contract> subcontracts = new List<Contract>();

//Unsubscribe subscriptions that are not found in the symbol new symbol list
foreach (Subscription subscription in theClient.Subscriptions)
subcontracts.Add(subscription.Contract);

foreach (Contract contract in subcontracts)
{
if(!SymbolFound(contract.Symbol,newContracts)){
theClient.Unsubscribe(contract);
theClient.UnsubscribeDOM(contract);
lblMessages.Text = contract.Symbol + " Removed";
SendPost(GetInformationMessageXml(lblMessages.Text), System.Configuration.ConfigurationSettings.AppSettings["INFORURL"]);
lblMessages.Refresh();
}
}
}

void AddContract(string ContractName)
{
if (theClient.Contracts[ContractName] != null)
{
theClient.Subscribe(theClient.Contracts[ContractName]);
lblMessages.Text = ContractName + "Added";
SendPost(GetInformationMessageXml(lblMessages.Text), System.Configuration.ConfigurationSettings.AppSettings["INFORURL"]);
lblMessages.Refresh();
}
else
PostError("Invalid Contract " + ContractName);
}

void theClient_OnLoginComplete()
{
Clock = new Timer();
Clock.Interval = int.Parse(System.Configuration.ConfigurationSettings.AppSettings["REGISTRATIONINTERVAL"]);
Clock.Start();
Clock.Tick += new EventHandler(Clock_Tick);

SubscriptionUpdates();
}

void Clock_Tick(object sender, EventArgs e)
{
if (sender == Clock)
{
SubscriptionUpdates();
}

}

void theClient_OnCommandUpdated(OEC.API.Order Order, OEC.API.Command Command)
{
//throw new Exception("The method or operation is not implemented.");
}

void theClient_OnOrderFilled(OEC.API.Order Order, OEC.API.Fill Fill)
{
//throw new Exception("The method or operation is not implemented.");
}

void theClient_OnAccountSummaryChanged(OEC.API.Account Account, OEC.API.Currency Currency)
{
//throw new Exception("The method or operation is not implemented.");
}

protected void login()
{


try
{
count = 0;
theClient.Connect("api.openecry.com", 9200, System.Configuration.ConfigurationSettings.AppSettings["UID"], System.Configuration.ConfigurationSettings.AppSettings["PWD"], false);
}
catch (Exception ex)
{
PostError("Connect failed: " + ex.Message);
}

}


private void btnStart_Click(object sender, EventArgs e)
{


}

private void btnStop_Click(object sender, EventArgs e)
{
theClient.Disconnect();
lblMessages.Text = "Disconnected";
SendPost(GetInformationMessageXml(lblMessages.Text), System.Configuration.ConfigurationSettings.AppSettings["INFORURL"]);
lblMessages.Refresh();
}

protected void PostError(string ErrorMessage)
{
lblMessages.Text = ErrorMessage;
lblMessages.Refresh();
SendPost(GetErrorXml(ErrorMessage),System.Configuration.ConfigurationSettings.AppSettings["ERRORURL"]);
}

protected string GetInformationMessageXml(string ErrorMSG)
{

StringBuilder sb = new StringBuilder();
sb.Append("<Info>");
sb.Append("<TimeStamp>" + DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString() + "</TimeStamp>");
sb.Append("<Message>" + ErrorMSG + "</Message>");
sb.Append("</Info>");
return sb.ToString();
}

protected string GetErrorXml(string ErrorMSG)
{

StringBuilder sb = new StringBuilder();
sb.Append("<Error>");
sb.Append("<TimeStamp>" + DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString() + "</TimeStamp>");
sb.Append("<Message>" + ErrorMSG + "</Message>");
sb.Append("</Error>");
return sb.ToString();
}


protected string GetContractXml(Contract contract)
{

StringBuilder sb = new StringBuilder();
sb.Append("<Contract>");
sb.Append("<TimeStamp>" +DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString() + "</TimeStamp>");
sb.Append("<Symbol>" + contract.Symbol + "</Symbol>");
sb.Append("<LastPrice>" + contract.PriceToString(contract.CurrentPrice.LastPrice) + "</LastPrice>");
sb.Append("<AskPrice>" + contract.PriceToString(contract.CurrentPrice.AskPrice) + "</AskPrice>");
sb.Append("<BidPrice>" + contract.PriceToString(contract.CurrentPrice.BidPrice) + "</BidPrice>");
sb.Append("</Contract>");
return sb.ToString();

}

private void Form1_Load(object sender, EventArgs e)
{

}

private void lbPrice_Click(object sender, EventArgs e)
{

}


}
}


Edited by CWest88 on Oct 12, 2007 at 01:11 PM
Edited by CWest88 on Oct 12, 2007 at 01:12 PM
SergeK
-Developer-
Posts: 475
Joined: Jan 26, 2007


Posted: Oct 12, 2007 @ 01:28 PM             Msg. 4 of 6
I'm not quite sure I understand what are you trying to achieve with the code:

"TimeSpan interval = contract.EndDate.Subtract(contract.BeginDate);"

The interval parameter in the RequestBars method is the length of intraday bars - like 1 minute, or 5 minutes, or 1 hour.

if you are looking for daily data, one bar per day, please use RequestHistory method.

(note that daily data currently could be not available for selected contracts)
CWest88
Posts: 3
Joined: Oct 03, 2007


Posted: Oct 12, 2007 @ 03:54 PM             Msg. 5 of 6
That is what we were doing previous you told us to change it to RequestBars.

What we want here is to get prices and timestamps for each high, low, open and close bars on an specific trading session date.

How could we do this?

Thank you so much in advance.
SergeK
-Developer-
Posts: 475
Joined: Jan 26, 2007


Posted: Oct 12, 2007 @ 04:20 PM             Msg. 6 of 6
it seems to me that we are talking about totally different concepts.

for us, the bar is a record of <timestamp, open, high, low, close, volume> values.

bar represent trades made for a given period, where open is a first trade price, high is max(price), low is min(price), close is the latest price and volume is sum of tick volumes.
for intraday bars timestamp is the time of bar beggining - i.e hourly bar with timestamp 10/11/2007 08:00 will aggregate ticks from 08:00 to 09:00.

a daily bar for a specific date will have timestamp with only date part set to a business day(10/11/2007 12:00 am), and daily OHLCV values are accumulated from session open to session close.

there is no specific timestamps per each of OHLC values, and no separate high, low, open and close bars in our system.