use volume indicator to backtesting , using 2618
Table of Contents
Nowadays Momentum trade are frequently used to trade strategy,we often talk about the price-volume relationship .So in this article we are going to talk about this strategy which based on abnormal growing of the trading volume.but this strategy doesn’t have the clear definition.so we write the function more flexible.you can change the parameter by yourself ! Following is the way to our set the parameter :
1. buy-signal : when the trading volume is 2.5 times more than the average of previous 4 days.
2. sell-singal : when the trading volume is 0.75 times less than the average of last 4 days.
Window10 Spyder(anaconda31)
##########
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
#################TEJ
import tejapi
tejapi.ApiConfig.api_key = 'Your Key'
tejapi.ApiConfig.ignoretz = True
Security Transaction Data Table:Listed securities with unadjusted price and index. Code is ‘TWN/EWPRCD’.
coid="2618" #### you can replace the stock id what you want
start="2018-01-01" ### time~
end= "2022-03-2" ### endopts={'columns': ['coid', 'mdate', 'volume', 'close_adj','close_d','open_d']} ###
#############
fly=tejapi.get('TWN/EWPRCD',coid=coid,
mdate={'gt':start,'lt':end},
paginate=True,
chinese_column_name=True,
opts=opts )
we using the popular groups in recent days to demonstrate our code .Time we select is 2018/1/1~ 2022~3/2.After we get the data ,we want to plot the data.
fly.set_index("日期",drop=True,inplace=True) # set index
plt.figure(facecolor='white',figsize=(12,8))
plt.plot(fly['收盤價'], label='收盤價')
plt.title("飛機起飛表",fontsize=25)
plt.xticks(rotation=45)
plt.xlabel('日期',fontsize=25)
plt.ylabel('股價',fontsize=25)
plt.grid()
plt.show()
Step 1. set the indicator
def voltrade(df,p,q,r):
df =df.copy()
df["當日交易量"]=df["成交量(千股)"].rolling(p).mean()
df["前五日總量"]=df["成交量(千股)"].rolling(q).sum()
df[str(r)+"日均線"]=df["收盤價-除權息"].rolling(r).mean()
####扣除掉當日之平均
df["前幾日平均"]=(df["前五日總量"]-df["當日交易量"])/(q-p)
return df
This function we can get previous 4(q) days average tradeing volume ,and the 5(r)ma ( we can change the q r)
r=5
stock=voltrade(fly, 1, 5, r) # the parameter is which we set in this articlestock
Step 2 find the buy singal and sell singal
def buysell(company,a,b):
company =company.copy()
buy=[]
sell=[]
hold=0
for i in range(len(company)):
if company["當日交易量"][i] > company["前幾日平均"][i]*a :
sell.append(np.nan)
if hold !=1:
buy.append(company["收盤價-除權息"][i])
hold = 1
else:
buy.append(np.nan)elif company["當日交易量"][i]<company["前幾日平均"][i]*b :
buy.append(np.nan)
if hold !=0:
sell.append(company["收盤價-除權息"][i])
hold = 0
else:
sell.append(np.nan)
else:
buy.append(np.nan)
sell.append(np.nan)
a=(buy,sell)
company['Buy_Signal_Price']=a[0]
company['Sell_Signal_Price']=a[1]
company["買賣股數1"]=company['Buy_Signal_Price'].apply(lambda x : 1000 if x >0 else 0)
company["買賣股數2"]=company['Sell_Signal_Price'].apply(lambda x : -1000 if x >0 else 0 )
company["買賣股數"]=company["買賣股數1"]+ company["買賣股數2"]
return companyvol=buysell(stock,2.5,0.75)
plot(vol)
In this stargey ,we have done too much buying and selling which incrase frictional cost.and found that we often sell to early.Therefore we try to increase more restriction like the 5ma stargey,here is the following :
casue we are talking about the indicator ,so we plot it together .
pvtwo(volma) #seprate
pvsame(volma)#combine
In Backtesting by MACD Indicator, we have discussed the details in the calculation of frictions cost and the method to calculate return with initial principal. In this article, we use function to achieve all of it.
def target_return(data, principal):
data=data.copy()
#計算成本
data['手續費'] = data['收盤價-除權息']* abs(data['買賣股數'])*0.001425
data['手續費'] = np.where((data['手續費']>0)&(data['手續費'] <20), 20, data['手續費'])
data['證交稅'] = np.where(data['買賣股數']<0, data['收盤價-除權息']* abs(data['買賣股數'])*0.003, 0)
data['摩擦成本'] = (data['手續費'] + data['證交稅']).apply(np.floor)
#計算資產價值
data['股票價值'] = data['買賣股數'].cumsum() * data['收盤價-除權息']
data['現金價值'] = principal - data['摩擦成本'] + (data['收盤價-除權息']* -data['買賣股數']).cumsum()
data['資產價值'] = data['股票價值'] + data['現金價值']
#計算報酬率
data['當日價值變動(%)'] = (data['資產價值']/data['資產價值'].shift(1) - 1)*100
data['累計報酬(%)'] = (data['資產價值']/principal - 1)*100
return data
We only consider the trading of common stock. There is no margin buy or margin sell situation, so we do not have to calculate premium. With the data containing trading shares and initial principal, we can quickly get the transaction costs and return. In this article, we set 16000 as our principal.
volreturn1 = target_return( volma, principal = 16000)##with ma
volreturn2 = target_return( vol, principal = 16000)##without ma
we add buy-and-hold strategy as our benchmarks.
keep=vol.copy()
keep["買賣股數"]=0
keep["買賣股數"][0]=1000
keep["買賣股數"][len(keep)-1]=-1000
volreturn3 = target_return( keep, principal = 16000)
Step 1. Comparison of cumulative return (See the details in source code)
Step 2. Performance table (See the details in source code)
We found that if we only use trading volume as the only indicator,the performace will equal to the buy&hold,but when we add the ma,we found that the performace is 2 times than the others ,and the sharp ratio is the highest.But this method also has obvious disadvantages .when we look at the 2018 ~2020 ,in this time period is negative pay.Perhaps the entry conditions can be set more strictly to reduce redundant buying and selling.
There are two special cases to remind the use of this method:
In 2021 , “2618” started to growth ,this stargey can find the good position to buy ,and can efficient use your funds ! So we will introduce how to use TEJ -API to find the abnormal increase volume next ,and we can Cooperate with this article.
After all, the application of technical indicator varies from person to person. As a result, if readers are interested in diverse trading backtesting, welcome to purchase the plan offered in TEJ E-Shop. Construct trading strategies fitting you with high quality database.
Subscribe to newsletter