qstrader icon indicating copy to clipboard operation
qstrader copied to clipboard

Could you add a sample code for alpha 101 formula?

Open easytrader opened this issue 8 years ago • 14 comments

Could you add a sample code for alpha 101 formula?

I have bought the book "advanced trading strategies". But I want to use the qstrader to write the sample code for worldquant alpha 101's formula. I am not familiar the qstrader. I don't know how to get the dataframe from 100 stock's yahoo price. And I don't know how to write the position sizer to reach the goal. Could you write the simpliest formula 101 on top 100 capital stocks? Alpha#101: ((close - open) / ((high - low) + .001))

It might use 2week or 1 month rebalance day that will be simple. The position size will use the profolio value to buy 100 stocks.

Thank you very much.

Uqer's platform's sample code:

import numpy as np

start = '2010-01-01'                       # 回测起始时间

end = '2016-03-20'                         # 回测结束时间

benchmark = 'HS300'                        # 策略参考标准

universe = set_universe("HS300")           # 证券池,支持股票和基金

capital_base = 100000                      # 起始资金

freq = 'd'                                 # 策略类型,'d'表示日间策略使用日线回测,'m'表示日内策略使用分钟线回测

refresh_rate = 20                          # 调仓频率,表示执行handle_data的时间间隔,若freq = 'd'时间间隔的单位为交易日,若freq = 'm'时间间隔为分钟

​
def foo(data, dependencies=['closePrice', 'openPrice', 'highPrice', 'lowPrice'], max_window=1):
    today = (data['closePrice'].ix[-1]-data['openPrice'].ix[-1])/((data['highPrice'].ix[-1]-data['lowPrice'].ix[-1]) + 0.001)
    return today



def initialize(account):                   # 初始化虚拟账户状态
    a = Signal("worldquant_101", foo)
    account.signal_generator = SignalGenerator(a)



def handle_data(account):                  # 每个交易日的买入卖出指令



    # 只选信号,即worldquant_101计算结果大于0的股票,而且选前40只
    # 平均仓位持仓
    weight = account.signal_result['worldquant_101']
    weight = weight[weight>0]
    weight.sort(ascending=False)
    weight = weight[0:40]
    weight = weight/weight.abs()
    weight = weight/weight.sum()
    weight = weight.replace([np.inf, -np.inf], np.nan).dropna()



    buy_list = weight.index
    sell_list = account.valid_secpos

    for stk in sell_list:
        if stk not in buy_list:
            order_to(stk, 0)



    total_money = account.referencePortfolioValue
    prices = account.referencePrice 

    for stk in buy_list:
        if stk not in prices:
            continue

        if np.isnan(prices[stk]) or prices[stk] == 0:  # 停牌或是还没有上市等原因不能交易
            continue

        order_num = int(total_money * weight[stk] / prices[stk] /100)*100
        if order_num < 100:
            order_num = 100
        order_to(stk, order_num)

easytrader avatar Oct 25 '16 08:10 easytrader

Hi easytrader,

Is there a blog post related to the above WorldQuant strategy?

Also do you know what the HS300 universe is? I think it might be CSI 300 but I just want to check!

Mike.

mhallsmoore avatar Oct 25 '16 09:10 mhallsmoore

Hi mhallsmoore,

I only can find the correct WorldQuant strategy be implemented by China's backtesting platform "UQER". The page below is describing WorldQuant strategy sample code for uqer platform, but it write in chinese. https://uqer.io/community/share/56e7d803228e5b887de50afe

In uqer's platform ,there are more than 20 WorldQuant strategies have been implemented . And some of these WorldQuant strategies have more than 25~40% Annualized Return in China's stock market. If you want to know more about the WorldQuant strategies, I might translte chinese to english for you.

Below's page is the sample code for alpha 101's formula: https://uqer.io/community/share/56efdba1228e5b8880e51052

HS300 universe is 300 most capitalist in china.you can check this page: http://finance.sina.com.cn/qizhi/hs300.html

Thank you.

easytrader avatar Oct 25 '16 10:10 easytrader

