<commit_before>'''
(c) 2011, 2012 Georgia Tech Research Corporation
This source code is released under the New BSD license.  Please see
http://wiki.quantsoftware.org/index.php?title=QSTK_License
for license details.

Created on Jan 1, 2011

@author:<NAME>
@contact: <EMAIL>
@summary: Contains tutorial for backtester and report.

'''


import math
import datetime as dt
import numpy as np
from qstkutil import qsdateutil
from math import sqrt
import pandas as pd
from copy import deepcopy


import random as rand

from qstkutil import DataAccess as da
from qstkutil import qsdateutil as du
import numpy as np

def daily(lfFunds):
    """
    @summary Computes daily returns centered around 0
    @param funds: A time series containing daily fund values
    @return an array of daily returns
    """
    if type(lfFunds) == type(pd.Series()):
        ldt_timestamps = du.getNYSEdays(lfFunds.index[0], lfFunds.index[-1], dt.timedelta(hours=16))
        lfFunds = lfFunds.reindex(index=ldt_timestamps, method='ffill')
    nds = np.asarray(deepcopy(lfFunds))
    s= np.shape(nds)
    if len(s)==1:
        nds=np.expand_dims(nds,1)
    returnize0(nds)
    return(nds)

def daily1(lfFunds):
    """
    @summary Computes daily returns centered around 1
    @param funds: A time series containing daily fund values
    @return an array of daily returns
    """
    nds = np.asarray(deepcopy(lfFunds))
    s= np.shape(nds)
    if len(s)==1:
        nds=np.expand_dims(nds,1)
    returnize1(nds)
    return(nds)

def monthly(funds):
    """
    @summary Computes monthly returns centered around 0
    @param funds: A time series containing daily fund values
    @return an array of monthly returns
    """
    funds2 = []
    last_last_month = -1
    years = qsdateutil.getYears(funds)
    for year in years:
        months = qsdateutil.getMonths(funds, year)
        for month in months:
            last_this_month = qsdateutil.getLastDay(funds, year, month)
            if last_last_month == -1 :
                last_last_month=qsdateutil.getFirstDay(funds, year, month)
            if type(funds).__name__=='TimeSeries':
                funds2.append(funds[last_this_month]/funds[last_last_month]-1)
            else:
                funds2.append(funds.xs(last_this_month)/funds.xs(last_last_month)-1)
            last_last_month = last_this_month
    return(funds2)

def average_monthly(funds):
    """
    @summary Computes average monthly returns centered around 0
    @param funds: A time series containing daily fund values
    @return an array of average monthly returns
    """
    rets = daily(funds)
    ret_i = 0
    years = qsdateutil.getYears(funds)
    averages = []
    for year in years:
        months = qsdateutil.getMonths(funds, year)
        for month in months:
            avg = 0
            count = 0
            days = qsdateutil.getDays(funds, year, month)
            for day in days:
                avg += rets[ret_i]
                ret_i += 1
                count += 1
            averages.append(float(avg) / count)
    return(averages)    

def fillforward(nds):
    """
    @summary Removes NaNs from a 2D array by scanning forward in the 
    1st dimension.  If a cell is NaN, the value above it is carried forward.
    @param nds: the array to fill forward
    @return the array is revised in place
    """
    for col in range(nds.shape[1]):
        for row in range(1, nds.shape[0]):
            if math.isnan(nds[row, col]):
                nds[row, col] = nds[row-1, col]

def fillbackward(nds):
    """
    @summary Removes NaNs from a 2D array by scanning backward in the 
    1st dimension.  If a cell is NaN, the value above it is carried backward.
    @param nds: the array to fill backward
    @return the array is revised in place
    """
    for col in range(nds.shape[1]):
        for row in range(nds.shape[0] - 2, -1, -1):
            if math.isnan(nds[row, col]):
                nds[row, col] = nds[row+1, col]

def returnize0(nds):
    """
    @summary Computes stepwise (usually daily) returns relative to 0, where
    0 implies no change in value.
    @return the array is revised in place
    """
    s= np.shape(nds)
    if len(s)==1:
        nds=np.expand_dims(nds,1)
    nds[1:, :] = (nds[1:, :] / nds[0:-1]) - 1
    nds[0, :] = np.zeros(nds.shape[1])

def returnize1(nds):
    """
    @summary Computes stepwise (usually daily) returns relative to 1, where
    1 implies no change in value.
    @param nds: the array to fill backward
    @return the array is revised in place
    """
    s= np.shape(nds)
    if len(s)==1:
        nds=np.expand_dims(nds,1)
    nds[1:, :] = (nds[1:, :]/nds[0:-1])
    nds[0, :] = np.ones(nds.shape[1])
    
def priceize1(nds):
    """
    @summary Computes stepwise (usually daily) returns relative to 1, where
    1 implies no change in value.
    @param nds: the array to fill backward
    @return the array is revised in place
    """
    
    nds[0, :] = 100 
    for i in range(1, nds.shape[0]):
        nds[i, :] = nds[i-1, :] * nds[i, :]
    
    
def logreturnize(nds):
    """
    @summary Computes stepwise (usually daily) logarithmic returns.
    @param nds: the array to fill backward
    @return the array is revised in place
    """<commit_msg>fix for return calculation<commit_after>'''
(c) 2011, 2012 Georgia Tech Research Corporation
This source code is released under the New BSD license.  Please see
http://wiki.quantsoftware.org/index.php?title=QSTK_License
for license details.

Created on Jan 1, 2011

@author:<NAME>
@contact: <EMAIL>
@summary: Contains tutorial for backtester and report.

'''


