Beispiel #1
0
def compute_risk():
  
  global risk_data
  ret_data = []
  
  for i,r in enumerate(sharpe_rank_data):

    if i == 0 or (i + 24) >= num_rows: continue
    
    fund = r.split(',')[1]
    nav_line = nav_data[i + 12].split(',')[1:]
    nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
    nav = nav_dict[fund]
    units = mnt_inv / nav
    
    curr_nav_line = nav_data[i + 24].split(',')[1:]
    curr_nav_dict = common.get_fund_nav_dict(fund_names, curr_nav_line)
    curr_nav = curr_nav_dict[fund]
    
    wealth = units * curr_nav
    ret = (wealth / mnt_inv) - 1.0
    ret_data.append(ret)
  
  sharpe = common.get_sharpe(ret_data, 'annual')
  risk_data = sharpe
Beispiel #2
0
def compute_risk():

    global stats_dict
    for fund in fund_names:

        ret_data = []
        for i, units in enumerate(units_save_dict[fund]):

            # why (i + 13) and (i + 25)?
            # the header row and first 12 rows are ignored in nav_data
            # hence, the first index where investment starts is (i + 13)
            # to look nav of this investment one year later, we use (i + 25)

            if (i + 25) >= num_rows: break

            nav_line = nav_data[i + 13].split(',')[1:]
            nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
            inv = units * nav_dict[fund]
            if inv == 0: continue

            curr_nav_line = nav_data[i + 25].split(',')[1:]
            curr_nav_dict = common.get_fund_nav_dict(fund_names, curr_nav_line)
            wealth = units * curr_nav_dict[fund]

            ret = (wealth / inv) - 1.0
            ret_data.append(ret)

        sharpe = common.get_sharpe(ret_data, 'annual')
        stats_dict[fund].append(sharpe)
Beispiel #3
0
def compute_risk():

    global stats_data
    num_funds = len(fund_names)
    default_inv = common.mnt_inv
    mnt_inv = default_inv / num_funds

    ret_data = []
    for i, r in enumerate(nav_data):

        if i < 13: continue
        if (i + 25) >= num_rows: break

        nav_line = nav_data[i + 13].split(',')[1:]
        nav_dict = common.get_fund_nav_dict(fund_names, nav_line)

        curr_nav_line = nav_data[i + 25].split(',')[1:]
        curr_nav_dict = common.get_fund_nav_dict(fund_names, curr_nav_line)

        inv = default_inv

        wealth = 0
        for fund in fund_names:

            nav = nav_dict[fund]
            units = mnt_inv / nav
            wealth += units * curr_nav_dict[fund]

        ret = (wealth / inv) - 1.0
        ret_data.append(ret)

    sharpe = common.get_sharpe(ret_data, 'annual')
    stats_data.append(sharpe)
Beispiel #4
0
def compute_risk():
  
  global risk_data
  ret_data = []
  
  for i,r in enumerate(sharpe_rank_data):

    if i == 0 or (i + 24) >= num_rows: continue
    
    fund = r.split(',')[1]
    nav_line = nav_data[i + 12].split(',')[1:]
    nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
    nav = nav_dict[fund]
    units = mnt_inv / nav
    
    curr_nav_line = nav_data[i + 24].split(',')[1:]
    curr_nav_dict = common.get_fund_nav_dict(fund_names, curr_nav_line)
    curr_nav = curr_nav_dict[fund]
    
    wealth = units * curr_nav
    ret = (wealth / mnt_inv) - 1.0
    ret_data.append(ret)
  
  sharpe = common.get_sharpe(ret_data, 'annual')
  risk_data = sharpe
Beispiel #5
0
def compute_risk():

  global stats_dict
  for fund in fund_names:
    
    ret_data = []
    for i, units in enumerate(units_save_dict[fund]):
    
      # why (i + 13) and (i + 25)?
      # the header row and first 12 rows are ignored in nav_data
      # hence, the first index where investment starts is (i + 13)
      # to look nav of this investment one year later, we use (i + 25)
    
      if (i + 25) >= num_rows: break
      
      nav_line = nav_data[i + 13].split(',')[1:]
      nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
      inv = units * nav_dict[fund]
      if inv == 0: continue
      
      curr_nav_line = nav_data[i + 25].split(',')[1:]
      curr_nav_dict = common.get_fund_nav_dict(fund_names, curr_nav_line)
      wealth = units * curr_nav_dict[fund]
      
      ret = (wealth / inv) - 1.0
      ret_data.append(ret)
    
    sharpe = common.get_sharpe(ret_data, 'annual')
    stats_dict[fund].append(sharpe)
Beispiel #6
0
def compute_returns():

    global stats_dict, units_save_dict
    stop_inv_dict = defaultdict(lambda: None)
    inv_dict = defaultdict(float)
    units_dict = defaultdict(float)
    cashflows_dict = defaultdict(list)

    default_inv = common.mnt_inv
    max_total_inv = default_inv * (num_rows - 14)

    for i, r in enumerate(nav_data):

        if i < 13 or i == (num_rows - 1): continue
        dt = datetime.strptime(r.split(',')[0], '%d-%m-%Y')
        nav_line = r.split(',')[1:]
        nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
        wealth = get_fund_wealth(units_dict, nav_dict)

        index = i - 12
        for fund in fund_names:

            nav = nav_dict[fund]
            fund_value = wealth[fund]
            fund_inv = inv_dict[fund]

            mnt_inv = max(default_inv, default_inv * index - fund_value)
            mnt_inv = min(mnt_inv, max_total_inv - fund_inv)
            inv_dict[fund] += mnt_inv

            units = mnt_inv / nav
            units_dict[fund] += units
            units_save_dict[fund].append(units)
            cf = (dt, -mnt_inv)
            cashflows_dict[fund].append(cf)

            if fund_inv + mnt_inv == max_total_inv and not stop_inv_dict[fund]:
                stop_inv_dict[fund] = index

    last_line = nav_data[num_rows - 1].split(',')
    curr_dt = datetime.strptime(last_line[0], '%d-%m-%Y')
    curr_nav_line = last_line[1:]
    curr_nav_dict = common.get_fund_nav_dict(fund_names, curr_nav_line)

    for fund in fund_names:

        investment = inv_dict[fund]
        stop_inv = stop_inv_dict[fund]
        wealth = units_dict[fund] * curr_nav_dict[fund]
        abs_return = (wealth / investment) - 1

        cf = (curr_dt, wealth)
        cashflows_dict[fund].append(cf)
        ann_return = common.xirr(cashflows_dict[fund])

        stats = [investment, wealth, abs_return, ann_return, stop_inv]
        stats_dict[fund].extend(stats)