I found this paper, which seems to be the original source ?

https://arxiv.org/pdf/1601.00991.pdf

ryankennedyio avatar Oct 25 '16 10:10 ryankennedyio

There's a fairly active thread on the 101 Formulaic Alphas at Quantopian (not sure if Mike approves of the link to them...): https://www.quantopian.com/posts/the-101-alphas-project Towards the bottom of the dicussion, there's an implementation of at least 50 or so of the Alphas. General consensus is not so positive and given the factor weights that come with some of the Alphas, they seem (to me at least) highly optimized/fitted: Alpha#69: ((rank(ts_max(delta(IndNeutralize(vwap, IndClass.industry), 2.72412), 4.79344))^Ts_Rank(correlation(((close * 0.490655) + (vwap * (1 - 0.490655))), adv20, 4.92416), 9.0615)) * -1) -- I mean, seriously?

DirkFR avatar Oct 25 '16 14:10 DirkFR

Dirk - no problem about the link! It's always good to get a discussion going.

I'll admit I'm sceptical initially, as many of the proposed alphas seem to have been generated from what is often termed "alpha mining". That is, machine learning models "thrown at data". My approach to trading is to find a specific set of economic "structural" rationales for why prices are (currently) dislocated and then attempt to exploit those, rather than applying myriads of indicators at data.

However, I've only had a cursory glance and haven't read through the arXiv paper Ryan suggested to any great extent as of yet. It does look like they're saying that 80% of the alphas are actually in production in a large "mega-alpha" generator.

It is certainly worth a look, albeit quite an involved project!

mhallsmoore avatar Oct 25 '16 14:10 mhallsmoore

Hi DirKFR,

I don't know the differece between US stock market and China stock market. But it seems working in China's market. You can use SH50(Shanghai 50) or HS300(The 300 Shenzhen Component Index) that can work perfectly. I have three examples below:

1.WorldQuant's Alpha10 https://uqer.io/community/share/56f3c074228e5b887ee51258

Annualized Return:38.3% Period: 2013~2016

2.WorldQuant's Alpha#12 https://uqer.io/community/share/56f4a475228e5b887fe5123c

Annualized Return:39.9% Period: 2013~2016

3.WorldQuant's Alpha#18 https://uqer.io/community/share/5756993d228e5b8a3c285c0c

Annualized Return:29.0% Period: 2013~2016

Thank you.

easytrader avatar Oct 25 '16 14:10 easytrader

Hi easytrader,

I have no means to quickly replicate the strategies on uqer.io - the numbers look impressive in back-test. Since this seems to be a daily rebalancing approach, it would be interesting to see if transaction cost and slippage have been included in the tests - unfortunately, I can't see (=understand) this from the site - do you know?

DirkFR avatar Oct 25 '16 17:10 DirkFR

Hi DirkFR,

I update the rebalancing period for each strategy. Alpha 10 and Alpha 12's rebalancing period is 20 days. Only Alpha#18's rebalancing period is 1 day. If we only use Alpha 10 and Alpha 12 that transaction cost and slippage might not be a problem. I might rewrite the uqer code and test the result for you.

1.WorldQuant's Alpha10 https://uqer.io/community/share/56f3c074228e5b887ee51258

Annualized Return:38.3% Period: 2013~2016 rebalancing period:20days

2.WorldQuant's Alpha#12 https://uqer.io/community/share/56f4a475228e5b887fe5123c

Annualized Return:39.9% Period: 2013~2016 rebalancing period:20days

3.WorldQuant's Alpha#18 https://uqer.io/community/share/5756993d228e5b8a3c285c0c

Annualized Return:29.0% Period: 2013~2016 rebalancing period:1day

easytrader avatar Oct 26 '16 09:10 easytrader

I want to explain the uqer's sample code. data['openPrice'] should be a dataframe showing below:

          000001.XSHE  000002.XSHE  000009.XSHE  000027.XSHE  000039.XSHE  \
20131106        7.474        8.054        5.972        3.548       12.213   
20131107        7.363        7.930        5.905        3.561       11.850   
20131108        7.301        7.878        5.611        3.591       11.784 

