SmartQuant Discussion

Automated Quantitative Strategy Development, SmartQuant Product Discussion and Technical Support Forums
It is currently Sat Feb 29, 2020 12:49 am

All times are UTC + 3 hours




Post new topic Reply to topic  [ 32 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject:
PostPosted: Sat May 10, 2008 9:41 am 
Offline

Joined: Tue Aug 05, 2003 3:43 pm
Posts: 6816
I'll talk to our developers on Monday but in general Daily objects differ from Bar objects in SQ framework due to historical reasons :roll:


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 14, 2008 9:21 pm 
Offline

Joined: Fri Apr 04, 2008 6:11 am
Posts: 138
Thanks Anton. Any update on this?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 17, 2008 11:22 pm 
Offline

Joined: Fri Apr 04, 2008 6:11 am
Posts: 138
Still curious on this one, but I've got an additional question too.

How can you preload data with multiple instruments and maintain the bar processing order OQ uses in simulation mode (ie. breadth first rather than depth first)? With the preloading code examples given, each instrument is processed on its own before moving on to the next instrument. This is not the way OQ runs simulations. It is fine if you aren't doing any kind of pairs trade in your strategy, but you run into major issues if you are (how can you grab the price of the hedge instrument at the given bar if the bars aren't even loaded yet for that instrument?).

How can I modify the preloading code such that it runs in two phases:
1) Download the required historical data for each instrument
2) Process the earliest bar for each instrument, then the next bar for each instrument, etc.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 18, 2008 12:20 am 
Offline

Joined: Fri Apr 04, 2008 6:11 am
Posts: 138
I was hoping something along the lines of what I've included below would work, but it doesn't look likely. This does manage to walk through all the instruments in parallel, but there's a major show stopper: there is no way to force OnBarOpen and OnBar to execute on a specific instrument. Instead, they will always execute on the current instrument (Strategy.Instrument, which in this case will always be the last instrument in the list) and Stratey.Instrument is read only so there's no easy temporary swapping solution.

Code:
if (Instrument == LastInstrument)
{
   int barsAgo = 300;
 
   while (barsAgo >= 0)
   {
   foreach (Instrument i in Instruments)
   {
      BarSeries bars = GetBarsForInstrument(i);
      
      if (bars.Count > barsAgo)
      {
         Bar bar = bars.Ago(barsAgo);
         
         OnBarOpen(bar);
         OnBar(bar);
      }
   }      
   
   barsAgo--;
   }
}


Even if you could specify the instrument, the solution would still be no good. Any member variables of your strategy would reflect the current Instrument, and not the one specified.

A parallel preloading process looks like a feature that will have to be developed on OQ's side.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 18, 2008 12:02 pm 
Offline

Joined: Wed Oct 08, 2003 1:06 pm
Posts: 833
Hi,

You can try to use a static Dictionary<Instrument, Strategy>, fill it in the OnStrategyStart method, like myStrategyInstances.Add(instrument, this); and use this object to call OnBar and OnBarOpen of a "correct" strategy. One problem here is that you should make sure that you call the PreloadHistoricalBars inside instance that is initialized at the very end, this can be easily checked by incrementing a static int field in OnStrategyStart and comparing it with Instruments.Count value. Do you see what I mean?

Regards,
Sergey.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 18, 2008 9:44 pm 
Offline

Joined: Fri Apr 04, 2008 6:11 am
Posts: 138
Yeah, thanks Sergey. I'll give that a shot. I completely forgot that I could store instances of the entire strategy class.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 19, 2008 1:20 am 
Offline

Joined: Fri Apr 04, 2008 6:11 am
Posts: 138
Nice work! I was able to get it working using the strategy store approach. Just in case anyone runs into this issue in the future, here's a few tips:

* Within each OnStrategyStart, call your preloading code but load the bars into your own BarSeries (ie. static Dictionary<Instrument, BarSeries> SharedBars). Do not add them into Strategy.Bars, as that will throw off any bar series calculations your strategy uses (such as Bars.HighestHigh, Bars.Last, Bars.Count, etc.)

* Within OnStrategyStart, track the number of instruments already initialized. You want to do all your preloading simulations only once the last instrument has been initialized.

* Create a Strategy.Preloading property that you can use as a flag to modify the way your strategy behaves while in the preloading state (such as simulating the execution of orders rather than actually sending them)

* For the actual bar iteration, you'll need to go through each bar in parallel, adding each bar to the real Strategy.Bars and calling the OnBar* methods yourself. The easiest way to do this is using the BarSeries.Ago method. Simply stepping forward one by one from the first bars will fail if any of the instruments have fewer bars than the others. The code explains this part better:

Code:
// Begin preload execution
foreach (MyStrategy s in SharedStrategies.Values)
   s.Preloading = true;

for (int barsAgo = 300; barsAgo >= 0; barsAgo--)
{
   foreach (MyStrategy s in SharedStrategies.Values)
   {      
      BarSeries bars = SharedBars[s.Instrument];
      
      if (bars.Count > barsAgo)
      {
         Bar bar = SharedBars[s.Instrument].Ago(barsAgo);
         
         s.Bars.Add(bar);
         s.OnBarOpen(bar);
         s.OnBar(bar);
      }
   }
}

// Done preloading
foreach (MyStrategy s in SharedStrategies.Values)
   s.Preloading = false;