import math
import datetime as dt
import numpy as np
from qstkutil import qsdateutil
from math import sqrt
import pandas as pd
from copy import deepcopy


import random as rand

from qstkutil import DataAccess as da
from qstkutil import qsdateutil as du
import numpy as np

def daily(lfFunds):
    """
    @summary Computes daily returns centered around 0
    @param funds: A time series containing daily fund values
    @return an array of daily returns
    """
    if type(lfFunds) == type(pd.Series()):
        ldt_timestamps = du.getNYSEdays(lfFunds.index[0], lfFunds.index[-1], dt.timedelta(hours=16))
        lfFunds = lfFunds.reindex(index=ldt_timestamps, method='ffill')
    nds = np.asarray(deepcopy(lfFunds))
    s= np.shape(nds)
    if len(s)==1:
        nds=np.expand_dims(nds,1)
    returnize0(nds)
    return(nds)

def daily1(lfFunds):
    """
    @summary Computes daily returns centered around 1
    @param funds: A time series containing daily fund values
    @return an array of daily returns
    """
    nds = np.asarray(deepcopy(lfFunds))
    s= np.shape(nds)
    if len(s)==1:
        nds=np.expand_dims(nds,1)
    returnize1(nds)
    return(nds)

def monthly(funds):
    """
    @summary Computes monthly returns centered around 0
    @param funds: A time series containing daily fund values
    @return an array of monthly returns
    """
    funds2 = []
    last_last_month = -1
    years = qsdateutil.getYears(funds)
    for year in years:
        months = qsdateutil.getMonths(funds, year)
        for month in months:
            last_this_month = qsdateutil.getLastDay(funds, year, month)
            if last_last_month == -1 :
                last_last_month=qsdateutil.getFirstDay(funds, year, month)
            if type(funds).__name__=='TimeSeries':
                funds2.append(funds[last_this_month]/funds[last_last_month]-1)
            else:
                funds2.append(funds.xs(last_this_month)/funds.xs(last_last_month)-1)
            last_last_month = last_this_month
    return(funds2)

def average_monthly(funds):
    """
    @summary Computes average monthly returns centered around 0
    @param funds: A time series containing daily fund values
    @return an array of average monthly returns
    """
    rets = daily(funds)
    ret_i = 0
    years = qsdateutil.getYears(funds)
    averages = []
    for year in years:
        months = qsdateutil.getMonths(funds, year)
        for month in months:
            avg = 0
            count = 0
            days = qsdateutil.getDays(funds, year, month)
            for day in days:
                avg += rets[ret_i]
                ret_i += 1
                count += 1
            averages.append(float(avg) / count)
    return(averages)    

def fillforward(nds):
    """
    @summary Removes NaNs from a 2D array by scanning forward in the 
    1st dimension.  If a cell is NaN, the value above it is carried forward.
    @param nds: the array to fill forward
    @return the array is revised in place
    """
    for col in range(nds.shape[1]):
        for row in range(1, nds.shape[0]):
            if math.isnan(nds[row, col]):
                nds[row, col] = nds[row-1, col]

def fillbackward(nds):
    """
    @summary Removes NaNs from a 2D array by scanning backward in the 
    1st dimension.  If a cell is NaN, the value above it is carried backward.
    @param nds: the array to fill backward
    @return the array is revised in place
    """
    for col in range(nds.shape[1]):
        for row in range(nds.shape[0] - 2, -1, -1):
            if math.isnan(nds[row, col]):
                nds[row, col] = nds[row+1, col]

def returnize0(nds):
    """
    @summary Computes stepwise (usually daily) returns relative to 0, where
    0 implies no change in value.
    @return the array is revised in place
    """
    s= np.shape(nds)
    if len(s)==1:
        nds=np.expand_dims(nds,1)
    nds[1:, :] = (nds[1:, :] - nds[0:-1]) / abs(nds[0:-1])
    nds[0, :] = np.zeros(nds.shape[1])

def returnize1(nds):
    """
    @summary Computes stepwise (usually daily) returns relative to 1, where
    1 implies no change in value.
    @param nds: the array to fill backward
    @return the array is revised in place
    """
    s= np.shape(nds)
    if len(s)==1:
        nds=np.expand_dims(nds,1)
    nds[1:, :] = (nds[1:, :]/nds[0:-1])
    nds[0, :] = np.ones(nds.shape[1])

def priceize1(nds):
    """
    @summary Computes stepwise (usually daily) returns relative to 1, where
    1 implies no change in value.
    @param nds: the array to fill backward
    @return the array is revised in place
    """
    
    nds[0, :] = 100 
    for i in range(1, nds.shape[0]):
        nds[i, :] = nds[i-1, :] * nds[i, :]
    
    
def logreturnize(nds):
    """
    @summary Computes stepwise (usually daily) logarithmic returns.
    @param nds: the array to fill backward
    @return the array is revised in place
    """
{'fraction_non_alphanumeric': 0.10490307867730901, 'fraction_numerical': 0.016818700114025087, 'mean_word_length': 2.5982905982905984, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1732249', 'n_tokens_mistral': 3664, 'n_tokens_neox': 3490, 'n_words': 1093}