CloudQuant API vs. Quantopian API

ms778834ms778834 Posts: 28
edited March 2017 in Onboarding Help

Hey fellow quants!
Is there anyone who ported their algorithm(s) from Zipline/Quantopian? I would love to have a comparison of both APIs, as the CloudQuant's one is very different and the documentation here is quite poor - isn't there a one-to-one compilation of API calls from both platforms?
Does CQ have an equivalent of Zipline's context for the global variables?

My next question is related to portfolio rebalancing: how to do that? I need to use an equivalent of order_target_percent, but position_size only sets absolute number of shares, not the relative one, i.e. the percentage of portfolio's value to be allocated in a particular stock.

BTW, server's time is 13 minutes delayed; also, many of the Public Scripts do not load (College_Challenge, for example). And one cannot delete all backtest results at once ('DELETE ALL' does not work)! :-/


  • shayneshayne Posts: 70

    Martin -

    • Superquant can probably answer a lot of you zipline related questions
    • It's my understanding you have access to both the fast and full simulator, where fast evaluates your code on minute bars. Full simulation evaluates on a lot of available market data, like every trade.
    • from your perspective, how can we improve the documentation?
    • thanks for the heads-up on server's time being off
    • can you elaborate on "many of the Public Scripts do not load"? is that in the editor (like the page stays blank)?
    • we added a ticket for "delete all" not working

    Thanks for the feedback

  • Hi Martin,

    I believe the following two examples would probably realize the functionality of global variable: context in zipline:

    from cloudquant.interfaces import Strategy
    class solution_1_for_Martin(Strategy):
        # Suppose you want to make a strategy on 'AAPL' but need 'SPY' price info
        def is_symbol_qualified(cls, symbol, md, service, account):
            return symbol == 'AAPL'
        def backtesting_extra_symbols(cls, symbol, md, service, account):
            return symbol == 'SPY'
        def on_start(self, md, order, service, account):
            # Collect the most recent 5D daily bar of SPY
            recent_5d_spy_price_bar = md['SPY'].bar.daily(start=-5)
            # Print daily high of SPY on last available trading day
            print recent_5d_spy_price_bar.high[-1]

    The example above would let you query market data of other symbols within an instance, which is very useful for pairs-trading-like strategies.

    from cloudquant.interfaces import Strategy
    class solution_2_for_Martin(Strategy):
        # Suppose you would like to set up a variable to store information that could be shared by all strategy instances
        # shared_data would be a class variable
        shared_data = dict(zip(['BABA','AAPL','BAC','GOOG','C'],[1,2,3,4,5]))
        def is_symbol_qualified(cls,symbol,md,service,account):
            return symbol in ['BABA','AAPL','BAC','GOOG']
        def on_start(self, md, order, service, account):
            # call the class variable of solution_2_for_Martin
            print self.__class__.shared_data[self.symbol]

    The second example illustrates how you could setup general class/global variables that can be shared by all instances. You may also read your user files in on_strategy_start to do so, e.g. cls.shared_data = service.read_file(my_user_file_name). The class variable in class methods could be reached via: cls.shared_data while in other object level methods via: self.__class__.shared_data.

    Hope that helps you to build the strategy!

  • ms778834ms778834 Posts: 28

    Shayne, all of the Public Scripts seem to load now, including the College_Challenge. Previously, I was getting an error message which read "Could not fetch data for publicuser!", or something similar.

    Concerning the documentation, it is well categorised, nevertheless, what I am missing is more top-down approach→ with Quantopian, one can use some neat one-liners to express what he wants; CQ is much more complex. I appreciate the freedom it gives me, but my algorithm is not an HFT one, and I have yet a lot to learn, being only 21 yo. For example, working with and retrieving data and/or placing orders is much easier in Quantopian, or at least it seems to me like that. Maybe it is just that I am not used to CQ yet.

    John, thank you for the code; unfortunately, I can't tell you how much it has helped me, as I am waiting for statsmodels to be installed to be able to run my script.

    Anyway, when statsmodels is up and running, would any of you guys have time to help me implement parts which I might have trouble with? I assume both of you work for KTG, so we could just connect on Skype and share screens ;-)
    My algo's got 4.6 Sharpe, 8.56 Sortino and 23% p.a. with only 1.98% DD, and β .019 over a 4-month $30M paper trading period.

  • superquantsuperquant Posts: 28
    edited March 2017

    Hi Martin,
    We are in the process up upgrading our user onboarding and educational content that will give you a more top-down approach to learning. We appreciate you feedback and patience.

    statsmodel is now installed as requested.

    As a fellow developer we value your input and are working to fill in the gaps you have pointed to. Keep the ideas coming.

  • tb210201tb210201 Posts: 5

    Quantopian is a contest and they completely changed their documentation at one point and it seemed confusing. Also you can only enter when the contest starts to be counted. Not that contest are bad but it would be nice to have a contest against yourself without some specific date.

  • ms778834ms778834 Posts: 28
    edited August 2017

    Tradertb123 Well, APIs change, even here. And contests are great, especially if you are the winner! :grimace:

    Now I would like to know an optimal way to make my algorithm order shares according to the amounts specified in such pandas DataFrame ↓

    IBM     -2998420
    CSCO    -1098563
    FB      -9692346
    MSFT     9788660
    GOOGL    307225
    AAPL     52790609
    BABA    -551919
    GOOG    -456599
    The sign specifies direction (minusorder.algo_sell(), plusorder.algo_buy()). With Quantopian, Zipline converts that for you; CloudQuant, on the other hand, takes an absolute value, so position_size= -2998420 automatically becomes position_size=2998420, same with order_quantity. Isn't there something like order.determine_direction()?
    And my 2nd question is: why is there the intent parameter, and can I omit it in live trading?
  • tdraughontdraughon Posts: 14

    Intent = a rational check to ensure that the algo is either increasing or decreasing or exiting or entering. It serves as a safety check on the algo.

    As for the optimal way to buy or sell.... that somewhat depends upon your strategy. Some strategies are OK with a market algo_buy or algo_sell. Other strategies want to use limit orders. In the documentation under "Reference" you will find a number of "Order Algos".

    These are useful for entering larger positions like what you are showing in your question. Maybe a TWAP or VWAP, or MidPoint algo would be best. BUT it all depends upon your strategy. Many people will do a data study around how the different algo_buy() algorithms perform to choose the optimal one for their strategy.

    As for auto determination based only on quantity, could you consider writing your own function that would handle this for you? It would only be a few lines of code!

  • ms778834ms778834 Posts: 28

    @jd623170 Actually, I have already figured out what order algorithm to use to minimise market impact, after all, figures in the DataFrame above are larger than what I will actually be ordering, just to test the market. ;) By optimal I meant requiring as short computing time as possible.

    As for writing my own function... I could theoretically write the whole backtester, but isn't a point of CloudQuant to let you do as much as possible as fast as possible? Moreover, I don't have access to any CloudQuant's source code files, because, unlike its competitors, Kershner Trading Group has not open-sourced anything yet! :angry: This means that I can only code in Python→ my code gets interpreted by IronPython (or maybe CQ already uses CPython), which is gonna be significantly slower that having a function in the C++ & Cython kernel whose output would be in FIX and/or exchange-native protocol, routed directly to them exchanges and liquidity pools. :smirk:

  • @ms778834 Hi Marin, as for the intent parameter, I think you can set it to be 'none' to skip the rational check; however, for some strategies, it might be useful to utilize this feature and make sure the order logic is correct. As for the direction of sending orders, we appreciate your advice and we would consider incorporating this for better user experiences. The current algo_buy and algo_short, however, gives you some more choices over the type of execution such as VWAP, midpoint peg orders, etc; you can apply different GUIDs or shorthands according to the doc on the documentation website and we do provide several different sources of brokerage for comparison. We hope that would bring more practical trading experiences to the user including other features for example: if you are providing liquidity, we also calculate the rebate/commission credit to your account. There is no doubt that a C++/Cython based kernel would be faster, but CloudQuant is utilizing the cloud to perform the computations in a distributed way, which is another form of efficiency enhancement. On the other hand, we do have our simulation report open sourced and a couple of more projects are going to be open sourced later this year. By open sourcing the codes, we believe experienced professionals like you would definitely come up with more valuable suggestions to us and make us better.

  • ms778834ms778834 Posts: 28

    You are right about the reports, @johnbear565 , I forgot them. And I am glad about that, as well as about your open source initiatives continuing! :blush:

    What I am now aiming for is to find the most efficient way to execute trades according to my DataFrame above, preferably without losing my "for loops virginity" I've managed to keep so far in my script. Not only does it require +/- splitting to order.algo_buyand order.algo_sell, respectively, but also passing varying amounts onto order_quantity, as this parameter does not accept pandas objects. :/

Sign In or Register to comment.