Join the 80,000 other DTN customers who enjoy the fastest, most reliable data available. There is no better value than DTN!

(Move your cursor to this area to pause scrolling)




"I just wanted to let you know how fast and easy I found it to integrate IQFeed into our existing Java code using your JNI client. In my experience, such things almost never go so smoothly - great job!" - Comment from Nate
"I was with ******* for 4 years at $230 a month, this is a huge savings for me, GOD BLESS YOU PEOPLE," - Comment from T.S. via Email
"I like you guys better than *******...much more stable and a whole lot fewer issues." - Comment from Philip
"DTN has never given me problems. It is incredibly stable. In fact I've occasionally lost the data feed from Interactive Brokers, but still been able to trade because I'm getting good data from DTN." - Comment from Leighton
"Thanks for following up with me. You guys do a great job in tech support." - Comment from Phelps
"You have an excellent product !!!!!!" - Comment from Arely
"Boy, probably spent a thousand hours trying to get ******* API to work right. And now two hours to have something running with IQFeed. Hmmm, guess I was pretty stupid to fight rather than switch all this time. And have gotten more customer service from you guys already than total from them… in five years." - Comment from Jim
"I have been using IQFeed now for a few years in MultiCharts and I have zero complaints. Very, very rare to have any data hiccups or anything at all go wrong." - Comment from Public Forum
"I would just like to say that IQFeed version 4 is running very well and I am very happy with its performance. I would also like to extend a big thanks for the fast and efficient help that I always receive. My questions and concerns are always addressed promptly. Way to go!" - Comment from Josh in CO.
"This is an excellent value, the system is generous (allowing for 500 stocks) and stable (and really is tick-by-tick), and the support is fantastic." - Comment from Shirin via Email
Home  Search  Register  Login  Recent Posts

Information on DTN's Industries:
DTN Oil & Gas | DTN Trading | DTN Agriculture | DTN Weather
Follow DTNMarkets on Twitter
DTN.IQ/IQFeed on Twitter
DTN News and Analysis on Twitter
Viewing User Profile for: Dennis
About Contact
Joined: Oct 8, 2004 10:25 AM
Last Post: Jan 13, 2005 09:21 AM
Last Visit: Jun 20, 2005 09:22 AM
Website:  
Location: Austin, TX
Occupation:
Interests:
AIM:
ICQ:
MSN IM:
Yahoo IM:
Post Statistics
Dennis has contributed to 19 posts out of 21185 total posts (0.09%) in 7,140 days (0.00 posts per day).

20 Most recent posts:
IQFeed Developer Support » A Stable .NET Build for both IQFeed and History Jan 13, 2005 09:21 AM (Total replies: 12)

Greg, thank you for your comments.

The only instability I have experienced during IQFeed testing has been directly related to accessing the feed and/or history via .NET. This is most likely due to the combination of managed and unmanaged code, and the lack of proper marshaling. To date, my most stable .NET solutions use the IQfeed ActiveX API and Interop (as described in this post). I have yet to build a "production worthy" feed/history solution using the "sockets" interface. It is my understanding that it can be done, but I have been unable to "crack that nut".

I have found the VC++ samples and testing to be very stable, and this would be my language of choice if I were not "hell bent" on developing all of my current work in .NET. Although I have successfully built and exercised the IQFeed API in the other languages/interfaces provided (VB, Java, DDE), my limited testing in these areas prevents me from commenting on their relative stability.

Regards,
Dennis Sanders


Kary,

Thanks for your post and comments. Any .NET insights you have would be greatly appreciated.

Dennis Sanders

IQFeed Developer Support » Useful Functions in IQ32.dll Dec 21, 2004 04:18 PM (Total replies: 2)

Thanks Glenn.

IQFeed Developer Support » Useful Functions in IQ32.dll Dec 21, 2004 03:02 PM (Total replies: 2)

The following functions are prototyped in iq32.h.

void SetAutoLogin (const char* szUserName, const char* szPassword);
void ClearAutoLogin ();
void SetCallbackFunction (CallbackType callback);
int RegisterClientApp (HWND hClient, char* szProductName, char* szProductKey, char* szProductVersion);
void RemoveClientApp (HWND hClient);
void RegisterSocketHandle (HWND connect, int client);
void RemoveSocketHandle ();
void WaitForMessageMux ();
void ReleaseMessageMux ();
void ErrorReport (DWORD code, _EXCEPTION_POINTERS* pexp);
short CxSet ();
short CxGet ();
short ConnectToRobbins ();
short CloseRobbins ();
short SendTradeToRobbins (char *TType, char *Price, char *Action, char *Qty, char *Symbol, char *Month, char *Year);

The IQFeed API documentation describes the first five functions.
Do the remaining functions provide any benefits (diagnostic or otherwise) for the IQFeed developer?

IQFeed Developer Support » A Stable .NET Build for both IQFeed and History Dec 20, 2004 03:06 PM (Total replies: 12)

Reporting IQFeed & History from .NET:

