SmartQuant Discussion

Automated Quantitative Strategy Development, SmartQuant Product Discussion and Technical Support Forums
It is currently Thu Dec 13, 2018 5:09 am

All times are UTC + 3 hours




Post new topic Reply to topic  [ 11 posts ] 
Author Message
PostPosted: Thu Aug 20, 2009 8:49 pm 
Offline

Joined: Sat Jul 24, 2004 12:40 am
Posts: 77
Location: Odessa, Florida
Hello,
It would really be great if you could provide the API to the chart object. Basically, i would like to add my own annotations to the chart. I would like to be able to draw my own lines on the chart or type text on the chart.

As an attempt to do a work around, I tried to create a windows form that would hold a charting object that I have purchased from a vendor (gigasoft.com). I was able to create and display a windows Form outside the IDE with the following code:
First: I created a Form class called Form0 derived from the Windows Form class
Code:
public class Form0 : Form
{
   private System.ComponentModel.Container components = null;
   
   public Form0()
   {
      InitializeComponent();
   }
   
   private void InitializeComponent()
   {
      components = new System.ComponentModel.Container();
   }

   protected override void Dispose(bool disposing)
   {
      if (disposing)
      {
         if (components != null)
         {
            components.Dispose();
         }
      }
      base.Dispose(disposing);
   }
   

   [STAThread]
   static void Main()
   {
      Application.EnableVisualStyles();
      Application.Run(new Form0());
   }

}


And then, at the begining of the OnStrategyStart() I added
Code:
testForm = new Form0();
testForm.Show();


When I run my strategy, evrything works fine (I can see my windows form appear), BUT it is non responsive. If I move the mouse over my form, it immediately turns into an hourglass and the form is unresponsive.

If I could just get the form to be responsive, I could add my graphical chart control into it and, in parallel, display my stock data on my form and also control my own chart by being able to put text and graphics on it.


Any suggestions?


Top
 Profile  
 
PostPosted: Thu Aug 20, 2009 9:45 pm 
Offline

Joined: Sat Jul 24, 2004 12:40 am
Posts: 77
Location: Odessa, Florida
I will partially respond to my own suggestion. I went ahead and used ShowDialog to show my form in such a way that it would respond to mouse events.
That has worked. So, for the moment, I can display a form with everything else that OpenQuant does. Now, I will work on embedding my ProEssentials chart component (from Gigasoft.com) and in that way, as I do in my C++ applicaition, I should be able to display the instrument I am working with as well as put any kind of annotation I wish on the chart. Also, this is really useful for debugging as you can see and tell visually, on the chart, why something is not working as it shoud.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 21, 2009 1:54 am 
Offline

Joined: Thu Jun 08, 2006 3:56 pm
Posts: 537
Location: BC Canada
Thanks very much for posting this code example, and for mentioning that you have to use Show Dialog to get the form to respond to mouse events.

I'm sure that displaying your own windows during simulations or live trading is something that many people have thought about and have wanted to do, to help control their strategies, change parameters on the fly, and so on. But of course not many people know how to do it.

I hope that you continue to post up working examples on this thread, at least enough for people to get started at getting a window displayed and shut down properly, responding to mouse, keyboard, and menu events, and posting data to and from OpenQuant to and from the window. At that point, people will have a working framework that they can extend as they please.


Top
 Profile  
 
 Post subject: Chart control
PostPosted: Fri Aug 21, 2009 2:37 am 
Offline

Joined: Sat Jul 24, 2004 12:40 am
Posts: 77
Location: Odessa, Florida
You are welcome kkkwj,
But I am sorry to have to backtrack a bit, but my code is not working as well as I thought. I do think that what I have posted can help and somehow I feel that I am not too far from some solution. I hope that others can take the code and really make it work.
Being a C++ and part C# programmer, it is easy, using Visual Studio, to make a form, add components to it and just go.
Since you seem to be interested, I will add more information about what I have done in C++.
I have used C++ do write an application that reads stock data (I made my own little dabase and the software reads data from Yahoo). I have derived a chart class from the Pego class found in Gigasoft's Proessentials graphics tools. That derived class is used to display stock data. Since I have total control over that class, I can draw lines, text, maximize, send to a file, etc (you should really check out Gigasoft.com).
I display a chart pattern I have found and I can use the chart for debugging purpose. I have also made a C# version of that application and that is why I would LOVE to be able to put up a form containing my class while running OpenQuant 2. Yes, the code I posted earlier is able to display a form (I have not added my component yet, hopefully later I will be able to). However, if I use the Show() method for a form, OpenQuant 2 runs the strategy all the way to the end (I can see the chart being displayed as I also use the "Update UI during simulation" option), but while the strategy is being run, my form is totally unresponsive. If I move the mouse over the form, it turns into an hourglass.
Now, if I instead use the ShowModal() method, the form seems to be active (as a mouse pointer stays a pointer while being moved over the form), but OpenQuant2 doesn't run the strategy until I close the Form. Once I close the form then the strategy goes through all the bars of the instrument (I only use one instrument to keep things simple).
So, in either case, I still can't use my own form. And when that problem is somehow solved, I need to find out how to include a component (such as a simple textbox or a Gigasoft chart) so that I can control that component which will very certainly be a chart.
So, in a nutshell you understand what I am trying to do.
Of course, what would make all of this superfluous would be if our dear friends at smartquant simply provided the API to the chart object so that we too could add things to the chart and be able to add our own lines and text and whatever else we like.
Just to show you what the graphics of my chart object looks like after I uploaded it to a web page at wikinvest.com
http://www.wikinvest.com/image/LUV_BUY.jpg
I can display my technical patterns, important price levels, etc... I would be great if on top of all that I would have the buy and sell signals generated by OpenQuant 2.