Beispiel #7
0
def compute_returns():
  
  global stats_dict, units_save_dict
  stop_inv_dict = defaultdict(lambda: None)
  inv_dict = defaultdict(float)
  units_dict = defaultdict(float)
  cashflows_dict = defaultdict(list)
  
  default_inv = common.mnt_inv
  max_total_inv = default_inv * (num_rows - 14)

  for i,r in enumerate(nav_data):
    
    if i < 13 or i == (num_rows - 1): continue
    dt = datetime.strptime(r.split(',')[0], '%d-%m-%Y')
    nav_line = r.split(',')[1:]
    nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
    wealth = get_fund_wealth(units_dict, nav_dict)
    
    index = i - 12
    for fund in fund_names:
    
      nav = nav_dict[fund]
      fund_value = wealth[fund]
      fund_inv = inv_dict[fund]
      
      mnt_inv = max(default_inv, default_inv * index - fund_value)
      mnt_inv = min(mnt_inv, max_total_inv - fund_inv)
      inv_dict[fund] += mnt_inv
      
      units = mnt_inv / nav
      units_dict[fund] += units
      units_save_dict[fund].append(units)
      cf = (dt, -mnt_inv)
      cashflows_dict[fund].append(cf)
      
      if fund_inv + mnt_inv == max_total_inv and not stop_inv_dict[fund]:
        stop_inv_dict[fund] = index
    
  last_line = nav_data[num_rows - 1].split(',')
  curr_dt = datetime.strptime(last_line[0], '%d-%m-%Y')
  curr_nav_line = last_line[1:]
  curr_nav_dict = common.get_fund_nav_dict(fund_names, curr_nav_line)

  for fund in fund_names:
    
    investment = inv_dict[fund]
    stop_inv = stop_inv_dict[fund]
    wealth = units_dict[fund] * curr_nav_dict[fund]
    abs_return = (wealth / investment) - 1
    
    cf = (curr_dt, wealth)
    cashflows_dict[fund].append(cf)
    ann_return = common.xirr(cashflows_dict[fund])
    
    stats = [investment, wealth, abs_return, ann_return, stop_inv]
    stats_dict[fund].extend(stats)
Beispiel #8
0
def compute_returns():
  
  global perf_data
  total_inv = 0
  cashflows = []
  units_dict = defaultdict(float)
  
  max_total_inv = common.mnt_inv * (num_rows - 14)

  prev_inv = common.mnt_inv
  for i,r in enumerate(nav_data):
  
    if i < 13 or i == (num_rows - 1): continue
    dt = datetime.strptime(r.split(',')[0], '%d-%m-%Y')
    nav_line = r.split(',')[1:]
    nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
    
    index = i - 13
    j = i - 12
    fund = sharpe_rank_data[j].split(',')[1]
    nav = nav_dict[fund]
    ma = ma_dict[fund][i - 13]
    
    allowed_inv = max_total_inv - total_inv
    mnt_inv = get_mnt_inv(index, nav, ma, prev_inv)
    mnt_inv = min(mnt_inv, allowed_inv)
    
    cf = (dt, -mnt_inv)
    cashflows.append(cf)
    
    units = mnt_inv / nav
    units_dict[fund] += units
    total_inv += mnt_inv
    prev_inv = mnt_inv
    
  save_inv_data(units_dict)

  last_line = nav_data[num_rows - 1].split(',')
  curr_dt = datetime.strptime(last_line[0], '%d-%m-%Y')
  curr_nav_line = last_line[1:]
  curr_nav_dict = common.get_fund_nav_dict(fund_names, curr_nav_line)
  
  wealth = 0
  for fund in units_dict:
    wealth += units_dict[fund] * curr_nav_dict[fund]
  
  cf = (curr_dt, wealth)
  cashflows.append(cf)
  abs_return = (wealth / total_inv) - 1
  ann_return = common.xirr(cashflows)
  perf_data = (total_inv, wealth, abs_return, ann_return)
Beispiel #9
0
def compute_risk():
  
  inv_dict = defaultdict(list)
  ret_dict = defaultdict(list)
  units_dict = defaultdict(list)
  
  for i,r in enumerate(nav_data):
    
    if i < 13 or i == (num_rows - 1): continue
    nav_line = r.split(',')[1:]
    nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
    
    for fund in fund_names:
      nav = nav_dict[fund]
      units = mnt_inv / nav
      units_dict[fund].append(units)
      inv_dict[fund].append(mnt_inv)
      
      if len(inv_dict[fund]) == 13:
        inv = inv_dict[fund][0]
        units = units_dict[fund][0]
        wealth = nav * units
        ret = (wealth / inv) - 1.0
        ret_dict[fund].append(ret)
        del inv_dict[fund][0]
        del units_dict[fund][0]
        
  for fund in fund_names:
    sharpe = common.get_sharpe(ret_dict[fund], 'annual')
    risk_dict[fund] = sharpe
Beispiel #10
0
def compute_returns():

    global stats_data
    cashflows = []
    units_dict = defaultdict(float)

    num_funds = len(fund_names)
    default_inv = common.mnt_inv
    mnt_inv = (default_inv * 1.0) / num_funds
    print 'monthly investment - %f' % mnt_inv

    total_inv = 0
    for i, r in enumerate(nav_data):

        if i < 13 or i == (num_rows - 1): continue
        dt = datetime.strptime(r.split(',')[0], '%d-%m-%Y')
        nav_line = r.split(',')[1:]
        nav_dict = common.get_fund_nav_dict(fund_names, nav_line)

        cf = (dt, -default_inv)
        cashflows.append(cf)

        for fund in fund_names:

            nav = nav_dict[fund]
            units = mnt_inv / nav
            units_dict[fund] += units
            total_inv += mnt_inv

    last_line = nav_data[num_rows - 1].split(',')
    curr_dt = datetime.strptime(last_line[0], '%d-%m-%Y')
    curr_nav_line = last_line[1:]
    curr_nav_dict = common.get_fund_nav_dict(fund_names, curr_nav_line)

    wealth = 0
    for fund in fund_names:
        wealth += units_dict[fund] * curr_nav_dict[fund]

    cf = (curr_dt, wealth)
    cashflows.append(cf)
    abs_return = (wealth / total_inv) - 1
    ann_return = common.xirr(cashflows)
    stat = [total_inv, wealth, abs_return, ann_return]
    stats_data.extend(stat)
Beispiel #11
0
def compute_returns():
  
  global perf_data
  total_inv = 0
  cashflows = []
  units_dict = defaultdict(float)
  
  for i,r in enumerate(nav_data):
  
    if i < 13 or i == (num_rows - 1): continue
    dt = datetime.strptime(r.split(',')[0], '%d-%m-%Y')
    nav_line = r.split(',')[1:]
    nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
    
    total_inv += mnt_inv
    cf = (dt, -mnt_inv)
    cashflows.append(cf)
    
    j = i - 12
    fund = sharpe_rank_data[j].split(',')[1]
    nav = nav_dict[fund]
    units = mnt_inv / nav
    units_dict[fund] += units
    
  save_inv_data(units_dict)

  last_line = nav_data[num_rows - 1].split(',')
  curr_dt = datetime.strptime(last_line[0], '%d-%m-%Y')
  curr_nav_line = last_line[1:]
  curr_nav_dict = common.get_fund_nav_dict(fund_names, curr_nav_line)
  
  wealth = 0
  for fund in units_dict:
    wealth += units_dict[fund] * curr_nav_dict[fund]
  
  cf = (curr_dt, wealth)
  cashflows.append(cf)
  abs_return = (wealth / total_inv) - 1
  ann_return = common.xirr(cashflows)
  perf_data = (total_inv, wealth, abs_return, ann_return)
Beispiel #12
0
def compute_returns():

    global perf_data
    total_inv = 0
    cashflows = []
    units_dict = defaultdict(float)

    for i, r in enumerate(nav_data):

        if i < 13 or i == (num_rows - 1): continue
        dt = datetime.strptime(r.split(',')[0], '%d-%m-%Y')
        nav_line = r.split(',')[1:]
        nav_dict = common.get_fund_nav_dict(fund_names, nav_line)

        total_inv += mnt_inv
        cf = (dt, -mnt_inv)
        cashflows.append(cf)

        j = i - 12
        fund = sharpe_rank_data[j].split(',')[1]
        nav = nav_dict[fund]
        units = mnt_inv / nav
        units_dict[fund] += units

    save_inv_data(units_dict)

    last_line = nav_data[num_rows - 1].split(',')
    curr_dt = datetime.strptime(last_line[0], '%d-%m-%Y')
    curr_nav_line = last_line[1:]
    curr_nav_dict = common.get_fund_nav_dict(fund_names, curr_nav_line)

    wealth = 0
    for fund in units_dict:
        wealth += units_dict[fund] * curr_nav_dict[fund]

    cf = (curr_dt, wealth)
    cashflows.append(cf)
    abs_return = (wealth / total_inv) - 1
    ann_return = common.xirr(cashflows)
    perf_data = (total_inv, wealth, abs_return, ann_return)