Here is a code dump of 'frmMain.cs' which will report both IQFeed and History from .NET . There are a couple of missing puzzle pieces yet to be discussed. You have to configure your project to open up a console window (it's not that hard really). And more importantly, you have to build 'DTNHISTORYLOOKUPLib' (Line 9) and add it to your references (this will prove to be easy, too). See if you can figure it out (post the answers if you like).

I will provide the answers and the details in my next post.

// Sample application to request level1 data and 1 min history

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using DTNHISTORYLOOKUPLib;

namespace CSharpLevel1Socket
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class frmMain : System.Windows.Forms.Form
{
string strSymbol = "";
private bool reporting_history = false;

private System.Windows.Forms.Label lblSymbol;
private System.Windows.Forms.TextBox txtSymbol;
private System.Windows.Forms.Button cmdGetData;
private System.Windows.Forms.ListBox lstData;
private AxIQFEEDYLib.AxIQFeedY IQFeed;
private HistoryLookupClass m_HistoryLookupClass;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

public frmMain()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//

this.m_HistoryLookupClass = new HistoryLookupClass();
this.m_HistoryLookupClass.MinuteCompleted +=
new _IHistoryLookupEvents_MinuteCompletedEventHandler
(m_HistoryLookupClass_MinuteCompleted);
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}

this.IQFeed.RemoveClientApp();
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(frmMain));
this.lblSymbol = new System.Windows.Forms.Label();
this.txtSymbol = new System.Windows.Forms.TextBox();
this.cmdGetData = new System.Windows.Forms.Button();
this.lstData = new System.Windows.Forms.ListBox();
this.IQFeed = new AxIQFEEDYLib.AxIQFeedY();
((System.ComponentModel.ISupportInitialize)(this.IQFeed)).BeginInit();
this.SuspendLayout();
//
// lblSymbol
//
this.lblSymbol.Location = new System.Drawing.Point(8, 8);
this.lblSymbol.Name = "lblSymbol";
this.lblSymbol.Size = new System.Drawing.Size(48, 16);
this.lblSymbol.TabIndex = 0;
this.lblSymbol.Text = "Symbol: ";
//
// txtSymbol
//
this.txtSymbol.Location = new System.Drawing.Point(72, 8);
this.txtSymbol.Name = "txtSymbol";
this.txtSymbol.Size = new System.Drawing.Size(136, 20);
this.txtSymbol.TabIndex = 1;
this.txtSymbol.Text = "txtSymbol";
//
// cmdGetData
//
this.cmdGetData.Location = new System.Drawing.Point(216, 8);
this.cmdGetData.Name = "cmdGetData";
this.cmdGetData.Size = new System.Drawing.Size(88, 24);
this.cmdGetData.TabIndex = 2;
this.cmdGetData.Text = "&Get Data";
this.cmdGetData.Click += new System.EventHandler(this.cmdGetData_Click);
//
// lstData
//
this.lstData.HorizontalScrollbar = true;
this.lstData.Location = new System.Drawing.Point(8, 40);
this.lstData.Name = "lstData";
this.lstData.Size = new System.Drawing.Size(656, 316);
this.lstData.TabIndex = 3;
//
// IQFeed
//
this.IQFeed.Enabled = true;
this.IQFeed.Location = new System.Drawing.Point(480, 8);
this.IQFeed.Name = "IQFeed";
this.IQFeed.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("IQFeed.OcxState")));
this.IQFeed.Size = new System.Drawing.Size(100, 24);
this.IQFeed.TabIndex = 4;
this.IQFeed.Visible = false;
this.IQFeed.SummaryMessage +=
new AxIQFEEDYLib._DIQFeedYEvents_SummaryMessageEventHandler(this.IQFeed_SummaryMessage);
this.IQFeed.FundamentalMessage +=
new AxIQFEEDYLib._DIQFeedYEvents_FundamentalMessageEventHandler(this.IQFeed_FundamentalMessage);
this.IQFeed.QuoteMessage +=
new AxIQFEEDYLib._DIQFeedYEvents_QuoteMessageEventHandler(this.IQFeed_QuoteMessage);
this.IQFeed.SystemMessage +=
new AxIQFEEDYLib._DIQFeedYEvents_SystemMessageEventHandler(this.IQFeed_SystemMessage);
this.IQFeed.TimeStampMessage +=
new AxIQFEEDYLib._DIQFeedYEvents_TimeStampMessageEventHandler(this.IQFeed_TimeStampMessage);
//
// frmMain
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(672, 364);
this.Controls.Add(this.IQFeed);
this.Controls.Add(this.lstData);
this.Controls.Add(this.cmdGetData);
this.Controls.Add(this.txtSymbol);
this.Controls.Add(this.lblSymbol);
this.MaximizeBox = false;
this.Name = "frmMain";
this.Text = "frmMain";
this.Load += new System.EventHandler(this.frmMain_Load);
((System.ComponentModel.ISupportInitialize)(this.IQFeed)).EndInit();
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new frmMain());
}

//Form load handler, register client app here
private void frmMain_Load(object sender, System.EventArgs e)
{
this.Text = "CSharp Level1 Socket...";
this.txtSymbol.Text = "";
this.txtSymbol.Enabled = false;

string strName = "IQFEED_DEMO";
string strVersion = "1.0";
string strKey = "1.0";

this.IQFeed.RegisterClientApp( ref strName, ref strVersion, ref strKey );
}

//Watch symbol when the get data button is clicked
private void cmdGetData_Click(object sender, System.EventArgs e)
{
strSymbol = txtSymbol.Text.Trim();
if( strSymbol != "" )
{
IQFeed.WatchSymbol( ref strSymbol );
}
}

//Received fundamental message, add to list box
private void IQFeed_FundamentalMessage(object sender, AxIQFEEDYLib._DIQFeedYEvents_FundamentalMessageEvent e)
{
string strData = e.strFundamentalData;
lstData.Items.Add( strData );
}

//Received summary message, add to list box
private void IQFeed_SummaryMessage(object sender, AxIQFEEDYLib._DIQFeedYEvents_SummaryMessageEvent e)
{
string strData = e.strSummaryData;
lstData.Items.Add( strData );
}