Top
 Profile  
 
PostPosted: Sat Aug 22, 2009 12:36 am 
Offline

Joined: Sat Jul 24, 2004 12:40 am
Posts: 77
Location: Odessa, Florida
Hello again,
I will talk again about a topic that is dear to me, namely, controlling your own form while running a strategy. I find OpenQuant 2 (OQ2) to be a great tool, but as I've said before, I would really like to be able to also put up my own chart (and other controls like text boxes, treeviews, etc...) so that I can put more information out than OQ2 allows. This would also be extremely useful for debugging purposes.
Of course this could all be done easily in Visual Studio if the developers at OpenQuant were to create an object that would be a strategy object. That object would generate all the proper events necessary to run a strategy. All that a developer would then need to do is to include that Strategy component on their form and then write handlers for the events that would occur when the strategy is run. At that point it would be simple to add other components or controls on the form so that a developer could perform other tasks that simply can't be done right now on OQ2. I don't see why it is so difficult to create a .net assembly and dll that would make OQ2 a control. Perhaps someone reading this will be able to explain it technically to me (and all of us who are also interested in the topic)
In the meanwhile, I have tried to allow just such a thing to be done. I am missing one last piece, but perhaps others will be able to figure out how to make that last piece work.

Here is what I did.
First, I used Visual Studio 2008 to write a simple sample Windows Form application in C#.

1) I simply create a Form which I called TestForm
That form simply contains a label, a text box, a timer, a radio button, 2 buttons, a progress bar and a timer.

2) I then set up a couple of event handlers so that you could start and stop the timer by clicking on the start/stop button. You can also reset a counter that counts the number of clock ticks. The progress bar is updated to reflect the number of clock ticks and so is the text box. You can also interact with the form by typing text into the text box.

3) I then took the code generated by VS 2008 and imported the class code into OQ2.
Here is what it looks like:
Code:
public class TestForm : Form
{
   /// <summary>
   /// Required designer variable.
   /// </summary>
   private System.ComponentModel.IContainer components = null;