Beispiel #13
0
def compute_rank():

  global data_dict, sharpe_rank_data
  sharpe_data = common.get_sharpe_data()
  
  sharpe_rank_data = []
  header_line = 'Date,Fund'
  sharpe_rank_data.append(header_line)
  
  for i,r in enumerate(sharpe_data):
  
    if i == 0: continue
    dt = r.split(',')[0]
    data_line = r.split(',')[1:]
    data_dict = common.get_fund_nav_dict(fund_names, data_line)
    sorted_funds = sorted(fund_names, key=sort_fn, reverse=True)
    
    line_data = dt + ',' + sorted_funds[index]
    sharpe_rank_data.append(line_data)

  sharpe_rank_file = 'sharpeRank' + str(rank_type).capitalize() + str(rank) + '.csv'
  sharpe_rank_file_path = os.path.join(data_dir, sharpe_rank_file)
  common.write_to_file(sharpe_rank_file_path, sharpe_rank_data)
Beispiel #14
0
def compute_rank():

  global data_dict, sharpe_rank_data
  sharpe_data = common.get_sharpe_data()
  
  sharpe_rank_data = []
  header_line = 'Date,Fund'
  sharpe_rank_data.append(header_line)
  
  for i,r in enumerate(sharpe_data):
  
    if i == 0: continue
    dt = r.split(',')[0]
    data_line = r.split(',')[1:]
    data_dict = common.get_fund_nav_dict(fund_names, data_line)
    sorted_funds = sorted(fund_names, key=sort_fn, reverse=True)
    
    line_data = dt + ',' + sorted_funds[index]
    sharpe_rank_data.append(line_data)

  sharpe_rank_file = 'sharpeRank' + str(type).capitalize() + str(rank) + '.csv'
  sharpe_rank_file_path = os.path.join(data_dir, sharpe_rank_file)
  common.write_to_file(sharpe_rank_file_path, sharpe_rank_data)
Beispiel #15
0
def compute_returns():

  inv_dict = defaultdict(float)
  units_dict = defaultdict(float)
  cashflows_dict = defaultdict(list)
  
  for i,r in enumerate(nav_data):
    
    if i < 13 or i == (num_rows - 1): continue
    dt = datetime.strptime(r.split(',')[0], '%d-%m-%Y')
    nav_line = r.split(',')[1:]
    nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
    
    cf = (dt, -mnt_inv)
    for fund in fund_names:
      nav = nav_dict[fund]
      units = mnt_inv / nav
      inv_dict[fund] += mnt_inv
      units_dict[fund] += units
      cashflows_dict[fund].append(cf)

  last_line = nav_data[num_rows - 1].split(',')
  curr_dt = datetime.strptime(last_line[0], '%d-%m-%Y')
  curr_nav_line = last_line[1:]
  
  curr_nav_dict = {}
  for fund, nav in zip(fund_names, curr_nav_line):
    curr_nav_dict[fund] = float(nav)

  for fund in fund_names:
    investment = inv_dict[fund]
    wealth = units_dict[fund] * curr_nav_dict[fund]
    cf = (curr_dt, wealth)
    cashflows_dict[fund].append(cf)
    abs_return = (wealth / investment) - 1
    ann_return = common.xirr(cashflows_dict[fund])
    perf_dict[fund] = (investment, wealth, abs_return, ann_return)
Beispiel #16
0
def run(nav_file):
  
  # create data directory
  common.create_dir(data_dir)
  
  # read nav data
  nav_data = common.read_from_file(nav_file)
  
  # remove first 12 entries in nav_data 
  # to compare results with benchmark
  del nav_data[1:13]

  # retrieve fund names
  # the first column (date) is skipped
  fund_names = nav_data[0].split(',')[1:]
  
  # initialize
  cashflows = []
  returns_halfyr = common.init_array_dict(fund_names)
  returns_annual = common.init_array_dict(fund_names)
  units_dict_halfyr = common.init_dict(fund_names)
  units_dict_annual = common.init_dict(fund_names)
  units_dict_overall = common.init_dict(fund_names)
  
  # remove header line
  del nav_data[0]

  # compute cashflows and returns
  cnt = len(nav_data)
  for i in range(0, cnt):

    row_data = nav_data[i].split(',')
    dt = datetime.strptime(row_data[0], '%d-%m-%Y')
    fund_nav = row_data[1:]
    fund_nav_dict = common.get_fund_nav_dict(fund_names, fund_nav)
      
    # half-yearly returns for each fund
    if i % 6 == 0 and i > 0:
      wealth = common.get_fund_wealth(fund_nav_dict, units_dict_halfyr)
      for fund in fund_names:
        cashflows_halfyr = cashflows[i-6:i] # slice last 6 months cashflows
        cf = (dt, wealth[fund])
        cashflows_halfyr.append(cf)
        ret = common.xirr(cashflows_halfyr)
        returns_halfyr[fund].append(ret)

      # clean up for next pass
      units_dict_halfyr = common.init_dict(fund_names)

    # annual returns for each fund
    if i % 12 == 0 and i > 0:
      wealth = common.get_fund_wealth(fund_nav_dict, units_dict_annual)
      for fund in fund_names:
        cashflows_annual = cashflows[i-12:i] # slice last 12 months cashflows
        cf = (dt, wealth[fund])
        cashflows_annual.append(cf)
        ret = common.xirr(cashflows_annual)
        returns_annual[fund].append(ret)
      
      # clean up for next pass
      units_dict_annual = common.init_dict(fund_names)
    
    # no investment on the last date
    if i == cnt - 1:
      break
    
    # invested units
    for fund in fund_names:
      nav = fund_nav_dict[fund]
      units = mnt_inv / nav
      units_dict_halfyr[fund] += units
      units_dict_annual[fund] += units
      units_dict_overall[fund] += units
    
    # cash outflow
    cf = (dt, -mnt_inv)
    cashflows.append(cf)
  
  file_data = []
  
  header_line = \
    'Fund,Investment,Wealth,Absolute Return,Annualized Return,' + \
    'Half-Yr Return Mean,Half-Yr Return Std Dev,Half-Yr Sharpe,' + \
    'Annual Return Mean,Annual Return Std Dev,Annual Sharpe'
  file_data.append(header_line)
    
  # total investment
  num_inv = len(cashflows)
  total_inv = num_inv * mnt_inv
  
  # final wealth
  nav_line = nav_data[cnt - 1].split(',')[1:]
  fund_nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
  wealth = common.get_fund_wealth(fund_nav_dict, units_dict_overall)
  
  # performance stats for each fund
  last_date = nav_data[cnt - 1].split(',')[0]
  dt = datetime.strptime(last_date, '%d-%m-%Y')
  for fund in sorted(fund_names):
    fund_cashflows = cashflows[:]
    cf = (dt, wealth[fund])
    fund_cashflows.append(cf)
    abs_return = ((wealth[fund] / total_inv) - 1)
    ann_return = common.xirr(fund_cashflows)
    
    hfr = returns_halfyr[fund]
    halfyr_rf_rate = common.get_rf_rate('half-yearly')
    halfyr_return_mean = numpy.mean(hfr)
    halfyr_return_std = numpy.std(hfr)
    halfyr_sharpe = common.get_sharpe_ratio(hfr, halfyr_rf_rate)

    afr = returns_annual[fund]
    annual_rf_rate = common.get_rf_rate('annual')
    annual_return_mean = numpy.mean(afr)
    annual_return_std = numpy.std(afr)
    annual_sharpe = common.get_sharpe_ratio(afr, annual_rf_rate)
    
    line_data = \
      fund + ',' + str(total_inv) + ',' + str(wealth[fund]) + ',' + \
      str(abs_return) + ',' + str(ann_return) + ',' + \
      str(halfyr_return_mean) + ',' + str(halfyr_return_std) + ',' + \
      str(halfyr_sharpe) + ',' + str(annual_return_mean) + ',' + \
      str(annual_return_std) + ',' + str(annual_sharpe)
    file_data.append(line_data)

  regular_sip_file = os.path.join(data_dir, regular_sip_file_name)
  common.write_to_file(regular_sip_file, file_data)
