Skip to content

Instantly share code, notes, and snippets.

@ycytai
Last active October 15, 2021 09:21
Show Gist options
  • Save ycytai/8447972f0167a650522f4c9d3abe6f52 to your computer and use it in GitHub Desktop.
Save ycytai/8447972f0167a650522f4c9d3abe6f52 to your computer and use it in GitHub Desktop.
Dollar Averaging Strategy
def dollar_averaging(df, trade_date, trade_amount, f_or_b = 'f'):
'''
Input:
1. df (dataframe)
---> Datetime object should be set as index
2. trade_date (int)
---> determine which date to invest
3. trade_amount (int)
---> determine the amount of investing
4. f_or_b (str)
---> once trade_date market closed, move forward or backward
Output:
1. profit_or_loss (float)
---> dollar-averaging strategy profit/loss
2. annualized_ret
---> dollar-averaging strategy annualized return
3. trade_detail
---> trading record during the data period
'''
date_in_date = list(set([(date.year, date.month) for date in df.index]))
date_in_date = sorted(list(date_in_date), key=lambda x: (x[0], x[1]))
date_for_investing = trade_date
f_or_b = 1 if f_or_b == 'f' else 0
searched_count = 0
purchasing_date_list = []
for ym in date_in_date:
current_year = ym[0]
current_month = ym[1]
current_day = date_for_investing
purchasing_date = 'NA'
while purchasing_date == 'NA':
try:
searching_date = datetime.strptime(str(current_year) + '-' +
str(current_month)+ '-' +
str(current_day), '%Y-%m-%d')
if searching_date in df.index:
purchasing_date = searching_date
purchasing_date_list.append(purchasing_date)
else:
current_day += 1
searched_count += f_or_b # if selected date is not a trading date, then move backward or foreward
# if current_day add more than valid date for current month
except ValueError:
break
# initial parameters for dollar averaging
da_amount = int(trade_amount)
shares = 0
total_cost = 0
trade_detail = {}
# create trading details
for date in purchasing_date_list:
cost_price = df.loc[date][0]
got_shares = int(da_amount / cost_price)
cost = round(cost_price * got_shares) * (1 + 0.001425*0.6)
trade_detail[date] = [cost_price, got_shares, cost]
shares += got_shares
total_cost += cost
# Count days between first and the last time trading for Annualize
da_period_as_year = (purchasing_date_list[-1] - purchasing_date_list[0]).days / 365
# Calculate dollar-averaging performance
profit_or_loss = round( (shares * df.loc[purchasing_date_list[-1]][0]) - total_cost )
annualized_ret = round((profit_or_loss / total_cost + 1) ** (1 / da_period_as_year) - 1, 4)
return profit_or_loss, annualized_ret, trade_detail
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment