Back

Migrating from Quantopian to QuantConnect

In this thread, we are going to cover the differences between Quantopian and QuantConnect APIs.

Basic Algorithm
In QuantConnect, all algorithms must have an Initialize method to setup your strategy. Once setup most algorithms have OnData event handlers to process market data and make trading decisions:

# Quantopian
def initialize(context):
    # Reference to AAPL
    context.aapl = sid(24)

def handle_data(context, data):
    # Position 100% of our portfolio to be long in AAPL
    order_target_percent(context.aapl, 1.00)
# QuantConnect

class MyAlgo(QCAlgorithm):
    def Initialize(self):
    # Reference to AAPL
        self.aapl = self.AddEquity("AAPL")

    def OnData(self, data):
        # Position 100% of our portfolio to be long in AAPL
        self.SetHoldings("AAPL", 1.00)

Please note that we must define a class with the QuantConnect API and it must inherit from QCAlgorithm.
self refers to the instance attributes of the algorithm class. It is used to access methods and members of QCAlgorithm like AddEquity in the example above.

Update Backtest






The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.



@Lukel 

 - You would need to merge the current day/minute/hour's bar to create the final one for your indicator if you want it dynamically updated intra-bar. It sounds like work.. the easiest way would probably be to create a rolling window and re-create the indicator each time.
 - Currect in QC anytime there's a bar count its refering to the market open bars so that code should be transportable.

0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


In QC, is there an equivalent of Quantopian's data.can_trade before placing an order? Or is it not necessary in QC?

4

Hi guys, 

Thank you for helping us to switch from Qantopian to QC.

How can I follow the leverage ? On Q I was using:

record(Leverage = context.account.leverage)
0

If anyone is having trouble porting their code over from Quantopian, one thing that I discovered was causing a lot of errors was the whitespace. Quantopian didn't have a problem using 4 spaces as equivalent to tab, and mixing both methods but when you copy that code over QC has trouble reading it.

My solution was to go into a text editor like notepad++, enable "view tabs and whitespaces" and then change all space indents to tabs. That fixed a lot of problems that were hard to pin down. Also on QC the indents matter on blank lines, if you have a function with a blank line in it QC ends that function at the blank line. You need to indent your blank lines to the correct level so that QC will continue recognizing the rest of the function. These errors don't always get picked up in the text editor, you only see the real effect during the backtest with a mysterious error.

2

Thank you for mentioning it LukeI - if possible please send examples (support@quantconnect.com) as we're trying to create a code solution to the "white space issue" :) 

Chris D - We limit leverage for you like a real broker would do. To make it close to Quantopian's behavior you could set the leverage very high so you can trade without limits. Leverage for each security is set when you add the asset. 

Internally this is modelled as margin used. Each holding on leverage takes a cash position/margin to hold. At the time of purchase this is called "Initial Margin". To hold a position you need a "Maintenance Margin" fraction which is often lower than the initial margin. Margin is a good way of modelling multiple security types in a single portfolio as some assets have a fixed margin-requirement per contract (vs leverage which is variable on portfolio value).

Instead of following "total leverage" which only applies to a Equities-only portfolio of fixed leverage per asset; you should probably track TotalMarginUsed --> Portfolio.TotalMarginUsed. Perhaps one of the community or team will have a better idea here of what could be equivalent.

1

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


@Lukel, you could also use Ctrl+H and use the Replace All to replace all 4 consecutive spaces with a tab. This is what I do each time. Find/Replace is actually a very helpful functionality that I don't believe was available in the Quantopian IDE

1

Do you or any members here offer any algo coding service? Tutorials are a great effort but finding time to learn this all over again is problematic. I'd pay to have my algo ported.

ps. What if QC offered free algo rewrite for Quantopian members with a 1yr subscription to QC?

0

@Jared Broad - Thank you for your response. I will try to adapt this method.

0

Hi,

I'm also a migrant from Quantopian. I guess this forum is the one we migrants need. Please help us. I will learn from you guys and hopefully rebuild my algos here. :)

0

Thank you Vladimir its an interesting idea and appreciate the sentiment. We'll keep it in mind. Ideally we'd like to highlight the community members who can help with this.

0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Hi,

def OnData(self, slice):

