CloudQuant Mariner - G&S Quotient Example

G&S Quotient ESG Dataset

G&S Quotient is an ESG (Environmental, Social and Governance) data and analytics platform.

They provide public company ESG data on a daily point-in-time basis.

This daily undated data uniquely enables short-term alpha discovery and short-term volatility prediction for equity and option pricing.

G&SQ data also has proven efficacy in achieving longer term alpha.

Available for sampling on CloudQuant are their stock-wise topline scores for both short-term and long-term strategies.

To create these topline scores, G&SQ measure Outcome Values for 76 G&SQ Measures (Risk factors), providing flexibility and differentiation in designing alpha signals.

For more information on utilizing G&S Quotient data on your own platform contact us.

Data Format

Field Description
ISIN Stock Identifier, presented on a point-in-time basis i.e. as it was on the corresponding score-date.
CUSIP Stock Identifier, presented on a point-in-time basis i.e. as it was on the corresponding score-date.
Ticker Stock Identifier, presented on a point-in-time basis i.e. as it was on the corresponding score-date.
source_key Symbol translated from above by Liberator
Date This is the score-date. The score is released by 08:30AM EST on the next trading day with respect to score-date. The underlying G&SQ variables are updated till the end-of-day(i.e. 23:59:59 hours EST) of the score-date. The stock price data input ends at the close of trading on the score-date.
Score G&SQ Price Predictor Score for a given stock for a given score-date. The score is expected to have predictive power for price movements beginning next trading day open.
Population_Index_Constituents This represents the major benchmark index the stock is a constituent of. ie SPX
Test Data in CloudQuant

CloudQuant's Liberator is used to access the topline G&S Scores.

Liberator is our proprietary interface for accessing all kinds of alternative datasets using a simple, consistent interface.

NOTE : As of April 2020 if you ask liberator for this data from today back to yesterday YOU WILL GET FUTURE DATA.

See the script below where, instead of requesting data timestamped between today and yesterday, we request data timestamped between yesterdays open and the day before.

We will amend this page and script if and when this situation is amended.

Simple Demo Script

Here is a simple demo script,

 # Copyright Cloudquant, LLC. All right reserved.
# G&SQ data available from January 2013
# Takes top and bottoms # symbols from GSQ data and goes long/short (# of long/short symbols is defined by the variable num_syms) 

from cloudquant.interfaces import Strategy
import liberator

# G&SQ data available from January 2013
# Takes top and bottoms # symbols from GSQ data and goes long/short (# of long/short symbols is defined by the variable num_syms) 

from cloudquant.interfaces import Strategy
import liberator as b24

class GSQ_Test(Strategy):
    @classmethod
    def on_strategy_start(cls, md, service, account):
        yesterday = service.time_to_string(service.get_market_hours(date_offset=-2)[0],"%Y-%m-%d")+" 02:00:00"
        today = service.time_to_string(service.get_market_hours(date_offset=-1)[0],"%Y-%m-%d")
        res = b24.query(symbols=None, as_of=today, back_to=yesterday, name='GSQ ESG Large Cap, Short Term Price Predictor')
        df = b24.get_dataframe(res)
        print(yesterday,today)
        print(df)
        df = df[['symbol','Score']]  # drop all other columns
        df.columns = ['Ticker','Score'] # rename header
        df.dropna(inplace = True) # drop nans
        mydf = df.sort_values('Score', ascending=False) # Sort!
        num_syms = 20 # enter # syms to go long and short. For a quintile (1/5th of the length of the list of qualified symbols) use num_syms = int(len(mydf)/5)
        myticker = mydf["Ticker"].tolist() # Convert the dataframe to a list (of just the symbols) in ranked order ready to split
        cls.top = myticker[:num_syms] # Top of list
        cls.bottom = myticker[-num_syms:] # Bottom of list

    @classmethod
    def is_symbol_qualified(cls, symbol, md, service, account):
        return (symbol in cls.top or symbol in cls.bottom) and symbol !="CBOE" and (md.stat.prev_close!=0 or md.stat.prev_close==md.stat.prev_close)

    def on_start(self, md, order, service, account):
        shares = int(10000/md.stat.prev_close) # $10k per position. Use shares = int(md.stat.avol/390/100) # for 1/100th of the average minute bar.
        if self.symbol in self.__class__.top:
            order.send(self.symbol, 'buy', shares, type='MOO') # enter at the open
            order.send(self.symbol, 'sell', shares, type='MOC') # exit at the close, hold for one trading day only.
        else:
            order.send(self.symbol, 'sell', shares, type='MOO') # enter at the open
            order.send(self.symbol, 'buy', shares, type='MOC') # exit at the close, hold for one trading day only.

For the script used to generate our G&SQ White Paper results click here, then click CLONE SCRIPT and then NEW TEST. Note this will take a lot longer to run than the simple quick script above.

 SP500 symbols x 39 days (7/1/2019 to 8/26/2019) = 18866 data points
count    18866
mean     -0.595380
std      3.876030
min     -41.436258
25%     -2.546505
50%     -0.538181
75%     1.405255
max     57.517595

18750 of the values fall between -15 and +15