   /// <summary>
   /// Clean up any resources being used.
   /// </summary>
   /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
   protected override void Dispose(bool disposing)
   {
      if (disposing && (components != null))
      {
         components.Dispose();
      }
      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()
   {
      this.components = new System.ComponentModel.Container();
      this.progressBar1 = new System.Windows.Forms.ProgressBar();
      this.textBox1 = new System.Windows.Forms.TextBox();
      this.timer1 = new System.Windows.Forms.Timer(this.components);
      this.radioButton1 = new System.Windows.Forms.RadioButton();
      this.button1 = new System.Windows.Forms.Button();
      this.label1 = new System.Windows.Forms.Label();
      this.button2 = new System.Windows.Forms.Button();
      this.SuspendLayout();
      //
      // progressBar1
      //
      this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
         | System.Windows.Forms.AnchorStyles.Right)));
      this.progressBar1.Location = new System.Drawing.Point(22, 212);
      this.progressBar1.Name = "progressBar1";
      this.progressBar1.Size = new System.Drawing.Size(276, 32);
      this.progressBar1.TabIndex = 0;
      //
      // textBox1
      //
      this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
         | System.Windows.Forms.AnchorStyles.Right)));
      this.textBox1.Location = new System.Drawing.Point(20, 29);
      this.textBox1.Name = "textBox1";
      this.textBox1.Size = new System.Drawing.Size(278, 20);
      this.textBox1.TabIndex = 1;
      //
      // timer1
      //
      this.timer1.Interval = 1000;
      this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
      //
      // radioButton1
      //
      this.radioButton1.AutoSize = true;
      this.radioButton1.FlatAppearance.CheckedBackColor = System.Drawing.Color.Red;
      this.radioButton1.Location = new System.Drawing.Point(38, 122);
      this.radioButton1.Name = "radioButton1";
      this.radioButton1.Size = new System.Drawing.Size(80, 17);
      this.radioButton1.TabIndex = 2;
      this.radioButton1.TabStop = true;
      this.radioButton1.Text = "Timer Alerts";
      this.radioButton1.UseVisualStyleBackColor = true;
      //
      // button1
      //
      this.button1.Location = new System.Drawing.Point(109, 145);
      this.button1.Name = "button1";
      this.button1.Size = new System.Drawing.Size(75, 23);
      this.button1.TabIndex = 3;
      this.button1.Text = "Reset";
      this.button1.UseVisualStyleBackColor = true;
      this.button1.Click += new System.EventHandler(this.button1_Click);
      //
      // label1
      //
      this.label1.AutoSize = true;
      this.label1.Location = new System.Drawing.Point(19, 9);
      this.label1.Name = "label1";
      this.label1.Size = new System.Drawing.Size(165, 13);
      this.label1.TabIndex = 4;
      this.label1.Text = "Go ahead, type something below!";
      //
      // button2
      //
      this.button2.Location = new System.Drawing.Point(110, 82);
      this.button2.Name = "button2";
      this.button2.Size = new System.Drawing.Size(75, 23);
      this.button2.TabIndex = 5;
      this.button2.Text = "Start";
      this.button2.UseVisualStyleBackColor = true;
      this.button2.Click += new System.EventHandler(this.button2_Click);
      //
      // TestForm
      //
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
      this.ClientSize = new System.Drawing.Size(323, 266);
      this.Controls.Add(this.button2);
      this.Controls.Add(this.label1);
      this.Controls.Add(this.button1);
      this.Controls.Add(this.radioButton1);
      this.Controls.Add(this.textBox1);
      this.Controls.Add(this.progressBar1);
      this.Name = "TestForm";
      this.Text = "TestForm";
      this.ResumeLayout(false);
      this.PerformLayout();

   }

   #endregion

   public System.Windows.Forms.ProgressBar progressBar1;
   public System.Windows.Forms.Timer timer1;
   public System.Windows.Forms.RadioButton radioButton1;
   public System.Windows.Forms.Button button1;
   public System.Windows.Forms.Label label1;
   public System.Windows.Forms.Button button2;
   public System.Windows.Forms.TextBox textBox1;

   // Here we have the event handlers for the form
   // We will need a counter to count the number of ticks from the timer
   private int timerCounter = 0;

   // Constructor
   public TestForm()
   {
      InitializeComponent();
   }

   // Event handler for button press. It resets all
   private void button1_Click(object sender, EventArgs e)
   {
      // clear the time counter
      timerCounter = 0;
      // Set the progress bar to 0
      progressBar1.Value = 0;
      // Clear the text box
      textBox1.Text = "";
      radioButton1.Checked = false;
   }

   // Event handler for timer ticks
   private void timer1_Tick(object sender, EventArgs e)
   {
      // Update the timer
      timerCounter++;
      // Display the total count in the text box
      textBox1.Text = timerCounter.ToString();
      // Update the progress bar
      progressBar1.Value = timerCounter % progressBar1.Maximum;
      // flash the radio button on odd counts
      radioButton1.Checked = (timerCounter % 2) == 1;
   }

   // Event Handler for starting and stopping the timer
   private void button2_Click(object sender, EventArgs e)
   {
      // Toggle the text
      if (button2.Text == "Start")
      {
         button2.Text = "Stop";
         // Start the timer
         timer1.Start();
      }
      else
      {
         button2.Text = "Start";
         // stop the timer
         timer1.Stop();
      }
   }
   
}


Once you have that code in the code.cs (I used Cut and Paste) you can declare an object of type TestForm inside the Strategy class.
Code:
   public TestForm sampleForm = null;


You will then want to actually instantiate the object when the strategy starts, with the following code inside the OnStrategyStart() event handler:
Code:
         /// <summary>
         /// The main entry point for the application.
         /// </summary>
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);
         sampleForm = new TestForm();
         Application.Run(sampleForm);


Try it with an empty strategy and actually see it work.

This is as far as I've gotten for now. If you run your strategy with the code I've provided, you will see the sampleForm appear. If you click on the start button you will see the count increase in the text box, the radio button will blink every time the timer ticks away (once per second). You will also see the progress bar update itself. If you click on the reset button the counter is reset to 0. This shows that the form is fully functional and that the events generated inside the form by the timer are properly working.

Note that if you want to have control over the components in the form, make sure that you set their access qualifiers to "public" as in:
Code:
   public System.Windows.Forms.ProgressBar progressBar1;
   public System.Windows.Forms.Timer timer1;
   public System.Windows.Forms.RadioButton radioButton1;
   public System.Windows.Forms.Button button1;
   public System.Windows.Forms.Label label1;
   public System.Windows.Forms.Button button2;
   public System.Windows.Forms.TextBox textBox1;