Variable today will caculate the alpha formula for each symbol in HS300. today = (data['closePrice'].ix[-1]-data['openPrice'].ix[-1])/((data['highPrice'].ix[-1]-data['lowPrice'].ix[-1]) + 0.001) Then weight will be a dataframe's type and put all symbols' today value in it.

weight = account.signal_result['worldquant_101']
print(weight)
weight = weight[weight>0]

The dataframe's weight format shows below: 600547.XSHG is stock symbol , 0.201936 is today's value.

600547.XSHG       0.201936
601866.XSHG       0.392157
000540.XSHE      -0.243243
300059.XSHE            NaN
601088.XSHG      -0.270330
002129.XSHE      -0.056075
600900.XSHG      -0.056180
002008.XSHE      -0.038043
000425.XSHE      -0.319767
000069.XSHE       0.366013
001979.XSHE            NaN
600332.XSHG      -0.124464
601166.XSHG       0.061947
601992.XSHG            NaN
000156.XSHE            NaN
601333.XSHG       0.000000
.................

China stock market only can buy the stock. weight = weight[weight>0]

It seleccts top 40 stocks to buy. weight = weight[0:40] It can caculate each stock's percentage of total portfolio. weight = weight/weight.sum() Replace the inf and -inf to NA and remove the NA value from weight. weight = weight.replace([np.inf, -np.inf], np.nan).dropna()

easytrader avatar Oct 26 '16 12:10 easytrader

Hi All, I find more interesting article for deep learning. It runs through the sample code uing R on EUR/USD, Maybe this article is useful for you. http://www.financial-hacker.com/build-better-strategies-part-5-developing-a-machine-learning-system/

easytrader avatar Oct 27 '16 14:10 easytrader

I have written the code for creating the dataframe like data['closePrice']. But I don't know how to pass the stock's porfolio weighting for position sizer. My code might be work but the code is not good. If there are bugs in my code, please let me know. Thank you. twentydays_liquidate_rebalance.txt twentydays_liquidate_backtest.txt

easytrader avatar Oct 30 '16 15:10 easytrader

I don't finish the alpha101's strategy. I still have some probelms. But I want to update my working. This is my codebase: alpha101_qstrader_3.tar.gz

I download the Shanghai 50 stocks data below: Shanghai50.tar.gz

You can type the command: python twentydays_liquidate_rebalance.py --tickers=000001SS,600000SS,600016SS,600030SS,600050SS,600111SS,600519SS,600795SS

You can see the figure below: 2016-11-11 23 40 43

I don't use 50 stocks. It still have problem.

easytrader avatar Nov 11 '16 15:11 easytrader

I want to update the new version of my alpha 101's strategy.

It includes qstrader folder and twentydays_liquidate_rebalance1.py. You should use the command: python twentydays_liquidate_rebalance1.py --tickers=SPY,AGG,AAPL > log5.txt

You can see the pic below: 2016-11-21 19 15 21

If you find the bug, please tell me. Thank you very much.

easytrader avatar Nov 21 '16 11:11 easytrader

I use Shanghai 50 stocks to produce alpha 101's formula.

You should type the cmd: python twentydays_liquidate_rebalance1.py --tickers=000001SS,600000SS,600016SS,600030SS,600050SS,600111SS,600519SS,600795SS,600893SS,601006SS,601169SS,601288SS,601336SS,601601SS,601669SS,601800SS,601901SS,601989SS,600010SS,600018SS,600036SS,600104SS,600150SS,600585SS,600837SS,600958SS,601088SS,601186SS,601318SS,601390SS,601628SS,601688SS,601818SS,601985SS,601998SS,600015SS,600028SS,600048SS,600109SS,600518SS,600637SS,600887SS,600999SS,601166SS,601211SS,601328SS,601398SS,601668SS,601766SS,601857SS,601988SS > log5.txt

You can see the figure below: 2016-11-22 11 31 49

If you find the bug, please tell me. Thank you very much.

easytrader avatar Nov 22 '16 03:11 easytrader