Beispiel #17
0
def compute_returns():

  global stats_dict, units_save_dict
  stop_inv_dict = defaultdict(lambda: None)
  inv_dict = defaultdict(float)
  last_inv_dict = defaultdict(lambda: common.mnt_inv)
  units_dict = defaultdict(float)
  cashflows_dict = defaultdict(list)
  
  # why (num_rows - 14)
  # ignore header, first 12 rows and last row
  max_total_inv = common.mnt_inv * (num_rows - 14)
  
  for i,r in enumerate(nav_data):
    
    if i < 13 or i == (num_rows - 1): continue
    dt = datetime.strptime(r.split(',')[0], '%d-%m-%Y')
    nav_line = r.split(',')[1:]
    nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
    index = i - 13
    
    for fund in fund_names:
    
      nav = nav_dict[fund]
      ma = ma_dict[fund][i - 13]
      fund_inv = inv_dict[fund]    
      prev_inv = last_inv_dict[fund]

      allowed_inv = max_total_inv - fund_inv
      mnt_inv = get_mnt_inv(index, nav, ma, prev_inv)
      mnt_inv = min(mnt_inv, allowed_inv)
      
      units = mnt_inv / nav
      units_dict[fund] += units
      units_save_dict[fund].append(units)
      inv_dict[fund] += mnt_inv
      last_inv_dict[fund] = mnt_inv
      
      cf = (dt, -mnt_inv)
      cashflows_dict[fund].append(cf)
      
      if fund_inv + mnt_inv == max_total_inv and not stop_inv_dict[fund]:
        stop_inv_dict[fund] = (index + 1)
  
  last_line = nav_data[num_rows - 1].split(',')
  curr_dt = datetime.strptime(last_line[0], '%d-%m-%Y')
  curr_nav_line = last_line[1:]
  curr_nav_dict = common.get_fund_nav_dict(fund_names, curr_nav_line)

  for fund in fund_names:

    investment = inv_dict[fund]
    stop_inv = stop_inv_dict[fund]
    wealth = units_dict[fund] * curr_nav_dict[fund]
    abs_return = (wealth / investment) - 1
    
    cf = (curr_dt, wealth)
    cashflows_dict[fund].append(cf)
    ann_return = common.xirr(cashflows_dict[fund])
    
    stats = [investment, wealth, abs_return, ann_return, stop_inv]
    stats_dict[fund].extend(stats)
Beispiel #18
0
def run(nav_file, rank_file):
  """
  Generates return statistics based on sharpe ratio ranking data.
  """

  # create data directory
  common.create_dir(data_dir)

  # read data files
  nav_data = common.read_from_file(nav_file)
  rank_data = common.read_from_file(rank_file)
  
  # remove redundant entries in nav_data
  target_date = rank_data[1].split(',')[0]
  common.trim_data(nav_data, target_date)
  assert len(nav_data) == len(rank_data)

  # retrieve fund names
  # the first column (date) is skipped
  fund_names = nav_data[0].split(',')[1:]

  # initialize
  cashflows_halfyr = []
  cashflows_annual = []
  cashflows_overall = []
  returns_halfyr = []
  returns_annual = []
  units_dict_halfyr = common.init_dict(fund_names)
  units_dict_annual = common.init_dict(fund_names)
  units_dict_overall = common.init_dict(fund_names)

  # remove header line
  del nav_data[0]
  del rank_data[0] 

  # compute cashflows and returns
  cnt = len(nav_data)
  for i in range(0, cnt):
  
    (date, fund, nav) = rank_data[i].split(',')
    dt = datetime.strptime(date, '%d-%m-%Y')
  
    # half-yearly returns
    if i % 6 == 0 and i > 0:
      nav_line = nav_data[i].split(',')[1:]
      fund_nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
      wealth = get_wealth(fund_nav_dict, units_dict_halfyr)
      cf = (dt, wealth)
      cashflows_halfyr.append(cf)
      ret = common.xirr(cashflows_halfyr)
      returns_halfyr.append(ret)

      # clean up for next pass
      del cashflows_halfyr[:]
      units_dict_halfyr[f] = common.init_dict(fund_names)
      
    # annual returns
    if i % 12 == 0 and i > 0:
      nav_line = nav_data[i].split(',')[1:]
      nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
      wealth = get_wealth(nav_dict, units_dict_annual)
      cf = (dt, wealth)
      cashflows_annual.append(cf)
      ret = common.xirr(cashflows_annual)
      returns_annual.append(ret)

      # clean up for next pass
      del cashflows_annual[:]
      units_dict_annual[f] = common.init_dict(fund_names)
    
    # no investment on the last date
    if i == cnt - 1:
      break
    
    # units invested
    units = mnt_inv / float(nav)
    units_dict_halfyr[fund] += units
    units_dict_annual[fund] += units
    units_dict_overall[fund] += units

    # cash outflow
    cf = (dt, -mnt_inv)
    cashflows_halfyr.append(cf)
    cashflows_annual.append(cf)
    cashflows_overall.append(cf)
  
  file_data = []
  
  # investment details
  file_data.append('Investment Details')
  file_data.append('Fund,Units')
  for f in units_dict_overall:
    if units_dict_overall[f] > 0:
      line_data = f + ','  + str(units_dict_overall[f])
      file_data.append(line_data)
  file_data.append('\n')
  
  # total investment
  num_inv = len(cashflows_overall)
  total_inv = num_inv * mnt_inv
  file_data.append('Investment,' + str(total_inv))
  
  # final wealth
  nav_line = nav_data[cnt - 1].split(',')[1:]
  fund_nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
  wealth = get_wealth(fund_nav_dict, units_dict_overall)
  file_data.append('Wealth,' + str(wealth))
  
  # absolute return
  abs_return = ((wealth / total_inv) - 1)
  file_data.append('Absolute Return,' + str(abs_return))
  
  # annualized return
  last_date = nav_data[cnt - 1].split(',')[0]
  dt = datetime.strptime(last_date, '%d-%m-%Y')
  cf = (dt, wealth)
  cashflows_overall.append(cf)
  annual_return = common.xirr(cashflows_overall)
  file_data.append('Annualized Return,' + str(annual_return))
  
  file_data.append('\n')
  file_data.append('Stats,Mean,Std Deviation, Sharpe Ratio')
  
  # half-yearly return stats
  halfyr_rf_rate = common.get_rf_rate('half-yearly')
  halfyr_mean = numpy.mean(returns_halfyr)
  halfyr_stdev = numpy.std(returns_halfyr)
  halfyr_sharpe = common.get_sharpe_ratio(returns_halfyr, halfyr_rf_rate)
  file_data.append('Half-Yearly,' + str(halfyr_mean) + ',' + str(halfyr_stdev) + ',' + str(halfyr_sharpe))
  
  # annual return stats
  annual_rf_rate = common.get_rf_rate('annual')
  annual_mean = numpy.mean(returns_annual)
  annual_stdev = numpy.std(returns_annual)
  annual_sharpe = common.get_sharpe_ratio(returns_annual, annual_rf_rate)
  file_data.append('Annual,' + str(annual_mean) + ',' + str(annual_stdev) + ',' + str(annual_sharpe))
  
  # save stats to file
  benchmark_file = os.path.join(data_dir, benchmark_file_name)
  common.write_to_file(benchmark_file, file_data)
