Example 1:10日均量倍增 + 收盤高於低點3%

input
table=api.USData.get('美股產業對照表')

#從每個粗產業中 ,挑出一檔市值最大的"非etf"
ls =[]
for group in table.粗產業名稱.unique():
    if group=='':
        continue
    symbol = table.loc[table[(table["粗產業名稱"] == group) & (table["是否為ETF"] == "0")]["市值(美元)"].idxmax()].股票代號
    ls.append(symbol)
    
dic ={}
for symbol in ls:
    table = api.USData.get('日K價量資料(個股、ETF)-單檔股票多個區間',symbol)
    df = table.set_index('日期')[['開盤價','收盤價','成交量','最低價']]
    df.columns=['Open','Close','Volume','Low']

    #量創10日均量的兩倍
    con1 = df['Volume'] > df['Volume'].shift(1).rolling(10).mean()*2
    #收盤價 > 最低價*1.03
    con2 = df['Close'] > df['Low']*1.03

    pos = con1 &con2
    df.loc[pos[pos==True].index,'sig']=True
    #每檔5000美元
    df['qty'] = np.around(5000/df['Open'])

    #存入dic
    dic[symbol] = df.reset_index()

#sig_value 用來計算止盈止損的對標欄位
#open_value 進場價格欄位
#close_value 出場價格欄位
benchmark =api.USData.get('日K價量資料(個股、ETF)-單檔股票多個區間','SPY').set_index('日期')['收盤價']
rp = api.backtest(  data=dic ,
                    date='日期',
                    sig_value='Close',
                    open_value='Open',  open_shift=True,   
                    close_value='Open', close_shift=True,  
                    longsig='sig',qty='qty',
                    moveloss=20,
                    fee=0.003/2 ,tax=0.0000051,
                    benchmark=benchmark)

Example 2:MACD底部反轉動能

input
table=api.USData.get('美股產業對照表')

#市值前30大的股票
ls =table[(table['是否為ETF']=='0')&(table['市值(美元)'].notnull())&(table.流通股數.notnull())].sort_values('市值(美元)',ascending=False)[:30].股票代號.tolist()

#計算macd
def ind_MACD(data, short_window=12 ,long_window = 26 ,macd_window = 9):
    short_ema = data.ewm(span=short_window, adjust=False).mean()
    short_ema[:short_window-1] = np.nan  # 前 11 筆設為 NaN
    long_ema = data.ewm(span=long_window, adjust=False).mean()
    long_ema[:long_window-1] = np.nan    # 前 25 筆設為 NaN
    macd = short_ema -long_ema
    macd_ema = macd.ewm(span=macd_window, adjust=False).mean()
    macdhist = macd - macd_ema
    return macd ,macd_ema  ,macdhist

dic ={}
for symbol in ls:
    table = api.USData.get('日K價量資料(個股、ETF)-單檔股票多個區間',symbol)
    df = table.set_index('日期')[['開盤價','收盤價','成交量','最低價']]
    df.columns=['Open','Close','Volume','Low']

    macd ,macd_ema  ,macdhist = ind_MACD(df['Close'], short_window=12 ,long_window = 26 ,macd_window = 9)

    #低點3bar内的最低macdhist
    low_point = macdhist.rolling(3).min()
    #低點是60内的最低點
    con1 = low_point ==low_point.rolling(60).min()
    #連續兩期上升
    con2 = (macdhist>macdhist.shift(1)) &(macdhist.shift(1)>macdhist.shift(2)) 
    #hist<0
    con3 = macdhist<0
    #進場
    bk = con1&con2&con3
    
    con4 = (macdhist<macdhist.shift(1))& (macdhist.shift(1)<macdhist.shift(2))
    #hist>0
    con5 = macdhist>1.5
    #出場
    bp = con4&con5 

    #套用到sig
    df.loc[bk[bk==True].index,'sig']=True
    df.loc[bp[bp==True].index,'sig']=False
    
    #每檔5000美元
    df['qty'] = np.around(5000/df['Open'])
    
    #存入dic
    dic[symbol] = df.reset_index()
    
benchmark =api.USData.get('日K價量資料(個股、ETF)-單檔股票多個區間','SPY').set_index('日期')['收盤價']
rp = api.backtest(  data=dic ,
                    date='日期',
                    sig_value='Close',
                    open_value='Open',  open_shift=True,   
                    close_value='Open', close_shift=True,  
                    longsig='sig',qty='qty',
                    fee=0.003/2 ,tax=0.0000051,
                    benchmark=benchmark)

