API Support Forum
OEC API > Market Data > When is current price available?
Author Topic: When is current price available?
(3 messages, Page 1 of 1)
Moderators: VPfau
PDavies541
Posts: 21
Joined: Feb 01, 2013


Posted: May 22, 2013 @ 02:25 PM             Msg. 1 of 3
Hi

I have been working on a project that re-used some code sent to me by your team which has been a great help.

There is one problem that I can't seem to get around. Here is what I effectively need to do:

1 - Invoke a DLL from an OEC chart
2 - When I invoke the DLL, I send the last, high and low price of the session - that is one time at startup
3 -When the underlying instrument on the chart changes, I kill my DLL and invoke it again
4 - If the market is on line I send the current session values. When the market is off line, I send the closing price of the last session in the last, high and low.

So - all this is working really well with the exception of one case. If I switch the indicator from YMM3, NQM3, ESM3, it works fine. If I try to switch to YMZ3, YMH4 - contracts that are not currently subscribed then it crashes when I try to access LastPrice, HighPrice or LowPrice.

When it crashes, I can re-compile the indicator and this time it will work for the symbol it crashed on.

I am subscribing to the contract but it seems that OEC is subscribing to certain commonly known contracts (current month for US stock indices, grains) on startup as they work. As soon as I try to load a contract a little further out or a slightly more exotic contract, it fails.

I reproduced this issue with a small change to the domindicator.cs you send me - which is here:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using OEC.UI;
using OEC.Chart;
using OEC.Chart.Indicators;
using OEC.Chart.Details;
using OEC.Chart.BaseSeries;
using OEC.EL.Runtime;
using System.Runtime.InteropServices;
using System.Drawing.Drawing2D;

namespace OEC.Chart.Custom.Sandbox
{

[TimeSeries("DomSample", "DomSample", "My Indicators", AreaScale.Any, SourceScale=AreaScale.Price)]
public sealed class DomSample : OEC.Chart.Custom.CustomIndicator
{
[XmlSerializable, Category("Data")]
public int Window = 15;

int SymbolLookupID = -1;
API.Contract ContractDOM = null;
string MonitoringSymbol = null;
bool Initialized = false;
bool first = true;

void InitializeAPI()
{
Print("Init API");
if (!IsCloned)
{
if (!Initialized)
{
Initialized = true;
OEC.API.OECClient.Global.OnLoginComplete += OnLoginComplete;
OEC.API.OECClient.Global.OnDisconnected += OnDisconnected;
OEC.API.OECClient.Global.OnSymbolLookupReceived += OnSymbolLookupReceived;
SubscribeDOM();
}
else
{
if (MonitoringSymbol != this.ContractInfo.Symbol)
{
UnsubscribeDOM();
SubscribeDOM();
}
}
}
try
{
Print(ContractDOM.CurrentPrice.LastPrice + " : " + ContractDOM.CurrentPrice.HighPrice + " : " + ContractDOM.CurrentPrice.LowPrice);
}
catch (Exception e)
{
Print("Print in Init Failed " + e.ToString());
}
}

void SubscribeDOM()
{
Print("Subscribe DOM");
if(MonitoringSymbol == null)
{
MonitoringSymbol = this.ContractInfo.Symbol;
Print("DOM Initializing");
if(OEC.API.OECClient.Global.CompleteConnected)
SymbolLookupID = OEC.API.OECClient.Global.SymbolLookup(MonitoringSymbol).ID;
}
}

void OnLoginComplete()
{
Print("OnLoginComplete");
ContractDOM = null;
MonitoringSymbol = null;
SubscribeDOM();
}

void OnDisconnected(bool unexpected)
{
Print("Disconnect");
UnsubscribeDOM();
}

void OnSymbolLookupReceived(API.SymbolLookupCriteria symbolLookup, API.ContractList contracts)
{
Print("OnSymbolLookupReceived");
if(symbolLookup.ID == SymbolLookupID)
{
if(contracts.Count == 1)
{
ContractDOM = contracts.First;
first = true;
OEC.API.OECClient.Global.OnDOMChanged += OnDOMChanged;
OEC.API.OECClient.Global.SubscribeDOM(ContractDOM);
OEC.API.OECClient.Global.Subscribe(ContractDOM);
Print("DOM subscribed");
try
{
Print(ContractDOM.CurrentPrice.LastPrice + " : " + ContractDOM.CurrentPrice.HighPrice + " : " + ContractDOM.CurrentPrice.LowPrice);
}
catch (Exception e)
{
Print("Print in OSE Failed " + e.ToString());
}
}
else
{
Print("DOM subscribing failed: symbol not found");
}
}
}

void FinalizeAPI()
{
Print("Finalize API");
if (Initialized)
{
OEC.API.OECClient.Global.OnSymbolLookupReceived -= OnSymbolLookupReceived;
OEC.API.OECClient.Global.OnLoginComplete -= OnLoginComplete;
OEC.API.OECClient.Global.OnDisconnected -= OnDisconnected;
UnsubscribeDOM();
}
}

void UnsubscribeDOM()
{
Print("unsubscribe");
MonitoringSymbol = null;
SymbolLookupID = -1;
if(ContractDOM != null)
{
OEC.API.OECClient.Global.OnDOMChanged -= OnDOMChanged;
OEC.API.OECClient.Global.UnsubscribeDOM(ContractDOM);
OEC.API.OECClient.Global.Subscribe(ContractDOM);
ContractDOM = null;
Print("DOM Unsubscribed.");
}
}

void OnDOMChanged(OEC.API.Contract contract)
{
if(contract == ContractDOM && first == true)
{
first = false;
Print("DOM Changed: " + contract.DOM.AskLevels.Length);
}
}

protected override void Calculate()
{
Result.Value = SMA(Close,15);
if (this.LastBarOnChart == true)
{
Print("Last Bar");
}
}

protected override void Refresh(DataChangedMode mode)
{
if(mode == DataChangedMode.Insert)
InitializeAPI();
base.Refresh(mode);
}

public override void Delete()
{
Print("Delete");
FinalizeAPI();
base.Delete();
}

protected override DataSeries[] DefaultSubseries
{
get
{
return new DataSeries[]{
new DataSeries(this, "Value", new ChartStyle(SeriesChartType.Line,System.Drawing.Color.Red,1,DashStyle.Solid))

};
}
}

protected Series ValueSeries
{
get
{
return RArray[0];
}
}

}
}


Try running this & start changing to future contracts on NQ, YM, ES and you will see it starts outputting "Print in OSE Failed" messages in the log.

You can see the code in the OnSymbolLookupReceived. It is almost as if I need to force it to load the contract data properly for those future month contracts but current month contracts work fine.

Any thoughts?

Thanks

Pete

Peter Davies
VictorV
Posts: 746
Joined: May 08, 2007


Posted: May 29, 2013 @ 09:08 AM             Msg. 2 of 3
Hello,

Requests to servers are asynchronous in OECAPI: it doesn't guarantee that ContractDOM.CurrentPrice will be defined on the next line after calling OEC.API.OECClient.Global.Subscribe method. If you need to monitor real-time quotes, it is better to hook OnPriceChanged or OnPriceTick events (http://www.openecry.com/api/api/html/4e2865e8-7ac9-457e-8d5a-6d930f3408a8.htm).

Victor Vins
Lead Software Developer
PDavies541
Posts: 21
Joined: Feb 01, 2013


Posted: May 29, 2013 @ 10:33 PM             Msg. 3 of 3
OK - got it, many thanks!

Peter Davies