Beispiel #19
0
def run(nav_file, rank_file):
    """
  Generates return statistics based on sharpe ratio ranking data.
  """

    # create data directory
    common.create_dir(data_dir)

    # read data files
    nav_data = common.read_from_file(nav_file)
    rank_data = common.read_from_file(rank_file)

    # remove redundant entries in nav_data
    target_date = rank_data[1].split(',')[0]
    common.trim_data(nav_data, target_date)
    assert len(nav_data) == len(rank_data)

    # retrieve fund names
    # the first column (date) is skipped
    fund_names = nav_data[0].split(',')[1:]

    # initialize
    cashflows_halfyr = []
    cashflows_annual = []
    cashflows_overall = []
    returns_halfyr = []
    returns_annual = []
    units_dict_halfyr = common.init_dict(fund_names)
    units_dict_annual = common.init_dict(fund_names)
    units_dict_overall = common.init_dict(fund_names)

    # remove header line
    del nav_data[0]
    del rank_data[0]

    # compute cashflows and returns
    cnt = len(nav_data)
    for i in range(0, cnt):

        (date, fund, nav) = rank_data[i].split(',')
        dt = datetime.strptime(date, '%d-%m-%Y')

        # half-yearly returns
        if i % 6 == 0 and i > 0:
            nav_line = nav_data[i].split(',')[1:]
            fund_nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
            wealth = get_wealth(fund_nav_dict, units_dict_halfyr)
            cf = (dt, wealth)
            cashflows_halfyr.append(cf)
            ret = common.xirr(cashflows_halfyr)
            returns_halfyr.append(ret)

            # clean up for next pass
            del cashflows_halfyr[:]
            units_dict_halfyr[f] = common.init_dict(fund_names)

        # annual returns
        if i % 12 == 0 and i > 0:
            nav_line = nav_data[i].split(',')[1:]
            nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
            wealth = get_wealth(nav_dict, units_dict_annual)
            cf = (dt, wealth)
            cashflows_annual.append(cf)
            ret = common.xirr(cashflows_annual)
            returns_annual.append(ret)

            # clean up for next pass
            del cashflows_annual[:]
            units_dict_annual[f] = common.init_dict(fund_names)

        # no investment on the last date
        if i == cnt - 1:
            break

        # units invested
        units = mnt_inv / float(nav)
        units_dict_halfyr[fund] += units
        units_dict_annual[fund] += units
        units_dict_overall[fund] += units

        # cash outflow
        cf = (dt, -mnt_inv)
        cashflows_halfyr.append(cf)
        cashflows_annual.append(cf)
        cashflows_overall.append(cf)

    file_data = []

    # investment details
    file_data.append('Investment Details')
    file_data.append('Fund,Units')
    for f in units_dict_overall:
        if units_dict_overall[f] > 0:
            line_data = f + ',' + str(units_dict_overall[f])
            file_data.append(line_data)
    file_data.append('\n')

    # total investment
    num_inv = len(cashflows_overall)
    total_inv = num_inv * mnt_inv
    file_data.append('Investment,' + str(total_inv))

    # final wealth
    nav_line = nav_data[cnt - 1].split(',')[1:]
    fund_nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
    wealth = get_wealth(fund_nav_dict, units_dict_overall)
    file_data.append('Wealth,' + str(wealth))

    # absolute return
    abs_return = ((wealth / total_inv) - 1)
    file_data.append('Absolute Return,' + str(abs_return))

    # annualized return
    last_date = nav_data[cnt - 1].split(',')[0]
    dt = datetime.strptime(last_date, '%d-%m-%Y')
    cf = (dt, wealth)
    cashflows_overall.append(cf)
    annual_return = common.xirr(cashflows_overall)
    file_data.append('Annualized Return,' + str(annual_return))

    file_data.append('\n')
    file_data.append('Stats,Mean,Std Deviation, Sharpe Ratio')

    # half-yearly return stats
    halfyr_rf_rate = common.get_rf_rate('half-yearly')
    halfyr_mean = numpy.mean(returns_halfyr)
    halfyr_stdev = numpy.std(returns_halfyr)
    halfyr_sharpe = common.get_sharpe_ratio(returns_halfyr, halfyr_rf_rate)
    file_data.append('Half-Yearly,' + str(halfyr_mean) + ',' +
                     str(halfyr_stdev) + ',' + str(halfyr_sharpe))

    # annual return stats
    annual_rf_rate = common.get_rf_rate('annual')
    annual_mean = numpy.mean(returns_annual)
    annual_stdev = numpy.std(returns_annual)
    annual_sharpe = common.get_sharpe_ratio(returns_annual, annual_rf_rate)
    file_data.append('Annual,' + str(annual_mean) + ',' + str(annual_stdev) +
                     ',' + str(annual_sharpe))

    # save stats to file
    benchmark_file = os.path.join(data_dir, benchmark_file_name)
    common.write_to_file(benchmark_file, file_data)