history = self.History(self.security_list, 40, Resolution.Daily)
history_mean = history['close'].mean()
self.log(str(history_mean))

I tried the above and got 'Build Request Successful'. But failed to do the backtest. What went wrong? I just wanted to see logs of 'mean' of the securities for the past 40 days. Help me! Thanks.  

0

Hi,

self.Schedule.On(self.DateRules.EveryDay(self.security_list),
self.TimeRules.AfterMarketOpen(self.security_list, 60),
Action(self.OnData))

1). Can we do this? 'Action(self.OnData))' ?

2). Do we need to put all the trading orders under the 'OnData(self, data)'? or can we do so under anywhere we want (e.g. def rebalance(self), ...)?

Thanks.

0

HanByul P, could you please open a new thread with your question and share the algorithm instead of code snippets?
Answering the last two questions:
1. No. System.Action encapsulates a method that has no parameters and does not return a value. OnData has one parameter.
2. Also no. You can place orders in method of the algorithm. In OnData is "special" because it is a entry point of new data and the Slice object was designed to deliver a snapshot of the market at a given time. However, the Security object also has pricing data, so if we need the price for placing an order, we can use it:

# In OnData(self, slice)
price = slice["SPY"].Close

# In any method
price = self.Securities["SPY"].Price
0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


@Alexandre Catarino, Thanks a lot.

I will have many more questions: In Quantopian, we did this as below.

# Quantopian

# For checking our leverage and counting longs/shorts
def my_record_vars(context, data):

longs = shorts = 0
for position in context.portfolio.positions.itervalues():
if position.amount > 0:
longs += 1
if position.amount < 0:
shorts += 1

record(leverage=context.account.leverage, \
Long_Count=longs, Short_Count=shorts)
In Quantopian, the 'record' function plots what we want to see as above in the backtest screen. In the QC's backtest, I see a plot of 'Daily Performance' below the equity performance chart. Just like a 'Daily Performance', I want to see leverage and counting of all the numbers of longs and shorts in the backtest screen..Can we do this in QC? Thanks.
0

We have addressed Charting in QuantConnect in this thread. Here is the comment with a working example:

https://www.quantconnect.com/forum/discussion/2317/migrating-from-quantopian-to-quantconnect/p1/comment-7000

The account leverage for Equity can be calculated by the ratio between Portfolio.TotalAbsoluteHoldingsCost and Portfolio.TotalPortfolioValue:

account_leverage = self.Portfolio.TotalAbsoluteHoldingsCost / self.Portfolio.TotalPortfolioValue
1

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


@HanByul P, (and others)

I spent MANY hours struggling with this until I figured out the trick: QC's historical data is given in a multiindex dataframe like this:

                    open    high    low    close   volume
spy 2017-1-1 00:00  101.00  105.00  99.00  100.00  123456
    2017-1-2 00:00  101.00  105.00  99.00  100.00  123456
    2017-1-3 00:00  101.00  105.00  99.00  100.00  123456
qqq 2017-1-1 00:00  201.00  205.00  199.00 200.00  123456
    2017-1-2 00:00  201.00  205.00  199.00 200.00  123456
    2017-1-3 00:00  201.00  205.00  199.00 200.00  123456

 

So when you use history["close"].mean() it gives you the mean of all the close prices of all the stocks averaged together. In my example it would give you a value of 150.00 which is useless to us. In order to get the data into quantopian format (for use with the quantopian code) You need to pick an OHLCV value then unstack the multiindex dataframe so that each stock becomes it's own column like this:

History = self.History(stocks, 20, Resolution.Daily)["close"].unstack(level=0)

                spy     qqq
2017-1-1 00:00  100.00  200.00
2017-1-2 00:00  100.00  200.00
2017-1-3 00:00  100.00  200.00

So now you can use .mean() which would give you values of SPY = 100.00 and QQQ = 200.00

I'm sure there's a better way to do it in a pure QC way but .unstack(level=0) pretty much gives you plug and play with quantopian code.

1

Great suggestion LukeI!

To keep this thread focused on specific migration tips I'll close it for now. If anyone has a migration tip contact us and we'll re-open to add your suggestion/addition so others reading the thread can get the most condensed information possible. 

0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Update Backtest





0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Loading...

This discussion is closed