Then you can access control them with statements such as:
Code:
       sampleForm.textBox1.Text = "Hello world";


The only problem is that while the form is up the strategy stops. You can verify that by checking the Solution->Update UI during simulation" menu item. You will see the chart frozen (perhaps even with the stock data from your last run), but as soon as you close the sample test form you will see the simulation clear the chart and update it as the OnBar event is repeatedly being fired.

This is probably a threading issue, and I would love to figure out or have someone explain how to get the form not freeze the strategy.

I even thought about not displaying the form until the OnStrategyStop() event, and updating the controls during the OnBar() event.
But that also did not work the way I wanted.

Any ideas from the powers that be at SmartQuant?


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 23, 2009 2:20 am 
Offline

Joined: Thu Jun 08, 2006 3:56 pm
Posts: 537
Location: BC Canada
I could be wrong (my C# isn't what it used to be), but I think I remember reading about the same problem elsewhere. As you surmise, it's a threading issue.

If memory serves me correctly, the workable method is to create the Form as an object (without showing it yet), and then show it as a non-modal form. Do I remember a ShowDialog name from the past, that is NOT the one that you want to use?

Anyhow, I'm pretty sure that the problem is caused by how you show the form. It seems to me that you should not be calling Application.Run on the form, because it's not really an application. Instead I think you need to find out how to just show the form as part of the IDE application.

Alex or Sergey would be the experts to comment, or Keith (krn_2k); I think they have more experience than me. The best I can do is to show an example from a webpage in VS help:

Code:
// Initialize window
Window window = new Window();

// Show window modelessly
// NOTE: Returns without waiting for window to close
window.Show();


Top
 Profile  
 
 Post subject: Controlling a chart
PostPosted: Sun Aug 23, 2009 4:24 am 
Offline

Joined: Sat Jul 24, 2004 12:40 am
Posts: 77
Location: Odessa, Florida
Hello kkkwj,
I have indeed tried to simply use Show() rather than Application.Run(). The same issues appear. I cant have both the chart and strategy running at the same time.
By the way, if you cut and past the code I provided you would be able to see the form come up and what the issues are. Now, the interesting thing if that if somehow one can get the form to work in parallel with the strategy it would open quite some possibilities. But somehow I get the feeling that if it were possible to do what I am looking for, someone would have figured it out by now.
I just wish that whoever is in charge at SmartQuant would make the decision to create a set of components that could be included in a form. All that would be needed would be to include the Strategy component on your form and handle the events it generates. One could then leverage any other type of components (charts, treeviews, etc...) for other purposes.
It really should not be that complicated to do for those developers who designed OQ2.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 25, 2009 6:29 pm 
Offline

Joined: Thu Jun 08, 2006 3:56 pm
Posts: 537
Location: BC Canada
I was thinking more about what you're trying to do, and I think you're right, it's a threading issue, and I think you'll have to spawn a separate process thread to run your window, if you want it to act independently of the main OQ application. And once it's gone from the address space of the spawning process, you'll face a bunch of other inter-process communication issues.

Sorry to take so long to remember all this, but it has been a number of years since I did that kind of asynch thread programming.

Once you spawn the thread with the window in it, then you'll have to face the problem of how to communicate with the now-separate process. You'll need to either open a socket to it (or some other equivalent IPC inter-process communication method), and ship commands and data that way, or maybe write data to a database and have your window read from the data store by polling it.

Try going to www.codeproject.com and searching for threads there; it's probably one of the best repositories of articles on C# programming.


Top
 Profile  
 
 Post subject: Threading
PostPosted: Tue Aug 25, 2009 10:29 pm 
Offline

Joined: Sat Jul 24, 2004 12:40 am
Posts: 77
Location: Odessa, Florida
Hello kkkwj,

Yes, I have done that kind of thing before. I was hoping that I would not have to. Well I'll see what I can do. Perhaps the powers that be at smartquant will see this as a real nice possibility to offer.
But, really, all I want is a simple component that represents a strategy. I would love to see that component be available in the toolbox. All one would need to do is plop that component on a form, write some event handlers and be on their way. Then you could also add other components, such as charts and do even more wonderful work.

But somehow I think this would encroach on some other product. :?

But thanks for the feedback


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 27, 2009 1:01 pm 
Offline

Joined: Wed Sep 16, 2009 6:26 pm
Posts: 27
any chance for a feedback from the admins? That would be really usefull if someone could show how to solve this issue. Thanks


Top
 Profile  
 
PostPosted: Fri Sep 14, 2012 8:47 am 
Offline

Joined: Thu Jun 08, 2006 3:56 pm
Posts: 537
Location: BC Canada
Just to update this thread with a pointer to more threading info, and a sample Form to run.

http://www.smartquant.com/forums/viewtopic.php?f=64&t=7740


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC + 3 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group