Beispiel #20
0
def run(nav_file, ma_type):
  nav_data = common.read_from_file(nav_file)
  fund_names = nav_data[0].split(',')[1:]
  del nav_data[1:7]
  ma_data = get_ma_data(nav_data)
  del nav_data[0:7]
  
  cashflows = common.init_array_dict(fund_names)
  fund_inv_dict = common.init_dict(fund_names)
  fund_corpus_dict = common.init_dict(fund_names)
  fund_corpus_index_dict = common.init_array_dict(fund_names)
  last_inv_dict = common.init_dict(fund_names, default_inv)
  returns_halfyr = common.init_array_dict(fund_names)
  returns_annual = common.init_array_dict(fund_names)
  units_dict_halfyr = common.init_dict(fund_names)
  units_dict_annual = common.init_dict(fund_names)
  units_dict_overall = common.init_dict(fund_names)
  
  cnt = len(nav_data)
  max_total_inv = default_inv * (cnt - 1)
  for i in xrange(0, cnt):
  
    row_data = nav_data[i].split(',')
    dt = datetime.strptime(row_data[0], '%d-%m-%Y')
    fund_nav = row_data[1:]
    fund_nav_dict = common.get_fund_nav_dict(fund_names, fund_nav)
    
    # half-yearly returns for each fund
    if i % 6 == 0 and i > 0:
      
      wealth = common.get_fund_wealth(fund_nav_dict, units_dict_halfyr)
      for fund in fund_names:
        start_corpus = fund_corpus_index_dict[fund][i-7]
        end_corpus = fund_corpus_index_dict[fund][i-1]
        corpus_wealth = end_corpus - start_corpus
        total_wealth = wealth[fund] + corpus_wealth
        
        cashflows_halfyr = cashflows[fund][i-6:i] # slice last 6 months cashflows
        if is_cashflow_missing(cashflows_halfyr):
          continue
          
        cf = (dt, total_wealth)
        cashflows_halfyr.append(cf)
        ret = common.xirr(cashflows_halfyr)
        returns_halfyr[fund].append(ret)

      # clean up
      units_dict_halfyr = common.init_dict(fund_names)

    # annual returns for each fund
    if i % 12 == 0 and i > 0:
      
      wealth = common.get_fund_wealth(fund_nav_dict, units_dict_annual)
      for fund in fund_names:
        start_corpus = fund_corpus_index_dict[fund][i-13]
        end_corpus = fund_corpus_index_dict[fund][i-1]
        corpus_wealth = end_corpus - start_corpus
        total_wealth = wealth[fund] + corpus_wealth
      
        cashflows_annual = cashflows[fund][i-12:i] # slice last 12 months cashflows
        if is_cashflow_missing(cashflows_annual):
          continue
          
        cf = (dt, wealth[fund] + fund_corpus_dict[fund])
        cashflows_annual.append(cf)
        ret = common.xirr(cashflows_annual)
        returns_annual[fund].append(ret)

      # clean up
      units_dict_annual = common.init_dict(fund_names)
    
    # no investment on the last date
    if i == cnt - 1:
      break
    
    for f in fund_names:
      
      # cap total investment
      allowed_inv = max_total_inv - fund_inv_dict[f]
    
      prev_inv = last_inv_dict[f]
      nav = fund_nav_dict[f]
      ma = ma_data[f][i]
      
      # equity investment
      mnt_inv = get_mnt_inv(ma_type, prev_inv, nav, ma)
      mnt_inv = min(mnt_inv, allowed_inv)
      last_inv_dict[f] = mnt_inv
      allowed_inv -= mnt_inv
      
      # debt investment
      corpus = fund_corpus_dict[f]
      debt_inv = default_inv - mnt_inv
      if debt_inv < 0:
        debt_inv = -min(mnt_inv - default_inv, corpus)
      else:
        debt_inv = min(debt_inv, allowed_inv)
        
      # corpus investment + interest
      corpus += debt_inv
      interest = corpus * int_rate
      corpus += interest
      fund_corpus_dict[f] = corpus
      fund_corpus_index_dict[f].append(corpus)
      
      # total investment
      total_inv = mnt_inv + debt_inv
      fund_inv_dict[f] += total_inv

      # invested units
      units = mnt_inv / nav
      units_dict_overall[f] += units
      units_dict_halfyr[f] += units
      units_dict_annual[f] += units

      # cashflows
      cf = (dt, -total_inv)
      cashflows[f].append(cf)

      # debugging
      # if f == 'Birla_Advantage_Fund':
        # print '%d\t%d\t%d\t%.2f\t%d\t%d' % (mnt_inv, debt_inv, round(fund_inv_dict[f]), units, -total_inv, round(corpus))

  file_data = []
  
  header_line = \
    'Fund,Investment,Wealth,Absolute Return,Annualized Return,' + \
    'Half-Yr Return Mean,Half-Yr Return Std Dev,Half-Yr Sharpe,' + \
    'Annual Return Mean,Annual Return Std Dev,Annual Sharpe'
  file_data.append(header_line)
  
  # final wealth
  nav_line = nav_data[cnt - 1].split(',')[1:]
  fund_nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
  wealth = common.get_fund_wealth(fund_nav_dict, units_dict_overall)

  # performance stats for each fund
  last_date = nav_data[cnt - 1].split(',')[0]
  dt = datetime.strptime(last_date, '%d-%m-%Y')
  for fund in sorted(fund_names):    
    total_wealth = wealth[fund] + fund_corpus_dict[fund]
    fund_cashflows = cashflows[fund][:]
    cf = (dt, total_wealth)
    fund_cashflows.append(cf)
    
    fund_inv = fund_inv_dict[fund]
    abs_return = ((total_wealth / fund_inv) - 1)
    ann_return = common.xirr(fund_cashflows)
    
    hfr = returns_halfyr[fund]
    halfyr_rf_rate = common.get_rf_rate('half-yearly')
    halfyr_return_mean = numpy.mean(hfr)
    halfyr_return_std = numpy.std(hfr)
    halfyr_sharpe = common.get_sharpe_ratio(hfr, halfyr_rf_rate)

    afr = returns_annual[fund]
    annual_rf_rate = common.get_rf_rate('annual')
    annual_return_mean = numpy.mean(afr)
    annual_return_std = numpy.std(afr)
    annual_sharpe = common.get_sharpe_ratio(afr, annual_rf_rate)
  
    line_data = \
      fund + ',' + str(fund_inv) + ',' + str(total_wealth) + ',' + \
      str(abs_return) + ',' + str(ann_return) + ',' + \
      str(halfyr_return_mean) + ',' + str(halfyr_return_std) + ',' + \
      str(halfyr_sharpe) + ',' + str(annual_return_mean) + ',' + \
      str(annual_return_std) + ',' + str(annual_sharpe)
    file_data.append(line_data)
  
  ma_file_name = 'ma_with_debt_' + ma_type + '.csv'
  ma_file = os.path.join(data_dir, ma_file_name)
  common.write_to_file(ma_file, file_data)
