def max_df(*dfs):
arr = np.stack([df.values for df in dfs])
result = np.max(arr, axis=0)
result_df = pd.DataFrame(result, index=dfs[0].index, columns=dfs[0].columns)
return msmp.DataFrame(result_df)
def min_df(*dfs):
arr = np.stack([df.values for df in dfs])
result = np.min(arr, axis=0)
result_df = pd.DataFrame(result, index=dfs[0].index, columns=dfs[0].columns)
return msmp.DataFrame(result_df)
# 一、股池為所有 ETF
# 二、前一日的五線最大值(含收盤價、10MA、20MA、50MA、60MA) < 五線最小值的 X% 範圍內
# 三、當日收盤價向上突破昨日五線最大值
# 四、淨利/淨值的排名小於等於 Y
# 五、以上為入場條件,出場條件為: 收盤價已連續 Z日未創Z日新高
# 六、手續費為 B 折 ,股票最大開倉金額不超過 A 萬
import numpy as np
import pandas as pd
import kgisuperpy as kgi
person_id = 'A123456789'
person_pwd = '0000'
#simulation可輸入參數True:連線至測試環境;Fales:連線至正式環境
simulation = True
api = kgi.login(person_id ,person_pwd ,simulation)
msmp = api.MSMP
msmp_to_dic = api.MSMP.msmp_to_dic
x=4
y=50
z=7
a=20
b=3
BM='0050'
info = msmp.INFO
pool = info[info.ETF==1].股票代號.tolist()
Open = msmp.日_K.Open
data = msmp.日_指標.淨利 /msmp.日_指標.淨值
adjclose = msmp.日_K.adj_Close
adjhigh = msmp.日_K.adj_High
adjlow = msmp.日_K.adj_Low
ma1 = adjclose.rolling(10).mean()
ma2 = adjclose.rolling(20).mean()
ma3 = adjclose.rolling(50).mean()
ma4 = adjclose.rolling(60).mean()
df_max = max_df(adjclose ,ma1 ,ma2, ma3 ,ma4)
df_min = min_df(adjclose ,ma1 ,ma2, ma3 ,ma4)
qty = np.floor(a * 10000 / (Open * 1000)) * 1000
con1 = df_max.shift(1) < df_min.shift(1)*(1+0.01*x)
con2 = adjclose >df_max.shift(1)
con3 = ~((adjlow.shift(-1)>adjclose*1.0947)&(adjhigh.shift(-1)==adjlow.shift(-1)))
con4 = data.loc[:,data.columns.isin(pool)].rank(axis=1) <= y
pos = con1 &con2&con3&con4&(qty!=0)
pos = pos.mask(pos==False)
pos = pos.loc[: , pos.columns.isin(pool)]
out = (adjclose > adjclose.shift(1).rolling(z).max()).rolling(z).sum()==0
dic = msmp_to_dic(['qty', 'long' ,'longout'], qty, pos ,out)
benchmark= api.Data.get('還原日K(個股、ETF、大盤)-單股單期' ,BM).set_index('日期')['收盤價']
rp = api.backtest(dic ,
symbol='id',date='date',qty='qty', sig_value='adjclose',
open_value='adjopen', open_shift=True,
close_value='adjopen', close_shift=True,
longsig='long', longout='longout',
benchmark=benchmark, fee=0.0001425 * b)