//Received quote message, add to list box
private void IQFeed_QuoteMessage(object sender, AxIQFEEDYLib._DIQFeedYEvents_QuoteMessageEvent e)
{
string strData = e.strQuoteData;
lstData.Items.Add( strData );
}

// First Time you receive the System message indicates you are connected.
private void IQFeed_SystemMessage(object sender,AxIQFEEDYLib._DIQFeedYEvents_SystemMessageEvent e)
{
string strData = e.strSystemData ;
txtSymbol.Enabled = true;
lstData.Items.Add(strData);
}

//Received Time Stamp message, add to list box, request history
private void IQFeed_TimeStampMessage( object sender,AxIQFEEDYLib._DIQFeedYEvents_TimeStampMessageEvent e)
{
string strData = e.strTimeStampData ;
lstData.Items.Add(strData);

if( strSymbol != "" )
{
this.m_HistoryLookupClass.RequestMinuteHistory(strSymbol, 1, 1);
}
}


private void m_HistoryLookupClass_MinuteCompleted( int lMinutesLoaded,
object Time,
object Open,
object Close,
object High,
object Low,
object Volume,
object IntVolume)
{
if (!reporting_history)
{
reporting_history = true;

DateTime[] m_TimeArray = (DateTime[]) Time;
double[] m_OpenArray = (double[]) Open;
double[] m_CloseArray = (double[]) Close;
double[] m_HighArray = (double[]) High;
double[] m_LowArray = (double[]) Low;
int[] m_VolumeArray = (int[]) Volume;
int[] m_IntVolumeArray = (int[]) IntVolume;

for(long i = lMinutesLoaded; i > 0; i--)
{
Console.Write("Time: {0}, ", m_TimeArray.GetValue(i));
Console.Write("Open: {0,8:F}, ", m_OpenArray.GetValue(i));
Console.Write("Close: {0,8:F}, ", m_CloseArray.GetValue(i));
Console.Write("High: {0,8:F}, ", m_HighArray.GetValue(i));
Console.Write("Low: {0,8:F}, ", m_LowArray.GetValue(i));
Console.Write("Volume:{0,6}, ", m_VolumeArray.GetValue(i));
Console.Write("IntVolume:{0,6}, ", m_IntVolumeArray.GetValue(i));
Console.WriteLine();
}

reporting_history = false;
}
}
}
}

IQFeed Developer Support » A Stable .NET Build for both IQFeed and History Dec 20, 2004 11:47 AM (Total replies: 12)

Restoring the C# .NET Example to Its Original Function:

This post assumes that a work folder has been built and modified as described in the previous posts.

The ‘csharplevel1com’ folder (in IQFeed_NET) should contain only the following files and no subfolders:

App.ico
AssemblyInfo.cs
CSharpLevel1.sln
CSharpLevel1.suo
CSharpLevel1COM.csproj
CSharpLevel1COM.csproj.user
CSharpLevel!COM.exe
frmMain.cs
frmMain.resx

Open the solution ‘CSharpLevel1.sln’ and expand ‘References’ in the Solution Explorer. ‘References’ should look like the list of references in Fig 2 of the previous post.

Before making any more changes to the files in folder ‘csharplevel1com’ , we need to make a copy of ‘frmMain.cs’ and save it in a convenient location (preferably outside of the work folder). My preference is to open up ‘frmMain.cs’ (right-click, View Code), Select All, copy and paste everything into Notepad and save it to the desktop as ’frmMain_old.cs’.

From Visual Studio, view the code in ‘frmMain.cs’. Look at the definition for ‘IQFeed’ in Line 20 and the subsequent occurrences of ‘IQFeed’ throughout ‘frmMain.cs’. Some of these occurrences were generated by Visual Studio when the original ActiveX was added to project and some of these were added later in order to complete application. Because we deleted the references and files generated when the ActiveX object was originally added, we will need to locate and add the ActiveX object once again. We could delete all the current ‘IQFeed’ occurrences before adding the ActiveX object, but let’s leave them in for now. They will serve as reference points to help us see the code Visual Studio does and does not generate. We will clean up any conflicting results before we are done.

First, we need to add the ActiveX object to our toolbox in Visual Studio. Remember, that we are adding the “unmanaged” ActiveX object. Before we are finished, Visual Studio .NET will have built everything necessary to make our project believe this is a “managed” Windows Forms control. Visual Studio will also build the code needed to manage the object (via Interop) at runtime.

From the Visual Studio select ‘Tools \ Add/Remove Toolbox Items…’. ‘Customize Toolbox’ will be opened. Select the COM Components tab. Scroll down the component choices until you see ‘IQfeedY Control’. Notice its path is to ‘IQFeedY.ocx’ in your IQFeed directory. This object was registered when the IQFeed API was installed. Click the box next to this entry. A check mark will be placed in the box. Now, click OK. This ActiveX object has been added to you Visual Studio .NET toolbox. Now, we need to add the object to our project.

Right-click ‘frmMain.cs’ in the Solution Explorer and select ‘View Designer’. From the Visual Studio menu, select ‘View / Toolbox’. Click the sub-heading labeled ‘General’ to reveal the ‘IQFeedY Control’. Select ‘IQFeedY Control’, then drag and drop it in the gray area of ‘frmMain’ to the right of the ‘Get Data’ button (exact placement is not important since this control will not be visible). You will notice two familiar members have been added to ‘References’ in the Solution Explorer; ‘AxIQFEEDYLib’ and ‘IQFEEDYLib’. A quick look at the properties of ‘AxIQFEEDYLIb’ and ‘IQFEEDYLib’ will verify that these are the same references that we deleted earlier. A check of the ‘csharplevel1com’ folder will show that the ‘obj’ subfolder has been re-created and ‘AxInterop.IQFEEDYLib.dll’ and ‘Interop.IQFEEDYLib.dll’ have been rebuilt and stored in ‘obj’. Visual Studio .NET (using aximp.exe and Interop services) has just saved us a lot of time and work.