Beispiel #21
0
def run(nav_file, ma_type):
    nav_data = common.read_from_file(nav_file)
    fund_names = nav_data[0].split(',')[1:]
    del nav_data[1:7]
    ma_data = get_ma_data(nav_data)
    del nav_data[0:7]

    cashflows = common.init_array_dict(fund_names)
    fund_inv_dict = common.init_dict(fund_names)
    fund_corpus_dict = common.init_dict(fund_names)
    fund_corpus_index_dict = common.init_array_dict(fund_names)
    last_inv_dict = common.init_dict(fund_names, default_inv)
    returns_halfyr = common.init_array_dict(fund_names)
    returns_annual = common.init_array_dict(fund_names)
    units_dict_halfyr = common.init_dict(fund_names)
    units_dict_annual = common.init_dict(fund_names)
    units_dict_overall = common.init_dict(fund_names)

    cnt = len(nav_data)
    max_total_inv = default_inv * (cnt - 1)
    for i in xrange(0, cnt):

        row_data = nav_data[i].split(',')
        dt = datetime.strptime(row_data[0], '%d-%m-%Y')
        fund_nav = row_data[1:]
        fund_nav_dict = common.get_fund_nav_dict(fund_names, fund_nav)

        # half-yearly returns for each fund
        if i % 6 == 0 and i > 0:

            wealth = common.get_fund_wealth(fund_nav_dict, units_dict_halfyr)
            for fund in fund_names:
                start_corpus = fund_corpus_index_dict[fund][i - 7]
                end_corpus = fund_corpus_index_dict[fund][i - 1]
                corpus_wealth = end_corpus - start_corpus
                total_wealth = wealth[fund] + corpus_wealth

                cashflows_halfyr = cashflows[fund][
                    i - 6:i]  # slice last 6 months cashflows
                if is_cashflow_missing(cashflows_halfyr):
                    continue

                cf = (dt, total_wealth)
                cashflows_halfyr.append(cf)
                ret = common.xirr(cashflows_halfyr)
                returns_halfyr[fund].append(ret)

            # clean up
            units_dict_halfyr = common.init_dict(fund_names)

        # annual returns for each fund
        if i % 12 == 0 and i > 0:

            wealth = common.get_fund_wealth(fund_nav_dict, units_dict_annual)
            for fund in fund_names:
                start_corpus = fund_corpus_index_dict[fund][i - 13]
                end_corpus = fund_corpus_index_dict[fund][i - 1]
                corpus_wealth = end_corpus - start_corpus
                total_wealth = wealth[fund] + corpus_wealth

                cashflows_annual = cashflows[fund][
                    i - 12:i]  # slice last 12 months cashflows
                if is_cashflow_missing(cashflows_annual):
                    continue

                cf = (dt, wealth[fund] + fund_corpus_dict[fund])
                cashflows_annual.append(cf)
                ret = common.xirr(cashflows_annual)
                returns_annual[fund].append(ret)

            # clean up
            units_dict_annual = common.init_dict(fund_names)

        # no investment on the last date
        if i == cnt - 1:
            break

        for f in fund_names:

            # cap total investment
            allowed_inv = max_total_inv - fund_inv_dict[f]

            prev_inv = last_inv_dict[f]
            nav = fund_nav_dict[f]
            ma = ma_data[f][i]

            # equity investment
            mnt_inv = get_mnt_inv(ma_type, prev_inv, nav, ma)
            mnt_inv = min(mnt_inv, allowed_inv)
            last_inv_dict[f] = mnt_inv
            allowed_inv -= mnt_inv

            # debt investment
            corpus = fund_corpus_dict[f]
            debt_inv = default_inv - mnt_inv
            if debt_inv < 0:
                debt_inv = -min(mnt_inv - default_inv, corpus)
            else:
                debt_inv = min(debt_inv, allowed_inv)

            # corpus investment + interest
            corpus += debt_inv
            interest = corpus * int_rate
            corpus += interest
            fund_corpus_dict[f] = corpus
            fund_corpus_index_dict[f].append(corpus)

            # total investment
            total_inv = mnt_inv + debt_inv
            fund_inv_dict[f] += total_inv

            # invested units
            units = mnt_inv / nav
            units_dict_overall[f] += units
            units_dict_halfyr[f] += units
            units_dict_annual[f] += units

            # cashflows
            cf = (dt, -total_inv)
            cashflows[f].append(cf)

            # debugging
            # if f == 'Birla_Advantage_Fund':
            # print '%d\t%d\t%d\t%.2f\t%d\t%d' % (mnt_inv, debt_inv, round(fund_inv_dict[f]), units, -total_inv, round(corpus))

    file_data = []

    header_line = \
      'Fund,Investment,Wealth,Absolute Return,Annualized Return,' + \
      'Half-Yr Return Mean,Half-Yr Return Std Dev,Half-Yr Sharpe,' + \
      'Annual Return Mean,Annual Return Std Dev,Annual Sharpe'
    file_data.append(header_line)

    # final wealth
    nav_line = nav_data[cnt - 1].split(',')[1:]
    fund_nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
    wealth = common.get_fund_wealth(fund_nav_dict, units_dict_overall)

    # performance stats for each fund
    last_date = nav_data[cnt - 1].split(',')[0]
    dt = datetime.strptime(last_date, '%d-%m-%Y')
    for fund in sorted(fund_names):
        total_wealth = wealth[fund] + fund_corpus_dict[fund]
        fund_cashflows = cashflows[fund][:]
        cf = (dt, total_wealth)
        fund_cashflows.append(cf)

        fund_inv = fund_inv_dict[fund]
        abs_return = ((total_wealth / fund_inv) - 1)
        ann_return = common.xirr(fund_cashflows)

        hfr = returns_halfyr[fund]
        halfyr_rf_rate = common.get_rf_rate('half-yearly')
        halfyr_return_mean = numpy.mean(hfr)
        halfyr_return_std = numpy.std(hfr)
        halfyr_sharpe = common.get_sharpe_ratio(hfr, halfyr_rf_rate)

        afr = returns_annual[fund]
        annual_rf_rate = common.get_rf_rate('annual')
        annual_return_mean = numpy.mean(afr)
        annual_return_std = numpy.std(afr)
        annual_sharpe = common.get_sharpe_ratio(afr, annual_rf_rate)

        line_data = \
          fund + ',' + str(fund_inv) + ',' + str(total_wealth) + ',' + \
          str(abs_return) + ',' + str(ann_return) + ',' + \
          str(halfyr_return_mean) + ',' + str(halfyr_return_std) + ',' + \
          str(halfyr_sharpe) + ',' + str(annual_return_mean) + ',' + \
          str(annual_return_std) + ',' + str(annual_sharpe)
        file_data.append(line_data)

    ma_file_name = 'ma_with_debt_' + ma_type + '.csv'
    ma_file = os.path.join(data_dir, ma_file_name)
    common.write_to_file(ma_file, file_data)
Beispiel #22
0
def run(nav_file):

    # create data directory
    common.create_dir(data_dir)

    # read nav data
    nav_data = common.read_from_file(nav_file)

    # remove first 12 entries in nav_data
    # to compare results with benchmark
    del nav_data[1:13]

    # retrieve fund names
    # the first column (date) is skipped
    fund_names = nav_data[0].split(',')[1:]

    # initialize
    cashflows = []
    returns_halfyr = common.init_array_dict(fund_names)
    returns_annual = common.init_array_dict(fund_names)
    units_dict_halfyr = common.init_dict(fund_names)
    units_dict_annual = common.init_dict(fund_names)
    units_dict_overall = common.init_dict(fund_names)

    # remove header line
    del nav_data[0]

    # compute cashflows and returns
    cnt = len(nav_data)
    for i in range(0, cnt):

        row_data = nav_data[i].split(',')
        dt = datetime.strptime(row_data[0], '%d-%m-%Y')
        fund_nav = row_data[1:]
        fund_nav_dict = common.get_fund_nav_dict(fund_names, fund_nav)

        # half-yearly returns for each fund
        if i % 6 == 0 and i > 0:
            wealth = common.get_fund_wealth(fund_nav_dict, units_dict_halfyr)
            for fund in fund_names:
                cashflows_halfyr = cashflows[
                    i - 6:i]  # slice last 6 months cashflows
                cf = (dt, wealth[fund])
                cashflows_halfyr.append(cf)
                ret = common.xirr(cashflows_halfyr)
                returns_halfyr[fund].append(ret)

            # clean up for next pass
            units_dict_halfyr = common.init_dict(fund_names)

        # annual returns for each fund
        if i % 12 == 0 and i > 0:
            wealth = common.get_fund_wealth(fund_nav_dict, units_dict_annual)
            for fund in fund_names:
                cashflows_annual = cashflows[
                    i - 12:i]  # slice last 12 months cashflows
                cf = (dt, wealth[fund])
                cashflows_annual.append(cf)
                ret = common.xirr(cashflows_annual)
                returns_annual[fund].append(ret)

            # clean up for next pass
            units_dict_annual = common.init_dict(fund_names)

        # no investment on the last date
        if i == cnt - 1:
            break

        # invested units
        for fund in fund_names:
            nav = fund_nav_dict[fund]
            units = mnt_inv / nav
            units_dict_halfyr[fund] += units
            units_dict_annual[fund] += units
            units_dict_overall[fund] += units

        # cash outflow
        cf = (dt, -mnt_inv)
        cashflows.append(cf)

    file_data = []

    header_line = \
      'Fund,Investment,Wealth,Absolute Return,Annualized Return,' + \
      'Half-Yr Return Mean,Half-Yr Return Std Dev,Half-Yr Sharpe,' + \
      'Annual Return Mean,Annual Return Std Dev,Annual Sharpe'
    file_data.append(header_line)

    # total investment
    num_inv = len(cashflows)
    total_inv = num_inv * mnt_inv

    # final wealth
    nav_line = nav_data[cnt - 1].split(',')[1:]
    fund_nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
    wealth = common.get_fund_wealth(fund_nav_dict, units_dict_overall)

    # performance stats for each fund
    last_date = nav_data[cnt - 1].split(',')[0]
    dt = datetime.strptime(last_date, '%d-%m-%Y')
    for fund in sorted(fund_names):
        fund_cashflows = cashflows[:]
        cf = (dt, wealth[fund])
        fund_cashflows.append(cf)
        abs_return = ((wealth[fund] / total_inv) - 1)
        ann_return = common.xirr(fund_cashflows)

        hfr = returns_halfyr[fund]
        halfyr_rf_rate = common.get_rf_rate('half-yearly')
        halfyr_return_mean = numpy.mean(hfr)
        halfyr_return_std = numpy.std(hfr)
        halfyr_sharpe = common.get_sharpe_ratio(hfr, halfyr_rf_rate)

        afr = returns_annual[fund]
        annual_rf_rate = common.get_rf_rate('annual')
        annual_return_mean = numpy.mean(afr)
        annual_return_std = numpy.std(afr)
        annual_sharpe = common.get_sharpe_ratio(afr, annual_rf_rate)

        line_data = \
          fund + ',' + str(total_inv) + ',' + str(wealth[fund]) + ',' + \
          str(abs_return) + ',' + str(ann_return) + ',' + \
          str(halfyr_return_mean) + ',' + str(halfyr_return_std) + ',' + \
          str(halfyr_sharpe) + ',' + str(annual_return_mean) + ',' + \
          str(annual_return_std) + ',' + str(annual_sharpe)
        file_data.append(line_data)

    regular_sip_file = os.path.join(data_dir, regular_sip_file_name)
    common.write_to_file(regular_sip_file, file_data)
