SmartQuant Discussion

Automated Quantitative Strategy Development, SmartQuant Product Discussion and Technical Support Forums
It is currently Sat Feb 07, 2026 6:49 am

All times are UTC + 3 hours




Post new topic Reply to topic  [ 34 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
PostPosted: Mon Aug 06, 2007 2:18 am 
Offline

Joined: Thu Aug 02, 2007 2:47 am
Posts: 17
hi there..i'm still struggling to find/get a working strategy example of buying and selling a pair of securities (with entry and exit rules) .... does anyone have a working example? i tried to modify the bollinger example but cud'nt get past buying at the lower BBL limit without getting errors....


using System;
using System.Drawing;

using OpenQuant.API;
using OpenQuant.API.Indicators;

public class MyStrategy : Strategy
{
Instrument DELL;
Instrument CSCO;

TimeSeries spread_series;

[Parameter("Order quantity (number of contracts to trade)")]
double Qty = 100;

[Parameter("Length of SMA")]
int SMALength = 20;

[Parameter("Order of BBL")]
double BBLOrder = 2;

// indicators
BBL bbl;
SMA sma;


public override void OnStrategyStart()
{
DELL = Instruments["DELL"];
CSCO = Instruments["CSCO"];

spread_series = new TimeSeries("DELL - CSCO", Color.Pink);

// set up the moving averages
sma = new SMA(spread_series, SMALength);
sma.Color = Color.Yellow;
Draw(sma, 2);
// set up bollinger bands
bbl = new BBL(spread_series, SMALength, BBLOrder);
bbl.Color = Color.Green;
Draw(bbl, 2);
Draw(spread_series, 2);

}

public override void OnBarSlice(long size)
{

if (Instrument == CSCO)
{
double spread = CSCO.Bar.Close / DELL.Bar.Close;
spread_series.Add(CSCO.Bar.DateTime, spread);

if (!HasPosition)
if (spread < bbl.Last)
{
Buy(CSCO, Qty);
Sell(DELL, Qty);
}
}
}
}


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 06, 2007 5:25 pm 
Offline

Joined: Tue Aug 05, 2003 3:43 pm
Posts: 6817
What's the error?

Regards,
Anton


Top
 Profile  
 
 Post subject: OnBarSlice
PostPosted: Mon Aug 06, 2007 7:44 pm 
Offline

Joined: Thu Aug 02, 2007 2:47 am
Posts: 17
strategy error
Array has no elements

im having a hard time lifting/modifying examples from documentation because there really are'nt any working strategies in docs that use OnBarSlice. i want reference either a moving average or bollinger band (of the spread series) to trigger a buying and selling of the spread ..likewise i would use it to exit the trade as well. it tried using sma, crosses etc but got errors saying bar reference was invalid...


Top
 Profile  
 
PostPosted: Thu Aug 09, 2007 2:58 am 
Offline

Joined: Thu Aug 02, 2007 2:47 am
Posts: 17
Pretty Please

Section 4.7 (Spread and Volatility Trading Strategies) of the "Open Quant Strategy Development Manuel" clearly lays out a simple spread trading strategy which is my main motivation in using this powerful software. What kills me tho is the last paragraph (just before section 4.7.1) which abrubtly decides not to show us the spread strategy just described in detail but rather to swap over to a single security strategy example. (such a tease!! i thought i was nearly there!!) Is there any way we can see the spread strategy example that was described in section 4.7? it would be a great inclusion as a sample strategy since you've already described it quiet nicely and it is exactly what I'm looking for.
thanks again


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 09, 2007 10:44 am 
Offline

Joined: Tue Aug 05, 2003 3:43 pm
Posts: 6817
Hi,

it looks like this strategy is taken from QuantDeveloper doc and it uses so called CrossComponent strategy model that is not supported in OpenQuant. Our strategy development guru will come back from vacation on Monday and I will ask him to rewrite this strategy using OnBarSlice technique.

Regards,
Anton


Top
 Profile  
 
 Post subject: excellent
PostPosted: Tue Aug 14, 2007 1:04 am 
Offline

Joined: Thu Aug 02, 2007 2:47 am
Posts: 17
excellent! i'm looking fwd to getting a spread strategy up and running! many thanks in advance.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 15, 2007 11:01 am 
Offline

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

You should paste the following lines before the "if(!HasPosition)" line in the OnBarSlice method:
Code:
if (bbl.Count == 0)
    return;


The error is thrown when the strategy tries to get the Last element from the empty bbl series.

Regards,
Sergey.


Top
 Profile  
 
 Post subject: Sergey
PostPosted: Wed Aug 15, 2007 6:44 pm 
Offline

Joined: Thu Aug 02, 2007 2:47 am
Posts: 17
thanks now i can get in..how would i handle the exit using similar rules..im assuming i have to keep using OnBarSlice rather than OpenPosition? cant seem to get it....

using System;
using System.Drawing;

using OpenQuant.API;
using OpenQuant.API.Indicators;

public class MyStrategy : Strategy
{
Instrument DELL;
Instrument CSCO;

TimeSeries spread_series;

[Parameter("Order quantity (number of contracts to trade)")]
double Qty = 100;

[Parameter("Length of SMA")]
int SMALength = 20;

[Parameter("Order of BBU")]
double BBUOrder = 2;

[Parameter("Order of BBL")]
double BBLOrder = 2;

// indicators
BBU bbu;
BBL bbl;
SMA sma;


public override void OnStrategyStart()
{
DELL = Instruments["DELL"];
CSCO = Instruments["CSCO"];

spread_series = new TimeSeries("DELL - CSCO", Color.Pink);

// set up the moving averages
sma = new SMA(spread_series, SMALength);
sma.Color = Color.Yellow;
Draw(sma, 2);
// set up bollinger bands
bbu = new BBU(spread_series, SMALength, BBUOrder);
bbu.Color = Color.Green;
bbl = new BBL(spread_series, SMALength, BBLOrder);
bbl.Color = Color.Green;
Draw(bbu, 2);
Draw(bbl, 2);
Draw(spread_series, 2);

}

public override void OnBarSlice(long size)
{

if (Instrument == CSCO)
{
double spread = CSCO.Bar.Close / DELL.Bar.Close;
spread_series.Add(CSCO.Bar.DateTime, spread);
if (bbl.Count == 0)
return;
if (!HasPosition)
if (spread < bbl.Last)
{
Buy(CSCO, Qty);
Sell(DELL, Qty);
}
else

if (bbu.Count == 0)
if (spread > bbu.Last)
{
Sell(CSCO, Qty);
Buy(DELL, Qty);
}
}
}
}


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 16, 2007 2:24 pm 
Offline

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

This code works fine on my machine:
Code:
 if (Instrument == CSCO)
      {
         double spread = CSCO.Bar.Close / DELL.Bar.Close;
         spread_series.Add(CSCO.Bar.DateTime, spread);
         
         if (bbl.Count == 0)
            return;
         
         if (!HasPosition)
         {
            if (spread < bbl.Last)
            {
               Buy(CSCO, Qty);
               Sell(DELL, Qty);
            }
         }
         else
         {
            if (spread > bbu.Last)
            {
               Sell(CSCO, Qty);
               Buy(DELL, Qty);
            }
         }
      } 


Regards,
Sergey.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 20, 2007 8:57 am 
Offline

Joined: Thu Mar 16, 2006 12:15 pm
Posts: 184
Where to find the QD-Manual?

_________________
Expect the unexpected. May your MM/RM be with you.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 20, 2007 9:20 am 
Offline

Joined: Tue Aug 05, 2003 3:43 pm
Posts: 6817
fliesch wrote:
Where to find the QD-Manual?


www.quanthouse.com ...


Top
 Profile  
 
PostPosted: Wed Aug 29, 2007 9:12 pm 
Offline

Joined: Thu Aug 02, 2007 2:47 am
Posts: 17
was wondering if u had the Pair Trading Example from QD docs using OnBarSlice version translated yet? thanks


xxxxxxxxxxxxxxxxxxxxxxxxxx

Hi,

it looks like this strategy is taken from QuantDeveloper doc and it uses so called CrossComponent strategy model that is not supported in OpenQuant. Our strategy development guru will come back from vacation on Monday and I will ask him to rewrite this strategy using OnBarSlice technique.

Regards,
Anton


Top
 Profile  
 
 Post subject: i give up....u win
PostPosted: Sun Sep 09, 2007 11:00 pm 
Offline

Joined: Thu Aug 02, 2007 2:47 am
Posts: 17
i give up....u win


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 11, 2007 5:18 pm 
Offline

Joined: Wed Oct 08, 2003 1:06 pm
Posts: 833
Hi, I thought that you don't need additional samples after our corrections/discussions of the strategy above. Seems I was wrong.

Here is the "Unilateral Pairs Trading" strategy that shows how to use OnBarSlice techique and to implement a spread trading strategy. Note that it will work only in the next version because it requires tiny changes in the source code.

Code:
using System;
using System.Drawing;

using OpenQuant.API;
using OpenQuant.API.Indicators;

public class MyStrategy : Strategy
{
   // ratio series
   // Each day, the ratio is calculated and added to this series
   private TimeSeries ratioSeries;
   // sma of ratio series
   // Then we take a simple moving average of the daily ratios
   private SMA smaRatio;
   // diff between ratio series and sma of ratio series
   // Then we calculate the daily volatility of the ratio against the
   // simple moving average of itself, to see how far off normal it is.
   // Each day, the diff = ratio – moving average is put into this seies
   private TimeSeries diffSeries;
   // sma of diff between ratio series and sma of ratio series
   // Next we calculate a moving average of the differences
   private SMA smaDiff;
   // standard deviation of diff between ratio series and sma of ratio series
   // Finally we calculate a standard deviation for each daily diff value.
   // This value says how many standard deviations the current diff value is
   // from the normal mean (from the sma of the diff). If this number gets
   
   // to be too big, then the strategy enters a trade.
   private SMD smdDiff;
   // Number of contracts to order
   [Parameter("Order quantity (number of contracts to order)")]   
   public double Qty = 100;
   // Upper and lower bounds of Standard Deviation
   // Strategy opens a position when current ratio value is more
   // than 1.5 standard deviations from the mean.
   [Parameter("Entry StdDev Upper Bound")]
   public double EntryUpperStdDev = 1.5;
   [Parameter("Entry StdDev Lower Bound")]
   public double EntryLowerStdDev = -1.5;
   // Strategy closes a position when ratio value returns to
   // being within 0.5 standard deviations from the mean
   [Parameter("Exit StdDev Upper Bound")]
   public double ExitUpperStdDev = 0.5;
   [Parameter("Exit StdDev Lowe Bound")]
   public double ExitLowerStdDev = -0.5;
   // Upper and lower bounds of Percent
   private double upPercent = 2;
   private double downPercent = 2;
   private double mainLast = -1;
   private double secondLast = -1;
   [Parameter("Main Symbol")]
   public string MainSymbol = "QQQQ";
   [Parameter("Second Symbol")]
   public string SecondSymbol = "SPY";
   private Instrument mainInstrument; // reference the QQQQs
   private Instrument secondInstrument; // trade the SPYs
   private double mainPrev;

   // The initialization routine creates various objects and attaches
   // them to the class variables. It also specifies what lines to
   // draw on the QD bar chart.
   public override void OnStrategyStart ()
   {
      if (Instrument.Symbol == MainSymbol)
      {
         // create series objects and moving average objects
         ratioSeries = new TimeSeries ("Ratio");         
         diffSeries = new TimeSeries ();
         smaRatio = new SMA (ratioSeries, 20);
         smaDiff = new SMA (diffSeries, 20);
         smdDiff = new SMD (diffSeries, 20);
         // get references to SPY and QQQQ from instrument manager
         mainInstrument = InstrumentManager.Instruments[MainSymbol];
         secondInstrument = InstrumentManager.Instruments[SecondSymbol];
         // specify drawing colors and barchart pad locations
         smaDiff.Color = Color.Yellow;
         smdDiff.Color = Color.Yellow;
         smaRatio.Color = Color.Pink;
         ratioSeries.Color = Color.Yellow;
         
         Draw (ratioSeries, 2);
         Draw (smaRatio, 2);
         Draw (smdDiff, 3);
      }
   }

   public override void OnBarSlice (long barSize)
   {
      if (Instrument == mainInstrument)
      {
         // wait for first bars for each instrument
         if (mainInstrument.Bar == null || secondInstrument.Bar == null)
            return;
         
         mainPrev = mainLast; // yesterday’s SPY closing value
         mainLast = mainInstrument.Bar.Close; // today’s SPY closing value
      
         secondLast = secondInstrument.Bar.Close;      
      
         DateTime date = mainInstrument.Bar.DateTime;
         // if we have ratio values to work with
         if (mainLast != -1) {
            // calculate today’s ratio and add the ratio to the ratio series
            double ratio = mainLast / secondLast;
         
            ratioSeries.Add (date, ratio);
         
            // if there are values in the moving average series,
            // calculate diff between today’s ratio and its moving average,
            // then add the difference value to the diff series
            if (smaRatio.Count > 0)
               diffSeries.Add (date, ratio - smaRatio[date]);
         }
         // if we have no moving average of ratio-ratioSMA diff values,
         // we can’t do anything yet, so return
         if (smaDiff.Count == 0)
            return;
         // if we reach this point, we have a moving average of ratio-ratioSMA
         // to work with. This moving average lets us calculate std deviations.
         // compare todays diff (diffseries) with the SMA of diffs (smaDiff)
         // and divide by the standard deviation (smdDiff) denominator
         // Now we can tell if the current ratio is way off normal.
         double stdDev = (diffSeries[date] - smaDiff[date]) / smdDiff[date];
         // if we have no existing position, see if you can enter a trade
         if (Portfolio.Positions[mainInstrument.Symbol] == null) {
            // if current ratio-smaDiff is more than 1.5 standard deviations
            // from the mean, open a position (either long or short)
            if (stdDev > EntryUpperStdDev
               && (mainLast - mainPrev) / mainPrev >= upPercent / 100)
               SendOrder (OrderSide.Sell);
            if (stdDev < EntryLowerStdDev
               && (mainLast - mainPrev) / mainPrev <= -downPercent / 100)
               SendOrder (OrderSide.Buy);
         }
            // else if we already have an open position, try to close it if
            // current ratio-smaDiff value has returned inside 0.5 standard
            // deviations from the mean
         else {
            if (Portfolio.Positions[mainInstrument.Symbol].Side ==
            PositionSide.Short) {
               // if you are short, buy to close the position
               if (stdDev < ExitUpperStdDev)
                  SendOrder (OrderSide.Buy);
            }
            else {
               if (stdDev > ExitLowerStdDev)
                  SendOrder (OrderSide.Sell);
            }
         }
      }
   }

   // this is a helper method to open or close a position, using
   // a market order
   private void SendOrder (OrderSide side) {
      Order order = MarketOrder(mainInstrument, side, Qty);
      order.Send ();
   }
}


Regards,
Sergey.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 11, 2007 11:49 pm 
Offline

Joined: Thu Mar 16, 2006 12:15 pm
Posts: 184
When will this newer version be avaible? Is "bilateral" pairtrading possible?

_________________
Expect the unexpected. May your MM/RM be with you.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 34 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 13 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:  
Powered by phpBB® Forum Software © phpBB Group