Two .NET assemblies were added to our project’s references: an Interop Assembly for the ActiveX control’s type library, and an ActiveX Assembly that wraps the ActiveX control. The ActiveX Assembly has the same name as the Interop Assembly, but with an Ax prefix. So, we have IQFEEDYLib (the control’s type library) and AxIQFEEDYLib (the control’s wrapper). Now we can access the ActiveX control from our program as though it were a Windows Forms control.

Let’s finish by cleaning up the code that was generated in ‘frmMain.cs’ when we dropped our control on ‘frmMain’ in design mode. Close the toolbox and designer view of ‘frmMain.cs’ (select ‘yes’ if asked to Save). Return to (or re-open) the code view of ‘frmMain.cs’ . In a separate window, open the copy of the “old” version of ‘frmMain.cs’ that we saved earlier (‘frmMain_old.cs’ in my case). Now compare the areas containing the ‘IQFeed’ occurrences that we looked at earlier. You will see that Visual Studio has made some changes.

The first area we want to look at is Line 20 and Line 21.

private AxIQFEEDYLib.AxIQFeedY IQFeed;
private AxIQFEEDYLib.AxIQFeedY axIQFeedY1;

The Visual Studio code generator left the original definition untouched and added a new definition (‘axIQFeedY1’) for the newly added object. Go ahead and delete the original (old) definition since we have a new one to replace it. The new line 20 should be:

private AxIQFEEDYLib.AxIQFeedY axIQFeedY1;

Next, use the ‘Find’ utility (Menu: Edit / Find and Replace / Find …, set the Find config to ‘Match case’ and ‘Match whole word’) in Visual Studio to locate the other occurrences of ‘IQFeed’ The next ‘IQFeed’ is at line 50. Notice the code generator did not add (or change) any code in this area. We will assume that this ‘IQFeed’ code was added by the programmer of the original version of this example, and therefore leave this line of code intact. However, since we are now referencing the ActiveX object as ‘axIQFeedY1’, change ‘IQFeed’ to ‘axIQFeedY1’. Likewise, there are two other occurrences of ‘IQFeed at line 152 and 161 that were not affected by the code generator. Change ‘IQFeed’ to ‘axIQFeedY1’ in these lines as well. All three changes are shown below:

Line 50 Before: this.IQFeed.RemoveClientApp();
Line 50 After: this.axIQFeedY.RemoveClientApp();

Line 152 Before: this.IQFeed.RegisterClientApp( ref strName, ref strVersion, ref strKey );
Line 152 After: this.axIQFeedY1.RegisterClientApp( ref strName, ref strVersion, ref strKey );

Line 161 Before: IQFeed.WatchSymbol( ref strSymbol );
Line 161 After: axIQFeedY.WatchSymbol( ref strSymbol );

Lastly, there are areas in ‘frmMain.cs’ where the code was modified or deleted when the ActiveX object was dropped on the form. Minor code changes (replacing ‘IQFeed’ with ‘AxIQFeedY’) were made on lines 67, 68, 117 and 126. These changes are shown below:

Line 67 Before: this.IQFeed = new AxIQFEEDYLib.AxIQFeedY();
Line 67 After: this.axIQFeedY1 = new AxIQFEEDYLib.AxIQFeedY();

Line 68 Before: ((System.ComponentModel.ISupportInitialize)(this.IQFeed)).BeginInit();
Line 68 After: ((System.ComponentModel.ISupportInitialize)(this.axIQFeedY1)).BeginInit();

Line 117 Before: this.Controls.Add(this.IQFeed);
Line 117 After: this.Controls.Add(this.axIQFeedY1);

Line 126 Before: ((System.ComponentModel.ISupportInitialize)(this.IQFeed)).EndInit();
Line 126 After: ((System.ComponentModel.ISupportInitialize)(this.axIQFeedY1)).EndInit();

Leave these code changes as they are.

Within the InitializeComponent() method, the code generator replaced all the lines that were originally grouped under the subheading ‘IQFeed’. Visual Studio renamed the section to ‘axIQFeedY1’ and added the following lines (your position and size coordinates may be different):

this.axIQFeedY1.Enabled = true;
this.axIQFeedY1.Location = new System.Drawing.Point(416, 8);
this.axIQFeedY1.Name = "axIQFeedY1";
this.axIQFeedY1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject…
this.axIQFeedY1.Size = new System.Drawing.Size(100, 50);
this.axIQFeedY1.TabIndex = 4;

The event handling code and some configuration code of the original example was removed in the above replacement. These lines need to be restored (with the proper naming). To add these lines back, compare the ‘axIQFeedY1’ section of new code with the ‘IQFeed’ section original code (from your copy). The finished section should read as follows (your position and size coordinates may be different):

this.axIQFeedY1.Enabled = true;
this.axIQFeedY1.Location = new System.Drawing.Point(480, 8);
this.axIQFeedY1.Name = "IQFeed";
this.axIQFeedY1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axIQFeedY1.OcxState")));
this.axIQFeedY1.Size = new System.Drawing.Size(100, 24);
this.axIQFeedY1.TabIndex = 4;
this.axIQFeedY1.Visible = false;
this.axIQFeedY1.SummaryMessage += new AxIQFEEDYLib._DIQFeedYEvents_SummaryMessageEventHandler(this.IQFeed_SummaryMessage);
this.axIQFeedY1.FundamentalMessage += new AxIQFEEDYLib._DIQFeedYEvents_FundamentalMessageEventHandler(this.IQFeed_FundamentalMessage);
this.axIQFeedY1.QuoteMessage += new AxIQFEEDYLib._DIQFeedYEvents_QuoteMessageEventHandler(this.IQFeed_QuoteMessage);
this.axIQFeedY1.SystemMessage += new AxIQFEEDYLib._DIQFeedYEvents_SystemMessageEventHandler(this.IQFeed_SystemMessage);