Beispiel #23
0
def run(nav_file, ma_type):
  nav_data = common.read_from_file(nav_file)
  fund_names = nav_data[0].split(',')[1:]
  del nav_data[1:7]
  ma_data = get_ma_data(nav_data)
  del nav_data[0:7]
  
  cashflows = common.init_array_dict(fund_names)
  fund_inv_dict = common.init_dict(fund_names)
  last_inv_dict = common.init_dict(fund_names, default_inv)
  returns_halfyr = common.init_array_dict(fund_names)
  returns_annual = common.init_array_dict(fund_names)
  units_dict_halfyr = common.init_dict(fund_names)
  units_dict_annual = common.init_dict(fund_names)
  units_dict_overall = common.init_dict(fund_names)
  
  cnt = len(nav_data)
  max_total_inv = default_inv * (cnt - 1)
  for i in xrange(0, cnt):
  
    row_data = nav_data[i].split(',')
    dt = datetime.strptime(row_data[0], '%d-%m-%Y')
    fund_nav = row_data[1:]
    fund_nav_dict = common.get_fund_nav_dict(fund_names, fund_nav)

    # half-yearly returns for each fund
    if i % 6 == 0 and i > 0:
      wealth = common.get_fund_wealth(fund_nav_dict, units_dict_halfyr)
      for fund in fund_names:
        cashflows_halfyr = cashflows[fund][i-6:i] # slice last 6 months cashflows
        if is_cashflow_missing(cashflows_halfyr):
          continue
        
        cf = (dt, wealth[fund])
        cashflows_halfyr.append(cf)
        ret = common.xirr(cashflows_halfyr)
        returns_halfyr[fund].append(ret)

      # clean up for next pass
      units_dict_halfyr = common.init_dict(fund_names)
    
    # annual returns for each fund
    if i % 12 == 0 and i > 0:
      wealth = common.get_fund_wealth(fund_nav_dict, units_dict_annual)
      for fund in fund_names:
        cashflows_annual = cashflows[fund][i-12:i] # slice last 12 months cashflows
        if is_cashflow_missing(cashflows_annual):
          continue
        
        cf = (dt, wealth[fund])
        cashflows_annual.append(cf)
        ret = common.xirr(cashflows_annual)
        returns_annual[fund].append(ret)
      
      # clean up for next pass
      units_dict_annual = common.init_dict(fund_names)
    
    # no investment on the last date
    if i == cnt - 1:
      break
    
    for f in fund_names:
      
      # cap total investment
      allowed_inv = max_total_inv - fund_inv_dict[f]
    
      prev_inv = last_inv_dict[f]
      nav = fund_nav_dict[f]
      ma = ma_data[f][i]
      
      mnt_inv = get_mnt_inv(ma_type, prev_inv, nav, ma)
      mnt_inv = min(mnt_inv, allowed_inv)
      units = mnt_inv / nav
      units_dict_overall[f] += units
      units_dict_halfyr[f] += units
      units_dict_annual[f] += units
      
      last_inv_dict[f] = mnt_inv
      fund_inv_dict[f] += mnt_inv
      cf = (dt, -mnt_inv)
      cashflows[f].append(cf)
      
  file_data = []
  
  header_line = \
    'Fund,Investment,Wealth,Absolute Return,Annualized Return,' + \
    'Half-Yr Return Mean,Half-Yr Return Std Dev,Half-Yr Sharpe,' + \
    'Annual Return Mean,Annual Return Std Dev,Annual Sharpe'
  file_data.append(header_line)
  
  # final wealth
  nav_line = nav_data[cnt - 1].split(',')[1:]
  fund_nav_dict = common.get_fund_nav_dict(fund_names, nav_line)
  wealth = common.get_fund_wealth(fund_nav_dict, units_dict_overall)

  # performance stats for each fund
  last_date = nav_data[cnt - 1].split(',')[0]
  dt = datetime.strptime(last_date, '%d-%m-%Y')
  for fund in sorted(fund_names):    
    fund_cashflows = cashflows[fund][:]
    cf = (dt, wealth[fund])
    fund_cashflows.append(cf)
    fund_inv = fund_inv_dict[fund]
    abs_return = ((wealth[fund] / fund_inv) - 1)
    ann_return = common.xirr(fund_cashflows)
  
    hfr = returns_halfyr[fund]
    halfyr_rf_rate = common.get_rf_rate('half-yearly')
    halfyr_return_mean = numpy.mean(hfr)
    halfyr_return_std = numpy.std(hfr)
    halfyr_sharpe = common.get_sharpe_ratio(hfr, halfyr_rf_rate)

    afr = returns_annual[fund]
    annual_rf_rate = common.get_rf_rate('annual')
    annual_return_mean = numpy.mean(afr)
    annual_return_std = numpy.std(afr)
    annual_sharpe = common.get_sharpe_ratio(afr, annual_rf_rate)
  
    line_data = \
      fund + ',' + str(fund_inv) + ',' + str(wealth[fund]) + ',' + \
      str(abs_return) + ',' + str(ann_return) + ',' + \
      str(halfyr_return_mean) + ',' + str(halfyr_return_std) + ',' + \
      str(halfyr_sharpe) + ',' + str(annual_return_mean) + ',' + \
      str(annual_return_std) + ',' + str(annual_sharpe)
    file_data.append(line_data)
  
  ma_file_name = 'ma_' + ma_type + '.csv'
  ma_file = os.path.join(data_dir, ma_file_name)
  common.write_to_file(ma_file, file_data)