SmartQuant Discussion
http://www.smartquant.com/forums/

How to develop spread / pair trading strategies in OpenQuant
http://www.smartquant.com/forums/viewtopic.php?f=64&t=6566
Page 1 of 3

Author:  Dr. Anton Fokin [ Tue Mar 25, 2008 5:07 pm ]
Post subject:  How to develop spread / pair trading strategies in OpenQuant

OpenQuant runs one instance of a strategy per instrument. This concept simplifies strategy development a lot since you always refer to one instrument (Strategy.Instrument) in your code and don't need to maintain arrays and tables holding different values (for example indicator) per instrument. It works pretty well for instrument independent staregies, i.e. for strategies that can run with one instrument, for example trend following or swing trading strategies, but you need to utilize certain techniques if you want to develop strategies that depend on two or more instruments, for example spread, pair trading. market neutral or correlation based strategies.

Assume we want to develop a strategy that buys qty of MSFT and sells qty of AAPL if MSFT / AAPL price ratio becomes larger that certain number X.

Code:
OnBar(Bar bar)
{
  Instrument instrument = Instruments["MSFT"];

  if (nstrument.Bar.Close / bar.Close > X)
  {
    Buy(qty);
    Sell(instrument, qty);
  }
}

You can also define instruments in the header of your strategy to speed things up

Code:
Instrument instrument1 = InstrumentManager.Instruments["MSFT"];
Instrument instrument2 = InstrumentManager.Instruments["AAPL"];

OnQuote(Quote quote)
{
  if (Instrument == instrument1)
    if (quote.Ask > instrument2.Quote.Bid * delta)
    {
       Buy(instrument1, qty);
       Sell(instrument2, qty);
     }
}

Note that you can also use OnBarSlice event handler.

Quote:
OnBarSlice fires whenever the market data provider BarFactory has finished emitting new bars for all the instruments in the current portfolio. BarFactory emits new bars sequentially when multiple instruments are being traded—first a bar for instrument 1, then a bar for instrument 2, and so on. After all individual bars have been emitted, BarFactory will fire OnBarSlice to tell strategy components that the end of the instrument list has been reached, and that all new bars for the current bar interval have been emitted. OnBarSlice solves the problem of strategy code not knowing when all the instrument bars for a correlation strategy are present and ready to be used. For example, if you try to do correlation calculations in the OnBar event handler for multiple instruments, your code will have to keep track of which instruments have been seen in the OnBar handler for the current bar time interval.


Code:
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 (spread > bbu.Last)
            {
               Sell(CSCO, Qty);
               Buy(DELL, Qty);
            }
         }
      } 
   }
}

Author:  The Kid [ Thu Nov 06, 2008 7:28 pm ]
Post subject: 

Hi Anton,

Just started looking at OQ today. I like the fact you suppost multi instrument strategies. As part of that do you support Scatter plots?
ie plots where the y axis is one instrument and the x axis is another (rather than time).

As an example I would reffer you to the scatter plot functinality in excel which in addition to plots also provides regression (linear, poly and exponential) capabilities. It's an invaluable tool to the spread trader, please tell me you have this. :)

Thanks so much

Author:  jackla [ Mon Feb 02, 2009 11:10 am ]
Post subject:  Why there is no lines in the 3rd chart pad?

I copied and paste the last code (the one with OnBarSlice event handler) and ran it. But the 3rd chart pad is blank (see attachement). Why the SMA, BBU, BBL, and spread were not shown? I'm niebie. Please forgive me if this question is too simple.

Thanks a lot!

Attachments:
File comment: strategy chart
pairtrade.JPG
pairtrade.JPG [ 70.32 KiB | Viewed 19840 times ]

Author:  Alexei Kurov [ Tue Feb 03, 2009 2:27 pm ]
Post subject: 

Hi,

The reason is SMA,BBU and BBL are calculated from 'spread_series', but this series is empty for DELL and is populated in a case of CSCO only.
Please, look into code...
Code:
if (Instrument == CSCO)
{
     double spread = CSCO.Bar.Close / DELL.Bar.Close;
     spread_series.Add(CSCO.Bar.DateTime, spread);



Regards,
Alex

Author:  Alexei Kurov [ Tue Feb 03, 2009 2:33 pm ]
Post subject: 

...

Attachments:
spread_chart.gif
spread_chart.gif [ 60.63 KiB | Viewed 19830 times ]

Author:  jackla [ Sun Feb 22, 2009 4:40 pm ]
Post subject:  draw both stocks in a chart?

Is it possible to draw both stocks' candlestick charts together? Of course they can be into different panes.

Author:  Dr. Anton Fokin [ Sun Feb 22, 2009 9:56 pm ]
Post subject: 

Hi,

in principle yes, but on a separate canvas that you invoke from the startegy code.

Regards,
Anton

Author:  lg4to32 [ Wed Apr 22, 2009 11:48 am ]
Post subject: 

then how to do that? to draw the all instruments bar on the separate chart
if i use GetBars what happen is they draw 2 different instruments on the same chart

public override void OnStrategyStart()
{
KOSPI = Instruments["KOSPI001"];
BarsKospi = new BarSeries("KOSPI001");
BarsKospi = GetBars(KOSPI,60);

ES = Instruments["ES001"];
BarsEs = new BarSeries("ES001");
BarsEs = GetBars(ES,60);
}

public override void OnBar(Bar bar)
{
if (Instrument == ES)
{
BarsEs.Add(bar);
}

if (Instrument == KOSPI)
{
BarsKospi.Add(bar);
}
}

any help is appreciated ^^

Regards,
lg4to32

Author:  grandcanuck [ Tue May 19, 2009 7:59 pm ]
Post subject: 

I've been using my trial time to see if I can work a pairs model...

Dr. Anton Fokin wrote:
Hi,

in principle yes, but on a separate canvas that you invoke from the startegy code.

Regards,
Anton


I got some of it going but I am having a hard time working the Charts and Canvas. So far I have the indicators I wants but the Bar chart at the top always has the first symbol only. Can I overlay to bar charts together and see prices of both instruments on the same chart. I would need an example or something I guess.

I tried the same approach as lg4to32 but it didn't work.

Author:  TomTom [ Fri May 22, 2009 5:03 pm ]
Post subject:  Re: How to develop spread / pair trading strategies in OpenQ

Anton,
I think the coding of this strategy has the same problem as the one I have on my market breadth indicator. How do we know the spread between "ES" and "GOOG" is calculated on the same bar?

Am I wrong on this? Please clarify. Thanks!

Tom

Author:  Dr. Anton Fokin [ Sun May 24, 2009 10:09 am ]
Post subject: 

Hi,

you should calculate the spread in OnBarSlice event handler then.

Regards,
Anton

Author:  jackla [ Fri May 29, 2009 2:24 pm ]
Post subject:  Frame Work Problem?

It seems that for each instrument in a strategy, there is a separate of states that can not talk to the other clones related to other instruments. Then I don't know how to develop a strategy that involves multiple instruments and several orders that will be placed one by one. Following code won't work:
Code:
...
public class MyStrategy : Strategy
{
  int state=0;
//...

    public override void OnOrderFilled(Order order)
    {
        switch (state)
        {
            case 0:   //1st order is filled
                state = 1;
                //sth to do after the 1st order is placed;
                //...;
                break;
            case 1:   //2nd order is filled,
                state = 2;
                 //sth to do after the 2nd order is placed;
               //...;
                break;
            case 2:   //3rd order is filled,
                state = 2;
                 //sth to do after the 3rd order is placed;
            }
 }


if the 2nd order is on an instrument (instrument2) different from that (instrument1) in the 1st order, the member variable "state" will stay the original value 0 instead of the new value 1. actually there is a "state" with the new value 1, after the 1st order is filled. But that variable is in the variable set related to the instrument1 and can not be seen in this event "OnOrderFilled", because this is the event for instrument2, which has a completely different set of variables.

Is there any way to let the codes aware of something related to another instrument happened?

Author:  Dr. Anton Fokin [ Fri May 29, 2009 7:45 pm ]
Post subject: 

There is one instance of Strategy class for each instrument. The only way to pass data from one instance to another is to use static variables.

Regards,
Anton

Author:  VovaM [ Sun Jul 05, 2009 1:12 pm ]
Post subject:  OnBarSlice potential problem

For ex. we have two instruments with irregularities in bar series (liquid EURUSD and illiquid forex pair NOKEUR; sometimes we do not have bar for NOKEUR pair at the same time we always have one for EURUSD):

time\EURUSD OHLC bar\NOKEUR OHLC bar\ OnBarSlice event
10:00 \ yes \ yes \ yes
10:01\ yes \yes \ yes
10:02 \yes \ NO \ NO
10:03 \yes \yes \ yes

is this correct model "model" of onBarSlice event behavior?

Author:  Dr. Anton Fokin [ Sun Jul 05, 2009 2:33 pm ]
Post subject: 

Hi,

we will discuss it with Sergey on Monday.

Regards,
Anton

Page 1 of 3 All times are UTC + 3 hours
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/