Once these changes have been completed, the example will have been restored to its original function. The project can be built and the application will run as before. If you are a stickler for detail you can restore the original naming of the ActiveX object back to ‘IQFeed’ by selecting the ActiveX object in the Designer view of the form and changing the Design (Name) in the Properties Window (Menu: View / Properties Windows) back to ‘IQFeed’. Also remember to scan ‘frmMain.cs’ and change the remaining occurrences of ‘axIQFeedY1’ to ‘IQFeed’.

We will continue to progress toward the final feed/history example in the next post.

IQFeed Developer Support » A Stable .NET Build for both IQFeed and History Dec 15, 2004 03:35 PM (Total replies: 12)

ActiveX in a .NET World:

I mentioned earlier that ‘IQFeedY’ (an IQFeed ActiveX object) was originally intended for use with Visual Basic. But ‘IQFeedY’ can be used by any application language that has the ability to access and use ActiveX objects/controls. This is certainly the case with the C# (.NET) IQFeed example.

The big deal about using ‘IQFeedY’ with .NET, is that ‘IQFeedY’ (an ActiveX object) does not live in the .NET universe, even when we are using it. It resides among the ‘un-managed’ (from a .NET perspective). The simple explanation of ‘managed’ vs ‘unmanaged’ is “anything created from within .NET is ‘managed’ and anything created outside of .NET is ‘unmanaged’” (sounds a bit elitist). I will leave a more in-depth explanation of ‘managed/unmanaged’ code, objects, etc. to Microsoft, MSDN, and internet research. However, thankfully for us, .NET includes a hearty helping of “legacy attachments”, technically referred to as .NET Interoperability, that bridges the managed/unmanaged gap. When it is all said and done, .NET Interoperability (usually shortened to Interop) makes using ‘IQFeedY’ (and other ActiveX/COM objects) from C# a reasonable possibility.

The .NET Framework supports Windows Forms controls. These are the ‘managed’ equivalent of ActiveX controls. The basic idea behind using an ActiveX control from .NET, is to make the ActiveX control look like it is a Windows Forms control to the .NET application (or client). The proper orchestration of this “bait and switch” (George Costanza would call it the “Old Switcheroo”) is handled by the knowledgeable programmer armed with the proper .NET/COM Interop tools.

The .NET Framework SDK includes a tool, ‘aximp.exe’ (ActiveX Control Importer), that will map an ActiveX control to a Windows Form control. This tool is also available from Visual Studio .NET (we will be using it later). The importer tool does a lot more than just provide a mapping to the ActiveX control. But, for our purposes, it is enough to simply know that ‘aximp.exe’ can help us build a bridge to an ‘unmanaged’ ActiveX object like ‘IQFeedy’.

Enough of that. Now that we have a little knowledge on our side, let’s break some stuff.

From the work folder IQFeed_NET, open the solution containing the CSharpLevel1COM project by double-clicking CsharpLevel1.sln in the csharplevel1com folder. Expand ‘References’ in the Solution Explorer. Right-click ‘AxIQFEEDYLib’ and select properties from the drop-down menu. Examine the path property. This property contains the location of the file being referenced. Notice that ‘AxInterop.IQFEEDYLib.dll’ is the file which contains the reference ‘AxIQFEEDYLib’ for our project. The file itself is located in our project’s subfolder, ‘obj’ (i.e. …/csharplevel1com/obj). Now right-click ‘IQFEEDYLib’. The file ‘Interop.IQFEEDYLib.dll’ is the file containing the ‘IQFEEDYLib’ reference, and it is also located it our project’s ‘obj’ folder.

Ok, close the property window. Now in the Solution Explorer right-click ‘AxIQFEEDYLib’ once again. This time right-click ‘Remove’. Do the same with ‘IQFEEDYLib’. Your References should look like (Fig 2).


References
- System
- System.Data
- System.Drawing
- System.Windows.Forms
- System.XML

(Fig 2)