* You'll have to adjust your strategy to not use the Strategy.Bar member. It doesn't update automatically when you directly call the OnBar* methods and it is read only, so you'll have to track the current bar yourself. The easiest way I found to do this is to simply create a new strategy member (Bar MyBar, example) and set this value manually within the OnBar* methods.


Those are all the major issues I can remember running into. It works, but it definitely requires a number or modifications and workarounds in your strategy. I'd love to see OQ be able to handle all of this without special handling for the various modes, but until then this will have to do.

Thanks again Sergey.


Top
 Profile  
 
PostPosted: Thu Apr 02, 2009 6:35 pm 
Offline

Joined: Thu Jan 15, 2009 1:25 pm
Posts: 14
If my strategy need trade more than one instruments, how can I pre load all their data? It seems GetHistoricalBars can only work on one instrument?

_________________
Jack Lenard


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 06, 2009 1:30 pm 
Offline
Site Admin

Joined: Thu Jul 17, 2003 10:39 am
Posts: 1478
Hi,

You are able to call GetHistoricalBars method for each instrument separately.
Code:
foreach (Instrument instrument in <some_instrument_list>)
{
    GetHistoricalBars(instrument,....
}


Regards,
Alex

_________________
SmartQuant Development Team


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 18, 2009 10:58 pm 
Offline

Joined: Mon Mar 05, 2007 7:02 am
Posts: 58
I have the code in OnStrategyStart to load historical bars and it is working without any problems.

I also created a method that I would like to call multiple times using a Timer to re-load the data from the Daily Bar Database. I need to do this as the futures I trade are traded on multiple exchanges and my data provider (CSI) publishes the data for the exchanges at different times and my system trades nearly 24 hrs a day. Is this possible?

Also, is there a way to programatically import CSV files into the database from the disk? I am currently doing this manually, but need to repeat this process multiple times during the night.

Thanks,
Eric

Code:
   public void LoadHistoricalBars()
   {
      Console.WriteLine("Success");
      foreach (Bar bar in GetHistoricalBars(datetime1, datetime2, BarType.Time, 86400))
      {   
         Bars.Add(bar);
         series.Add(bar);
      }
      foreach (Bar bar in series)
      {
         prev_Close = bar.Close;
         //Console.WriteLine(Instrument.Symbol + "---->" + bar.DateTime.ToShortDateString() + "---->" + prev_Close.ToString());
         //series.Add(bar);
         
         double risk_short_Series_atom = Math.Abs((bar.High - bar.Close)) * Instrument.Factor  * Pos_Sizing_Multiplier;
         double risk_long_Series_atom = Math.Abs((bar.Close - bar.Low)) * Instrument.Factor  * Pos_Sizing_Multiplier;
         
         risk_short_Series.Add(bar.DateTime, risk_short_Series_atom);
         risk_long_Series.Add(bar.DateTime, risk_long_Series_atom);
         
         if (linear_Regression_Slope.Count > 0)
         {
            if (linear_Regression_Slope.Last > 0)
            {
               risk_combined_Series.Add(bar.DateTime, risk_long_Series.Last);
            }
            else
            {
               risk_combined_Series.Add(bar.DateTime, risk_short_Series.Last);
            }
         }
      }
   }


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 18, 2009 11:31 pm 
Offline

Joined: Tue Aug 05, 2003 3:43 pm
Posts: 6816
Normally you load historical data in OnStrategyStart method, i.e. before your startegy starts (Bars and other market data series are empty). Then you create indicators and pass Bars as parameter, so that indicators get calculated for hostorical bars as well.

Although Bars.Add(...) should add or update data at any point (so that potentially you can do what you want), I am not sure how this will influence your particular strategy, for example your indicators.

As for your second question... have you seen this FAQ ?

http://www.smartquant.com/forums/viewtopic.php?t=6277

Regards,
Anton


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 19, 2009 12:04 am 
Offline

Joined: Mon Mar 05, 2007 7:02 am
Posts: 58
Anton - Thanks for the prompt response. The prompt responses to questions in the forums makes the software much more useful for new users like myself.

It looks like I should be able to do what I am trying to do. I had not seen the FAQ item you referenced.

Regards,
Eric


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 14, 2009 1:13 pm 
Offline

Joined: Sat Jul 04, 2009 3:58 am
Posts: 10
Is it possible to use "for(i=0;i<...;i++)" loop instead of "foreach" in example mentioned above?
Thx


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 14, 2009 7:42 pm 
Offline

Joined: Tue Aug 05, 2003 3:43 pm
Posts: 6816
Yes, why not?

BarSeries series = GetHistoricalBars(datetime1, datetime2, BarType.Time, 86400);

Code:
for (int i=0; i < series.Count-1; i++)
{
   Bar bar = series[i];

    ...

}


Regards,
Anton


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 05, 2009 1:20 am 
Offline

Joined: Sat Aug 01, 2009 10:37 pm
Posts: 15
For sim mode, I think this works:

Code:
   if (Mode == StrategyMode.Simulation)
      datetime2 = StartDate;
   else
      datetime2 = DateTime.Now;
      datetime1 = datetime2.AddDays(-15);


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 32 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC + 3 hours


Who is online

Users browsing this forum: No registered users and 2 guests


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:  
cron
Powered by phpBB® Forum Software © phpBB Group