提供一系列方法展示對應數據。

Attribute

參數 資料型態 說明
data dict(symbol:DataFrame) or DataFrame 為資料本體,需為dataframe 或可為 dataframe 組成的dic
date str dataframe中代表"日期"欄位的column名稱。
symbol str 指定在 DataFrame 中代表"股票代號"欄位的列名。如data為字典,則使用字典的鍵作為 `symbol`。
sig_value str 設定用做停利停損判斷對象的"標準價"的column名稱,為必填欄位。
open_value str 設定"進場價"的column名稱,如果沒設定將使用sig_value設定的欄位名稱。
open_shift bool 默認為True,會在滿足信號後的下一根K棒執行進場;若為False,則在當根執行。
close_value str 設定"出場價"的column名稱,如果沒設定將使用sig_value設定的欄位名稱。
close_shift bool 默認為True,會在滿足信號後的下一根K棒執行出場;若為False,則在當根執行。
longsig str 做多方向的"進場信號"的column名稱,longsig和shortsig至少需設定一個;值為True代表進場,False為出場,nan不進行任何行爲。
longout str 做多方向的"出場信號"的column名稱,為longsig的補充欄位,非必填。值為True時代表出場。longsig和longout同時為True,依舊表示為出場。
shortsig str 做空方向的"進場信號"的column名稱,longsig和shortsig至少需設定一個。值為True代表進場,False為出場,nan不進行任何行爲。
shortout str 做空方向的"出場信號"的column名稱,為shortsig的補充欄位,非必填。值為True時代表出場。shortsig和shortout同時為True,依舊表示為出場。
qty int 設定"股數"的column名稱,為必填欄位。
tax float 交易稅率,默認為None將使用台灣交易規則的默認設置。默認規則為一般股票0.003、ETF為0.001、股票當沖0.0015-例如,設定為0.0005,在做多出場發生交易稅5bp,在做空時進場發生交易稅5bp。
美股需自行設定。
fee float 手續費率,用於計算進場和出場時的手續費,如不填寫為0.00025。-例如,設定為0.00125,代表進場及出場各會發生手續費12.5bp。
earn float 停利比率,表示當收益達到該比率時觸發停利。-例如,設定為 20 則代表停利為 20%。如果未指定,則不設定停利條件。
loss float 停損比率,表示當虧損達到該比率時觸發停損。
-例如,設定為 20 則代表停損為 20%。如果未指定,則不設定停損條件。
slippage float 滑點率,指在進場及出場時可能發生的往不利價格方向的變動量,默認為0。-例如,設定為0.001,代表進場及出場各會滑點10bp。
moveloss float 設定"移動停利",計算邏輯是用進場後設定的sig_value的最大值與進場價格計算。
若未設定數值,則不啟用移動停損條件
例如:
多方,moveloss=10:
移動止損=max(進場後的sig_value1 ,sig_value2 ,.... ,sig_valueN) * (1-0.01 * moveloss)
當 sig_valueN < 移動止損,觸發離場信號。

空方,moveloss=10:
移動止損=min(進場後的sig_value1 ,sig_value2 ,.... ,sig_valueN) * (1+0.01 * moveloss)
當 sig_valueN > 移動止損,觸發離場信號。
max_hold float 最大持有天數,表示持股的最大天數限制。
continuous_wins tuple or list 連勝N次後,交易量增為M倍的設置。-例如,設定為 (3, 2) 表示連勝3次後,交易量變為原來的2倍。如果未指定,則不調整交易量。
force_exit int 將列表裡的已持有股票在最後一根Kbar強制進行出場。
benchmark Series -對標價格,index需為日期,避免因日期錯誤產生誤差。
messages bool 是否顯示回測產出過程中的信息,默認為True。
_maxtrades int 最大交易次數,若未設定則默認為10000次。
可自行設定此參數值。

Return Attribute

將返回一個物件,封装了回測分析結果,並可使用以下方法展示對應數據。

方法 說明
dashboard 本次策略總績效報告儀錶板。
trade 交易明細。
position 每日持倉。
daily 每日帳戶損益。
report 策略績效報告。
plotly 顯示績效圖表。
save 將結果儲存在本地位置。