Now Rebuild the solution (Menu: Build / Rebuild Solution. Yep, it’s broken.

But we are not done yet. Let’s remove from our work folder all occurrences of AxInterop.IQFEEDYLib.dll and Interop.IQFEEDYLib.dll. Close Visual Studio .NET and open the csharplevel1com project folder (IQFeed_NET/csharplevel1com). Delete the files AxInterop.IQFEEDYLib.dll and Interop.IQFEEDYLib.dll from the csharplevel1com folder. For good measure, go ahead and delete both the ‘bin’ and ‘obj’ subfolders from csharplevel1com. If you remember, the files that contained our project references were in ‘obj’. In addition, every fresh build of our project puts an updated copy of AxInterop.IQFEEDYLib.dll and Interop.IQFEEDYLib.dll in the ‘Debug’ and ‘Release’ subfolders of ‘bin’. So, deleting ‘bin’ and ‘obj’ will make for a thorough cleaning. Now, we will be able to clearly see what we create anew.

We will rebuild the project in the next post.

IQFeed Developer Support » A Stable .NET Build for both IQFeed and History Dec 15, 2004 10:21 AM (Total replies: 12)

The References AxIQFEEDYLib and IQFEEDYLib:

From the work folder, open the CSharpLevel1.sln solution created in the previous post. Once the project is loaded, expand 'References' in the Solution Explorer and examine the references used in the C# .NET example (Fig 1)

------------------------
References
- AxIQFEEDYLib
- IQFEEDYLib
- System
- System.Data
- System.Drawing
- System.Windows.Forms
- System.XML

(Fig 1)
------------------------

If you have worked with, or studied, the VB IQFeed examples (i.e. the "non"-.NET examples), the references to AxIQFEEDYLib and IQFEEDYLib probably look familiar; but their form (or usage) is different. The familiar part is the 'IQFEEDY' in both references.

Explore the IQFeed folder which was installed with the IQFeed Developer API (C:\Program Files\DTN\IQFeed on my computer). There you will find the files IQFeedY.oca and IQFeedY.ocx; you have also found the origin of IQFEEDY. These files define and assist an IQFeed ActiveX Object (a non-visible ActiveX Control).

The IQFeedY ActiveX object allows a using application to start and stop the IQFeed; and also to receive Level 1, Regional and News data. It was originally intended for use with Visual Basic, but IQFeedY can assist an application written in any language, provided it has the ability to access and use ActiveX controls. You can find more about this object in the IQFeed 2.3 API Documentation under VisualBasic::IQFeedY.

The C# .NET example (CSharpLevel1) uses the same ActiveX object that was designed for Visual Basic. However, getting to it and using it from .NET requires a bit more work. Fortunately, .NET takes care of most of this work. In the next post, I will give an overview of what is happening behind the scenes to access and use the IQFeed ActiveX object (IOFeedY). We will delete all of our current references to IQFeedY in our C# sample and recreate AxIQFEEDYLib and IQFEEDYLib from scratch.

Just a note:
Honestly, all this is leading to a minimal .NET Feed/History example, but when we get to this thread’s end, I would like the code to make sense. A .NET (C#) approach to accessing the IQFeed/History is more concise (than say a C++ approach), but unless we really understand what is happening behind the scenes, it can be difficult to expand upon or incorporate into our current production development. Thank you for your patience.

IQFeed Developer Support » A Stable .NET Build for both IQFeed and History Dec 14, 2004 08:53 PM (Total replies: 12)

Building an IQFeed .NET Work Folder:

First, add a new folder to your desktop called IQFeed_NET. Now navigate via the Windows "Start Menu" (Start / Programs / IQFeed 2.3 / .NET Examples / --Go to Source Code --) and drag-n-drop a copy of the folder containing the .NET C# example (folder name: csharplevel1com) into your new folder. Be careful that you are dragging a COPY of the folder to your desktop and not just moving it; an easy mistake even for the well-seasoned.

Next, we need to remove the read-only and hidden attributes from the copied folder's files. Open the copied folder csharplevel1com (located in IQFeed_NET) and "Select All" (Menu: Edit / Select All) the files in the root of that folder. Right-click over the selection and select "Properties" from the drop-down menu. In the 'General' properties section "UN-check" the Read-Only and Hidden attributes. Click OK. When asked to "Confirm Attribute Changes", select "Apply changes to the selected items, subfolders and files". Click OK. Now, double-click the CSharpLevel1 solution file (CSharpLevel1.sln) to open the C# example in Visual Studio .NET (THIS WILL RESULT IN AN ERROR, read on...).

Don't be alarmed, you will get a load failure when Visual Studio tries to open the project (something like - "Unable to read the project file 'CSharpLevel1Socket.csproj'". Just click OK. Go to the Solution Explorer and right-click 'CSharpLevel1Socket (unavailable)'. Select 'Remove' and confirm by clicking OK. Now right-click the Solution 'CSharpLevel1'(in the Solution Explorer), select Add / Existing Project... and navigate to Desktop / IQFeed_NET / csharplevel1com / CSharpLevel1COM.csproj . Click 'Open'. "Voila", the project is now usable. (Defn of voila: used to call attention to or express satisfaction with a thing shown or accomplished). This is a good time to Save All (Menu: File / Save All). There are still a couple of changes that need to be made to the new project before we start building stuff.

If you look back on your desktop, you will notice a new folder called IQFEED_Release. This folder was created when we opened the solution file (.sln) in our new project. Its creation is orchestrated by the configuration that our new project inherited when we copied the original project. We need to change the configuration in the new project so that all of our work stays inside of the new folder (IQFeed_NET).

Return to the newly created project in Visual C# .NET (double-click CSharpLevel1.sln if you previously closed the project). Open the 'Configuration Manager' (Menu: Build / Configuration Manager...). Select <Edit...> from the 'Active Solution Configuration:' drop-down list in the upper left corner of the 'Configuration Manager'. Select ‘IQFeed Release’ (from the list under ‘Solution Configuration Name:’) and click 'Remove'. Confirm the delete by clicking 'Yes'. Close 'Edit Solution Configurations'. Before closing the 'Configuration Manager' select <Edit...> from the drop-down list to the right of project 'CSharpLevel1COM' and under the column labeled 'Configuration'. In the list under ‘Project Configuration Name:’ select 'IQFeed Release' and click 'Rename'. Change the name to 'Release' (excluding the quotes). Press 'Enter' and select 'Yes' to confirm the rename. Then select 'Close'. Go ahead and close the 'Configuration Manager'.

Lastly, right-click the project CSharpLevel1COM in the Solution Explorer and from the drop-down menu select 'Properties'. Single-click 'Configuration Properties' in the left-hand panel. In the upper left corner of the 'CSharpLevel1COM Property Pages' locate the 'Configuration:' Drop-Down List and select 'Release'. Now select the path in Outputs / Output Path (it is currently set to “..\..\IQFEED_Release\dotnet_examples\” ). Delete and replace this path with "bin\Release\" (excluding the quotes). Click OK.

You can now build both the debug and release configurations of the C# example. Run the example and get familiar with the general layout of the C# code. By the way, you can delete the ‘IQFeed_Release’ folder on your desktop (if you wish). It is not being used by the newly created Project any longer, and it will not be re-created when the new solution file (CSharpLevel1.sln) is re-opened. The next few posts will explore some of details of the C# .NET example provided by DTN.

Also, be on the lookout for posts marked ‘ERRATA’ which will contain corrections to previous posts; especially if your having problems getting something to work.

Feel free to email me (dennissanders@intsvcs.com) if you have questions and/or suggestions.

IQFeed Developer Support » A Stable .NET Build for both IQFeed and History Dec 14, 2004 07:43 PM (Total replies: 12)

Before diving into a .NET Feed/History code dump and discussion, it is important to first take a look at the .NET examples that DTN has provided. I will begin by working through the C# example (as opposed to VB .NET) primarily because C# exposes a little more of what .NET is doing behind the scenes (also, not to mention, all of my current production work is in C# and C++).

For the next few posts, it will helpful to have an IQFeed .NET desktop work folder. The following instructions assume you have installed the IQFeed Developer API version 2.3.0.2 with the default installation values. (That is what I did, as best I can remember..<g>). The following also assumes you have Visual Studio .NET installed.

IQFeed Developer Support » A Stable .NET Build for both IQFeed and History Dec 14, 2004 12:38 PM (Total replies: 12)

In the course of my product development, I have experimented with different configurations of the currently supplied DTN examples and APIs in an attempt to produce minimal, yet stable, examples which simultaneously run IQFeed and History in a .NET application. I will be posting some of my "more successful" results to this thread. I would like to know if there are other DTN developers interested in this area. Hopefully, our combined contributions will help us more quickly reach our individual development goals.

IQFeed Developer Support » IQFeed .NET C# sockets example using IQ32.dll Oct 27, 2004 07:10 PM (Total replies: 4)

frankzhou,

I am attempting to create a .NET C# version of the VC++ History Example. However, with my current work load, it may be a bit delayed. When I have something useful (in whole or in part), I will post it to the developer forum.

Regards,
Dennis

IQFeed Developer Support » IQFeed .NET C# sockets example using IQ32.dll Oct 26, 2004 10:23 PM (Total replies: 4)

To build and run console_stream.cs from Windows:

Create and name a new folder in a location of your choice.
Open the new folder in a window on your desktop.
Create a new C# Code File in the new folder using the posted code example.
- Open notepad (or a text editor of your choice), copy and paste the posted code to it.
- Using the brackets in the code as a guide, manually replace the indentions that were scrubbed in the forum post.
- Save the contents of notepad to your folder as console_stream.cs
Create a new compile.bat file using notepad.
- Select File->New from the notepad menu.
- Type "csc console_stream.cs" (do not include the quote marks).
- Save (File->Save As) the contents of notepad to your folder as build.bat

You should have two files in your folder; console_stream.cs and build.bat

Create the executable file console_stream.exe
- Double click build.bat

A new file, console_stream.exe should appear in the folder (if not, check the possible reasons below).
Double click console_stream.exe to run the new example.

Possible reasons console_stream.exe was not created or will not run.
- .NET Framework and/or .NET SDK are not installed on your computer (these are free from Microsoft).
- Your path does not include the directory (folder) that contains the .NET build command csc.exe
- Your path does not include the IQFeed directory (C:\Program Files\DTN\IQFeed on my computer).

Executing the build and/or run operations at the Windows Command Prompt will help you diagnose most problems.
Feel free to post your ideas/questions/problems to this thread, or send an email.

Regards,
Dennis Sanders
dennissanders@intsvcs.com

IQFeed Developer Support » IQFeed .NET C# sockets example using IQ32.dll Oct 26, 2004 06:56 PM (Total replies: 4)

To build and run console_stream.cs from Visual Studio.NET:

Create a new Visual C# "Empty Project" in Visual Studio.NET
- In VS.NET go to File->New->Project->Visual C# Projects->Empty Project.
- Type in "console_stream" as the project name and select a location for the project folder.
- Accept the remaining defaults and click OK.
Add a new Code File to the Project
- In the Solution explorer (use View if you don't see it), right click "console_stream" (the project name).
- Select Add->Add New Item->Code File.
- Name the Code File console_stream.cs, click Open.
Copy and paste the posted code to the editing space for console_stream.cs.
- (...All indents will be magically restored, thank God!...)
Add System.dll to the References in your project.
- Right click References (below the project name in the Solution Explorer).
- Select Add Reference, then scroll down the selections under the .NET tab.
- Double-click System.dll, it should appear in Selected Components, then click OK.
(System.dll will be added as System under References.
Now Build the Solution
- Change Active Configuration if desired.(the default is Debug, but Release works as well)
- Then select Build->Build Solution

The project should build with 0 failed, 0 skipped (and no warnings).
- Any build errors can most likely be resolved by adjusting your path or other environment variables.

You will need a path to IQ32.dll (C:\Program Files\DTN\IQFeed on my computer) in order to successfully run the program.

To run console_stream.exe from Visual Studio press F5. Or, to run the .exe from Windows; exit Visual Studio and hunt down the console_stream.exe in you newly created project folder. When you find it...double click it.

If you have any questions or problems, please post or email.

Regards,
Dennis Sanders
dennissanders@intsvcs.com

IQFeed Developer Support » IQFeed .NET C# sockets example using IQ32.dll Oct 26, 2004 05:36 PM (Total replies: 4)

This may be of interest to some:

///////////////////////////////////////////////////////////////////////////////////
// console_stream.cs, version 1.0, copyright 2004
// IQFeed .NET C# sockets example using IQ32.dll
//
// contributed to the IQFeed Developer Support Forum
// by Dennis Sanders (forum username: Dennis)
// email: dennissanders@intsvcs.com
///////////////////////////////////////////////////////////////////////////////////

using System;
using System.Threading;
using System.Net.Sockets;
using System.Runtime.InteropServices;

public delegate void Callback(int x, int y);

class IQFeed_NETSocket_Example
{
[DllImport("IQ32.dll")]
public static extern void SetCallbackFunction(Callback SetGoodToGo);
[DllImport("IQ32.dll")]
public static extern int RegisterClientApp(IntPtr hClient, string szProductName,
string szProductKey, string szProductVersion);
[DllImport("IQ32.dll")]
public static extern void RemoveClientApp(IntPtr hClient);

public static bool GoodToGo = false;

public static void SetGoodToGo(int x, int y)
{
GoodToGo = (x==0 && y==0);

if (x==1 && y==1)
{
Console.WriteLine("IQFeed delivered close message");
RemoveClientApp(IntPtr.Zero);
}
}

public static void Main()
{
Callback IQFeed_CallBack = new Callback(IQFeed_NETSocket_Example.SetGoodToGo);
SetCallbackFunction(IQFeed_CallBack);

RegisterClientApp(IntPtr.Zero, "IQFEED_DEMO", "1.0", "1.0");

while (!GoodToGo)
Thread.Sleep(100);

try
{
String server = "127.0.0.1";
Int32 port = 5009;
TcpClient client = new TcpClient(server, port);

NetworkStream stream = client.GetStream();

String message = "S,KEY\r\n";
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
stream.Write(data, 0, data.Length);

message = "wMSFT\r\n";
message += "wIBM\r\n";
data = System.Text.Encoding.ASCII.GetBytes(message);
stream.Write(data, 0, data.Length);

data = new Byte[5120];

for(int x=0; x<20; x++)
{
String responseData = String.Empty;
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
Console.Write(responseData);
}

client.Close();
}

catch (ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException: {0}", e);
}

catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}

RemoveClientApp(IntPtr.Zero);

Console.Write("\nPress Enter to continue...");
Console.Read();

GC.KeepAlive(IQFeed_CallBack);
}
}

//////////////////////////////////////////////////////////////////////////////////////
// end - console_stream.cs
//////////////////////////////////////////////////////////////////////////////////////


Please post or email any questions, comments or improvements.

Regards,
Dennis Sanders
dennissanders@intsvcs.com



You can recreate the "No Callback" with the following steps:
1. Remove from you PATH, the IQFeed directory (the installed location of IQConnnect.exe and IQ32.dll).
2. Copy IQ32.dll to your working directory (location of console_stream.exe or executable of above example).
3. Run console_stream.exe or executable of above example.

The "why would anyone do this" and/or "why this causes a problem" requires a lengthly post; which I will be glad to supply if someone is interested.

Otherwise, "...onward through the fog".
Dennis


The "No Callback" problem relates to how IQConnect.exe and IQ32.dll are accessed during runtime. It is possible to position these modules (in folders relative to your exe) in such a way as to cause the "No Callback" problem and mask an exception that IQConnect would otherwise display.

More to come...(busy weekend).
Dennis


Since my original posting, I reconfigured my environment and I now have a working instance of my test example (output below). I will try to isolate the particular change or changes that made the difference, and I will post under this thread.

Output from test program (after changes):
-------------------------------------------------
main..
callback function set..
registered client...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
callback from IQFeed...
goodToGo...
Press any key to continue


I cannot get the while(!goodToGo) loop to release in the VC++ console_stream example.
Early testing indicates that the callback, which is intended to set goodToGo, never occurs.
Has anyone else experienced this problem?

Test program (C++) and output follows:
----------------------------------------

// callback_test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

bool goodToGo = false;

void __stdcall callback(int x, int y) // Receives information from iqfeed.
{
cout << "callback from IQFeed...\n"; // Test Trace
goodToGo = (x==0 && y==0);

if (x && y) {
cout << "IQFeed delivered close message\n" << endl;
RemoveClientApp(NULL);
exit(0);
}
}


int main(int argc, char* argv[])
{
cout << "main..\n"; // Test Trace

SetCallbackFunction(callback); // set the callback function to get info from IQFeed
cout << "callback function set..\n"; // Test Trace

RegisterClientApp(NULL, "IQFEED_DEMO", "1.0", "1.0"); // start iq feed
cout << "registered client...\n"; // Test Trace

while (!goodToGo) { // wait for the callback
cout << "waiting for callback...\n"; // Test Trace
Sleep(100);
}

cout << "goodToGo...\n"; // Test Trace
return 0;
}
-----------------------------------------------------------------------------------------

Console Output:
---------------
main..
callback function set..
registered client...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
waiting for callback...
(ad infinitum)
-------------------------------------------------------------------------------------------

Using IQFeed Files:
-------------------
IQ32.h 5 KB 1/29/2003 1:55PM
IQ32.lib 8 KB 3/15/2004 11:00AM
IQ32.dll 96KB 7/26/2004 5:23PM

Note: I have compiled the console_stream example and the test program in both the Visual C++ and Visual .NET (C++) environments with the same result.


Time: Thu April 25, 2024 7:50 AM CFBB v1.2.0 10 ms.
© AderSoftware 2002-2003