def _advance(cls, date, n, units): if units == TimeUnits.Days or units == TimeUnits.BDays: return cls.fromExcelSerialNumber(date.__serialNumber__ + n) elif units == TimeUnits.Weeks: return cls.fromExcelSerialNumber(date.__serialNumber__ + 7 * n) elif units == TimeUnits.Months: d = date.dayOfMonth() m = date.month() + n y = date.year() addedYear = int(math.floor(m / 12)) monthLeft = m % 12 if monthLeft == 0: monthLeft = 12 addedYear -= 1 y += addedYear pyFinAssert( 1900 < y < 2200, ValueError, 'year {0:d} is out of bound. It must be in [1901, 2199]'. format(y)) return cls(y, monthLeft, d) elif units == TimeUnits.Years: d = date.dayOfMonth() m = date.month() y = date.year() + n pyFinAssert( 1900 < y < 2200, ValueError, 'year {0:d} is out of bound. It must be in [1901, 2199]'. format(y)) return cls(y, m, d)
def get_sec_price_on_date(cls, start_date, end_date, sec_ids, freq=FreqType.EOD, field=['close'], return_type=DfReturnType.DateIndexAndSecIDCol): """ :param start_date: str, start date of the query period :param end_date: str, end date of the query period :param sec_ids: list of str, sec IDs :param freq: FreqType :param field: str, filed of data to be queried :param return_type: dfReturnType :return: pd.DataFrame, index = date, col = sec ID """ if not w.isconnected(): w.start() pyFinAssert( freq == FreqType.EOD, ValueError, "for the moment the function only accepts freq type = EOD") start_date = str(start_date) if not isinstance( start_date, basestring) else start_date end_date = str(end_date) if not isinstance(end_date, basestring) else end_date raw_data = w.wsd(sec_ids, field, start_date, end_date, 'PriceAdj=F', 'Fill=Previous') ret = format_raw_data(raw_data, sec_ids, freq, field, return_type) return ret
def _advance(cls, date, n, units): if units == TimeUnits.Days or units == TimeUnits.BDays: return cls.fromExcelSerialNumber(date.__serialNumber__ + n) elif units == TimeUnits.Weeks: return cls.fromExcelSerialNumber(date.__serialNumber__ + 7 * n) elif units == TimeUnits.Months: d = date.dayOfMonth() m = date.month() + n y = date.year() addedYear = int(math.floor(m / 12)) monthLeft = m % 12 if monthLeft == 0: monthLeft = 12 addedYear -= 1 y += addedYear pyFinAssert(1900 < y < 2200, ValueError, 'year {0:d} is out of bound. It must be in [1901, 2199]'.format(y)) return cls(y, monthLeft, d) elif units == TimeUnits.Years: d = date.dayOfMonth() m = date.month() y = date.year() + n pyFinAssert(1900 < y < 2200, ValueError, 'year {0:d} is out of bound. It must be in [1901, 2199]'.format(y)) return cls(y, m, d)
def bachelierFormulaImpliedVol(optionType, strike, forward, tte, bachelierPrice, discount=1.0): strike = float(strike) forward = float(forward) tte = float(tte) bachelierPrice = float(bachelierPrice) discount = float(discount) pyFinAssert(tte > 0, ValueError, "tte ({0:f}) must be positive".format(tte)) SQRT_QL_EPSILON = math.sqrt(MathConstants.QL_EPSILON) forwardPremium = bachelierPrice / discount if optionType == OptionType.Call: straddlePremium = 2.0 * forwardPremium - (forward - strike) else: straddlePremium = 2.0 * forwardPremium + (forward - strike) nu = (forward - strike) / straddlePremium nu = max(-1.0 + MathConstants.QL_EPSILON, min(nu, 1.0 - MathConstants.QL_EPSILON)) eta = 1.0 if (abs(nu) < SQRT_QL_EPSILON) else (nu / math.atanh(nu)) heta = HCalculator.calculate(eta) impliedBpvol = math.sqrt(MathConstants.M_PI / (2 * tte)) * straddlePremium * heta return impliedBpvol
def get_sec_price_on_date(cls, start_date, end_date, sec_ids, freq=FreqType.EOD, field=['close'], return_type=DfReturnType.DateIndexAndSecIDCol): """ :param start_date: str, start date of the query period :param end_date: str, end date of the query period :param sec_ids: list of str, sec IDs :param freq: FreqType :param return_type: DfReturnType :param field: list of str, optional, filed of data to be queried :return: pd.DataFrame, index = date, col = sec ID """ pyFinAssert(freq == FreqType.EOD, ValueError, "for the moment the function only accepts freq type = EOD") start_date = str(start_date) if not isinstance(start_date, basestring) else start_date end_date = str(end_date) if not isinstance(end_date, basestring) else end_date ret = pd.DataFrame() for s in sec_ids: raw_data = ts.get_k_data(s, start=start_date, end=end_date, ktype=freq) if return_type == DfReturnType.DateIndexAndSecIDCol: ret = pd.concat([ret, raw_data[field]], axis=1) else: raise NotImplementedError if return_type == DfReturnType.DateIndexAndSecIDCol: ret.columns = sec_ids ret.index.name = 'tradeDate' ret.sort_index(ascending=True, inplace=True) return ret
def blackFormulaImpliedStdDev(optionType, strike, forward, blackPrice, discount=1.0, displacement=0.0): otherOptionPrice = blackPrice - optionType * (forward - strike) * discount if optionType == OptionType.Put and strike > forward: optionType = OptionType.Call blackPrice = otherOptionPrice if optionType == OptionType.Call and strike < forward: optionType = OptionType.Put blackPrice = otherOptionPrice strike += displacement forward += displacement func = lambda x: blackFormula(optionType, strike, forward, x, discount, displacement) - blackPrice stdAppr = _blackFormulaImpliedStdDevApproximation(optionType, strike, forward, blackPrice, discount, displacement) pyFinAssert(stdAppr >= 0.0, ValueError, "stdDev ({0:f})) must be non-negative".format(stdAppr)) return newton(func, stdAppr, tol=1e-10)
def __init__(self, window, dependency='x', isPopulation=False): super(MovingVariance, self).__init__(window, dependency) self._runningSum = 0.0 self._runningSumSquare = 0.0 self._isPop = isPopulation if not self._isPop: pyFinAssert(window >= 2, ValueError, "sampling variance can't be calculated with window size < 2")
def __init__(self, year=None, month=None, day=None, serialNumber=None): # do the input validation if serialNumber is not None and year is None and month is None and day is None: self.__serialNumber__ = serialNumber return elif serialNumber is not None and (year is not None or month is not None or day is not None): raise ValueError( "When serial number is offered, no year or month or day number should be entered" ) elif year is None or month is None or day is None: raise ValueError( "year: {0}, month: {1}, day: {2} can't be null value included". format(year, month, day)) isLeap = self.isLeap(year) pyFinAssert( 1 <= month <= 12, ValueError, 'month {0:d} is out of bound. It must be in [1, 12]'.format(month)) length = self._monthLength(month, isLeap) offset = self._monthOffset(month, isLeap) pyFinAssert( 1 <= day <= length, ValueError, 'day {0:d} is out of bound. It must be in [1, {1:d}]'.format( day, length)) self.__serialNumber__ = day + offset + _YearOffset[year - 1900]
def __init__(self, left, right): self._returnSize = right.valueSize self._symbolList = set(left.symbolList) self._window = left.window + right.window - 1 self._dependency = left.dependency if not isinstance(right.fields, str): pyFinAssert( left.valueSize == len(right.fields), ValueError, "left value size {0} is " "different from right dependency {1}".format( left.valueSize, right.fields)) else: pyFinAssert( left.valueSize == 1, ValueError, "left value size {0} is different from right dependency 1". format(left.valueSize)) self._right = copy.deepcopy(right._holderTemplate) self._left = copy.deepcopy(left._holderTemplate) self._holderTemplate = CompoundedValueHolder(self._left, self._right) self._innerHolders = { name: copy.deepcopy(self._holderTemplate) for name in self._symbolList }
def nthWeekday(nth, dayOfWeek, m, y): pyFinAssert(nth > 0, ValueError, "zeroth day of week in a given (month, year) is undefined") pyFinAssert(nth < 6, ValueError, "no more than 5 weekday in a given (month, year)") first = Date(y, m, 1).weekday() skip = nth - (1 if dayOfWeek >= first else 0) return Date(y, m, (1 + dayOfWeek + skip * 7) - first)
def __init__(self, dates, values): pyFinAssert( len(dates) == len(values), ValueError, "dates and values should have same length") self._values = OrderedDict() for date, value in zip(dates, values): self._values[date] = value
def __init__(self, valueHolder, N=1): super(Shift, self).__init__(N, valueHolder._dependency) pyFinAssert(N >= 1, ValueError, "shift value should always not be less than 1") self._valueHolder = deepcopy(valueHolder) self._window = valueHolder.window + N self._containerSize = N self._returnSize = valueHolder.valueSize self._dependency = deepcopy(valueHolder.dependency)
def SecurityShiftedValueHolder(secValueHolder, n): pyFinAssert(n >= 1, ValueError, "shift value should always not be less than 1") res = copy.deepcopy(secValueHolder) res._window = secValueHolder.window + n res._innerHolders = { name: Shift(secValueHolder.holders[name], n) for name in secValueHolder.holders } return res
def ptf_re_balance(return_dict, margin_prop=0.0, re_balance_freq=FreqType.EOM): """ :param return_dict: dict, returnName: [returnData, ReturnType] :param margin_prop: float, optional, proportion of the init ptf that is allocated to futures account :param re_balance_freq: str, optional, rebalance frequncy = daily/monthly/yearly :return: pd.Series, daily cumul returns of hedged ptf """ strat_return = return_dict['stratReturn'][0] strat_return_type = return_dict['stratReturn'][1] benchmark_return = return_dict['benchmarkReturn'][0] benchmark_return_type = return_dict['benchmarkReturn'][1] strat_return = empyrical.cum_returns(strat_return, starting_value=1.0) if strat_return_type == ReturnType.NonCumul \ else strat_return benchmark_return = empyrical.cum_returns(benchmark_return, starting_value=1.0) if benchmark_return_type == ReturnType.NonCumul \ else benchmark_return pyFinAssert(0 <= margin_prop <= 1.0, ValueError, " margin prop must be between 0 and 1") hedged_ptf_return = pd.Series() # merge strat and index returns together return_data = pd.concat([strat_return, benchmark_return], axis=1, join_axes=[strat_return.index]) return_data.columns = ['strategy', 'benchmark'] return_data.index = pd.to_datetime(return_data.index) pyFinAssert(return_data.isnull().values.any() == False, ValueError, " returnData has NaN values") regroup_total_return = regroup_by_re_balance_freq(return_data, re_balance_freq) # first date is a balance date re_balance_base_nav = 1.0 norm_base_return = return_data.iloc[0] for name, group in regroup_total_return: # compute the hedged return norm_strat_return = group['strategy'] / norm_base_return['strategy'] norm_benchmark_return = group['benchmark'] / norm_base_return[ 'benchmark'] hedged_return = (1 + (norm_strat_return - norm_benchmark_return) * (1 - margin_prop)) * re_balance_base_nav # update the re_balance base NPV re_balance_base_nav = hedged_return.iloc[-1] # update norm base return norm_base_return = group.iloc[-1] # merge into ptfValue hedged_ptf_return = pd.concat([hedged_ptf_return, hedged_return], axis=0) hedged_ptf_return.name = 'hedgedPtfReturn' hedged_ptf_return.index.name = return_data.index.name return hedged_ptf_return
def __init__(self, left, right): pyFinAssert(left.valueSize == right.valueSize, ValueError, "left value size {0} should be equal " "to right value size" .format(left.valueSize, right.valueSize)) self._returnSize = left.valueSize self._left = deepcopy(left) self._right = deepcopy(right) self._dependency = list(set(left.dependency).union(set(right.dependency))) self._window = max(self._left.window, self._right.window) self._containerSize = max(self._left._containerSize, self._right._containerSize)
def bizDatesList(self, fromDate, toDate): pyFinAssert(fromDate <= toDate, ValueError, "from date ({0} must be earlier than to date {1}" .format(fromDate, toDate)) result = [] d = fromDate while d <= toDate: if self.isBizDay(d): result.append(d) d += 1 return result
def nthWeekday(nth, dayOfWeek, m, y): pyFinAssert( nth > 0, ValueError, "zeroth day of week in a given (month, year) is undefined") pyFinAssert(nth < 6, ValueError, "no more than 5 weekday in a given (month, year)") first = Date(y, m, 1).weekday() skip = nth - (1 if dayOfWeek >= first else 0) return Date(y, m, (1 + dayOfWeek + skip * 7) - first)
def __init__(self, window, dependency): super(StatefulValueHolder, self).__init__(dependency) if not isinstance(window, int): raise ValueError("window parameter should be a positive int however {0} received" .format(window)) pyFinAssert(window > 0, ValueError, "window length should be greater than 0") self._returnSize = 1 self._window = window self._containerSize = window self._con = deque()
def holDatesList(self, fromDate, toDate, includeWeekEnds=True): pyFinAssert(fromDate <= toDate, ValueError, "from date ({0} must be earlier than to date {1}" .format(fromDate, toDate)) result = [] d = fromDate while d <= toDate: if self.isHoliday(d) and (includeWeekEnds or not self.isWeekEnd(d.weekday())): result.append(d) d += 1 return result
def __init__(self, window, dependency): super(StatefulValueHolder, self).__init__(dependency) if not isinstance(window, int): raise ValueError("window parameter should be a positive int however {0} received" .format(window)) pyFinAssert(window > 0, ValueError, "window length should be greater than 0") self._returnSize = 1 self._window = window self._containerSize = window self._con = deque() self._isFull = 0
def bizDatesList(self, fromDate, toDate): pyFinAssert( fromDate <= toDate, ValueError, "from date ({0} must be earlier than to date {1}".format( fromDate, toDate)) result = [] d = fromDate while d <= toDate: if self.isBizDay(d): result.append(d) d += 1 return result
def blackFormulaImpliedVol(optionType, strike, forward, tte, blackPrice, riskFree=0.0, displacement=0.0): pyFinAssert(tte > 0.0, ValueError, "time to maturity ({0:f})) must be positive".format(tte)) discount = math.exp(-riskFree * tte) stdDev = blackFormulaImpliedStdDev(optionType, strike, forward, blackPrice, discount, displacement) return stdDev / math.sqrt(tte)
def holDatesList(self, fromDate, toDate, includeWeekEnds=True): pyFinAssert( fromDate <= toDate, ValueError, "from date ({0} must be earlier than to date {1}".format( fromDate, toDate)) result = [] d = fromDate while d <= toDate: if self.isHoliday(d) and (includeWeekEnds or not self.isWeekEnd(d.weekday())): result.append(d) d += 1 return result
def __getitem__(self, item): if isinstance(item, tuple): symbolList = set(i.lower() for i in item) pyFinAssert(len(symbolList) == len(item), ValueError, "security name can't be duplicated") res = SecuritiesValues( {s: self._innerHolders[s].value for s in symbolList} ) return res elif isinstance(item, str) and item.lower() in self._innerHolders: item = item.lower() return self._innerHolders[item].value else: raise TypeError("{0} is not a valid index".format(item))
def top(df, column=None, n=5): """ :param df: pd.DataFrame/Series :param column: str, col name to be sorted :param n: int, optional, top n element to be returned :return: pd.Series, larget n element in col """ if isinstance(df, pd.Series): ret = df.sort_values(ascending=False)[:n] else: pyFinAssert(column is not None, "Specify the col name or use pandas Series type of data") ret = df.sort_values(by=column, ascending=False)[:n] return ret
def __getitem__(self, item): if isinstance(item, tuple): symbolList = set(i.lower() for i in item) pyFinAssert( len(symbolList) == len(item), ValueError, "security name can't be duplicated") res = SecuritiesValues( {s: self._innerHolders[s].value for s in symbolList}) return res elif isinstance(item, str) and item.lower() in self._innerHolders: item = item.lower() return self._innerHolders[item].value else: raise TypeError("{0} is not a valid index".format(item))
def _binary_operator(self, right, op): if isinstance(right, SecuritiesValues): pyFinAssert( self._values.keys() == right._values.keys(), ValueError, "left security names {0} " "is not equal to right {1}".format(self._values.keys(), right._values.keys())) return SecuritiesValues({ name: op(self._values[name], right._values[name]) for name in self._values }) else: return SecuritiesValues( {name: op(self._values[name], right) for name in self._values})
def eig_val_pct(eig_values, pct): """ :param eig_values: np.array/list, 所有特征值组成的向量 :param pct: 阈值 :return: 给定百分比阈值,返回需要降低到多少维度 """ pyFinAssert(0.0 <= pct <= 1.0, ValueError, "pct ({0:f}) must be between 0.0 and 1.0".format(pct)) sort_eig_values = np.sort(eig_values) sort_eig_values = sort_eig_values[-1::-1] # 特征值从大到小排列 eig_values_sum = sum(sort_eig_values) cum_sum = sort_eig_values.cumsum() marginal_eig_val = next(x for x in cum_sum if x / eig_values_sum >= pct) index = np.where(cum_sum == marginal_eig_val)[0][0] return index + 1
def __init__(self, left, right): self._returnSize = right.valueSize self._left = deepcopy(left) self._right = deepcopy(right) self._window = self._left.window + self._right.window - 1 self._containerSize = self._right._containerSize self._dependency = deepcopy(left.dependency) if hasattr(right.dependency, '__iter__'): pyFinAssert(left.valueSize == len(right.dependency), ValueError, "left value size {0} " "should be equal to right dependency size {1}" .format(left.valueSize, len(right.dependency))) else: pyFinAssert(left.valueSize == 1, ValueError, "left value size {0} should be equal to right dependency size 1" .format(left.valueSize))
def __add__(self, p2): res = Period(self.length, self.units) if self.length == 0: return Period(p2.length, p2.units) elif self.units == p2.units: res._length += p2.length return res else: if self.units == TimeUnits.Years: if p2.units == TimeUnits.Months: res._units = TimeUnits.Months res._length = res.length * 12 + p2.length elif p2.units == TimeUnits.Weeks or p2.units == TimeUnits.Days or p2.units == TimeUnits.BDays: pyFinAssert(p2.length == 0, ValueError, "impossible addition between {0} and {1}".format(self, p2)) else: raise ValueError("unknown time unit ({0:d})".format(p2.units)) return res elif self.units == TimeUnits.Months: if p2.units == TimeUnits.Years: res._length += 12 * p2.length elif p2.units == TimeUnits.Weeks or p2.units == TimeUnits.Days or p2.units == TimeUnits.BDays: pyFinAssert(p2.length == 0, ValueError, "impossible addition between {0} and {1}".format(self, p2)) else: raise ValueError("unknown time unit ({0:d})".format(p2.units)) return res elif self.units == TimeUnits.Weeks: if p2.units == TimeUnits.Days: res._units = TimeUnits.Days res._length = res.length * 7 + p2.length elif p2.units == TimeUnits.Years or p2.units == TimeUnits.Months or p2.units == TimeUnits.BDays: pyFinAssert(p2.length == 0, ValueError, "impossible addition between {0} and {1}".format(self, p2)) else: raise ValueError("unknown time unit ({0:d})".format(p2.units)) return res elif self.units == TimeUnits.Days: if p2.units == TimeUnits.Weeks: res._length += 7 * p2.length elif p2.units == TimeUnits.Years or p2.units == TimeUnits.Months or p2.units == TimeUnits.BDays: pyFinAssert(p2.length == 0, ValueError, "impossible addition between {0} and {1}".format(self, p2)) else: raise ValueError("unknown time unit ({0:d})".format(p2.units)) return res elif self.units == TimeUnits.BDays: if p2.units == TimeUnits.Years or p2.units == TimeUnits.Months or p2.units == TimeUnits.Weeks or p2.units == TimeUnits.Days: pyFinAssert(p2.length == 0, ValueError, "impossible addition between {0} and {1}".format(self, p2)) else: raise ValueError("unknown time unit ({0:d})".format(p2.units))
def __init__(self, value, n=1): if isinstance(value, Accumulator): pyFinAssert(value.valueSize == 1, ValueError, "Identity can't applied " "to value holder with value size {0} bigger than 1" .format(value.valueSize)) self._dependency = value._dependency self._isValueHolder = True self._window = value.window self._containerSize = value._containerSize else: self._dependency = [] self._isValueHolder = False self._window = 1 self._containerSize = 1 self._value = value self._returnSize = n
def _binary_operator(self, right, op): if isinstance(right, SecuritiesValues): pyFinAssert(self._values.keys() == right._values.keys(), ValueError, "left security names {0} " "is not equal to right {1}" .format(self._values.keys(), right._values.keys())) return SecuritiesValues( { name: op(self._values[name], right._values[name]) for name in self._values } ) else: return SecuritiesValues( { name: op(self._values[name], right) for name in self._values } )
def __getitem__(self, item): try: return self.holders[item].result() except (TypeError, KeyError) as _: if isinstance(item, tuple): symbolList = set(i.lower() for i in item) pyFinAssert(len(symbolList) == len(item), ValueError, "security name can't be duplicated") res = SecuritiesValues( {s: self.holders[s].result() for s in symbolList} ) return res elif isinstance(item, SecurityValueHolder): return FilteredSecurityValueHolder(self, item) else: raise TypeError("{0} is not a valid index".format(item))
def blackFormula2(optionType, strike, forward, tte, vol, riskFree=0.0, displacement=0.0): pyFinAssert(tte >= 0.0, ValueError, "time to maturity ({0:f})) must be non negative".format(tte)) if tte == 0.0: return max((forward - strike) * optionType, 0.0) discount = math.exp(-riskFree * tte) stdDev = math.sqrt(tte) * vol return blackFormula(optionType, strike, forward, stdDev, discount, displacement)
def push(self, data): values = super(MovingCorrelationMatrix, self).push(data) if values is None: return if self._isFirst: self._runningSum = np.zeros((1, len(values))) self._runningSumCrossSquare = np.zeros((len(values), len(values))) self._isFirst = False reshapeValues = np.array(values).reshape((1, len(values))) popout = self._dumpOneValue(reshapeValues) if not np.any(np.isnan(popout)): pyFinAssert(len(values) == self._runningSum.size, ValueError, "size incompatiable") self._runningSum += reshapeValues - popout self._runningSumCrossSquare += reshapeValues * reshapeValues.T - popout * popout.T else: pyFinAssert(len(values) == self._runningSum.size, ValueError, "size incompatiable") self._runningSum += reshapeValues self._runningSumCrossSquare += reshapeValues * reshapeValues.T
def __init__(self, left, right): self._returnSize = right.valueSize self._symbolList = left.symbolList self._window = left.window + right.window - 1 self._dependency = left.dependency if not isinstance(right.fields, str): pyFinAssert(left.valueSize == len(right.fields), ValueError, "left value size {0} is " "different from right dependency {1}" .format(left.valueSize, right.fields)) else: pyFinAssert(left.valueSize == 1, ValueError, "left value size {0} is different from right dependency 1" .format(left.valueSize)) self._right = copy.deepcopy(right.holders[list(right.holders)[0]]) self._left = copy.deepcopy(left.holders[list(left.holders)[0]]) self._innerHolders = { name: CompoundedValueHolder(self._left, self._right) for name in self._symbolList }
def __getitem__(self, item): try: if self._filter[item]: return self.holders[item].result() else: return np.nan except KeyError: if isinstance(item, tuple): symbolList = set(i.lower() for i in item).intersection(set(filter_flags.index)) # to be corrected pyFinAssert(len(symbolList) == len(item), ValueError, "security name can't be duplicated") res = SecuritiesValues( {s: self.holders[s].result() for s in symbolList} ) return res elif isinstance(item, SecurityValueHolder): return FilteredSecurityValueHolder(self, item) else: raise TypeError("{0} is not a valid index".format(item))
def format_raw_data(raw_data, sec_ids, freq, fields, return_type): ret = pd.DataFrame() if len(raw_data.Data) > 0: if return_type == DfReturnType.DateIndexAndSecIDCol: pyFinAssert( len(fields) == 1, ValueError, "length of query fields must be 1 under DateIndexAndSecIDCol return type" ) output = {'tradeDate': raw_data.Times} for secID in sec_ids: output[secID] = raw_data.Data[sec_ids.index(secID)] ret = pd.DataFrame(output) ret['tradeDate'] = ret['tradeDate'].apply( lambda x: x.strftime('%Y-%m-%d')) ret['tradeDate'] = pd.to_datetime(ret['tradeDate']) ret = ret.set_index('tradeDate') else: raise NotImplementedError return ret
def __init__(self, year=None, month=None, day=None, serialNumber=None): # do the input validation if serialNumber is not None and year is None and month is None and day is None: self.__serialNumber__ = serialNumber return elif serialNumber is not None and (year is not None or month is not None or day is not None): raise ValueError("When serial number is offered, no year or month or day number should be entered") elif year is None or month is None or day is None: raise ValueError("year: {0}, month: {1}, day: {2} can't be null value included".format(year, month, day)) isLeap = self.isLeap(year) pyFinAssert(1 <= month <= 12, ValueError, 'month {0:d} is out of bound. It must be in [1, 12]'.format(month)) length = self._monthLength(month, isLeap) offset = self._monthOffset(month, isLeap) pyFinAssert(1 <= day <= length, ValueError, 'day {0:d} is out of bound. It must be in [1, {1:d}]' .format(day, length)) self.__serialNumber__ = day + offset + _YearOffset[year - 1900]
def load_factor_data(self, start_date, end_date, sec_ids, field=['close'], freq=FreqType.EOD, return_type=DfReturnType.DateIndexAndSecIDCol, table_name='sec_close'): """ :param start_date: str, start date of the query period :param end_date: str, end date of the query period :param sec_ids: list of str, sec IDs :param freq: enum, optional, FreqType :param return_type: enum, optional, DfReturnType :param field: str, optional, filed of data to be queried :param table_name: str, optional, table name in sql database to be queried :return: pd.DataFrame, index = date, col = sec ID """ pyFinAssert( freq == FreqType.EOD, ValueError, "for the moment the function only accepts freq type = EOD") str_field = ','.join([element for element in field]) sql = 'select tradeDate, secID, {field} from {table} where tradeDate >= \'{start_date}\' and ' \ 'tradeDate <= \'{end_date}\' '.format(field=str_field, table=table_name, start_date=start_date, end_date=end_date) if not isinstance(sec_ids, basestring): sec_ids = [str(sec_id) for sec_id in sec_ids] if len(sec_ids) > 1: sql += 'and secID in {tp_sec_ids}'.format( tp_sec_ids=tuple(sec_ids)) else: sql += 'and secID in (\'{tp_sec_ids}\')'.format( tp_sec_ids=sec_ids[0]) raw_data = pd.read_sql(sql, self._engine) ret = format_raw_data(raw_data, freq, field, return_type=return_type) return ret
def bachelierFormula(optionType, strike, forward, stdDev, discount=1.0): strike = float(strike) forward = float(forward) stdDev = float(stdDev) discount = float(discount) pyFinAssert(stdDev >= 0, ValueError, "stdDev ({0:f}) must be non-negative".format(stdDev)) pyFinAssert(discount > 0, ValueError, "discount ({0:f}) must be positive".format(discount)) d = (forward - strike) * optionType if stdDev == 0: return discount * max(d, 0.0) h = d / stdDev result = discount * (stdDev * _dist.derivative(h) + d * _dist(h)) pyFinAssert(result >= 0, ValueError, "negative value ({0:f}) for " "stdDev: {1:f}" "option: {2}" "strike: {3:f}" "forward: {4:f}".format(result, stdDev, optionType, strike, forward)) return result
def __div__(self, n): pyFinAssert(n != 0, ValueError, "cannot be divided by zero") res = Period(self.length, self.units) if self.length % n == 0: res._length /= n else: units = res.units length = res.length if units == TimeUnits.Years: length *= 12 units = TimeUnits.Months elif units == TimeUnits.Weeks: length *= 7 units = TimeUnits.Days pyFinAssert(length % n == 0, ValueError, "{0} cannot be divided by {1:d}".format(res, n)) res._length = length / n res._units = units return res
def _checkParameters(strike, forward, displacement): strike = float(strike) forward = float(forward) displacement = float(displacement) pyFinAssert(displacement >= 0, ValueError, "displacement ({0:f}) must be non-negative".format(displacement)) pyFinAssert(strike + displacement >= 0, ValueError, "strike + displacement ({0:f}) must be non-negative" .format(strike + displacement)) pyFinAssert(forward + displacement >= 0, ValueError, "forward + displacement ({0:f}) must be non-negative" .format(forward + displacement)) return strike, forward, displacement
def __init__(self, dependency): if isinstance(dependency, Accumulator): self._isValueHolderContained = True else: self._isValueHolderContained = False if hasattr(dependency, '__iter__') and len(dependency) >= 2: for name in dependency: pyFinAssert(isinstance(name, str), ValueError, '{0} in pNames should be a plain string. But it is {1}' .format(name,type(name))) self._dependency = dependency elif hasattr(dependency, '__iter__') and len(dependency) == 1: for name in dependency: pyFinAssert(isinstance(name, str), ValueError, '{0} in pNames should be a plain string. But it is {1}' .format(name,type(name))) self._dependency = dependency[0] elif hasattr(dependency, '__iter__'): raise ValueError("parameters' name list should not be empty") else: pyFinAssert(isinstance(dependency, str) or isinstance(dependency, Accumulator), ValueError, '{0} in pNames should be a plain string or an value holder. But it is {1}' .format(dependency, type(dependency))) self._dependency = deepcopy(dependency)
def parseISO(cls, dateStr): pyFinAssert(len(dateStr) == 10 and dateStr[4] == '-' and dateStr[7] == '-', ValueError, "invalid format {0}".format(dateStr)) return cls(int(dateStr[0:4]), int(dateStr[5:7]), int(dateStr[8:10]))
def isLeap(year): pyFinAssert(1900 < year < 2200, ValueError, 'year {0:d} is out of bound. It must be in [1901, 2199]'.format(year)) return _YearIsLeap[year - 1900]
def defaultSymbolList(self, value): pyFinAssert(len(value) != 0, ValueError, "default symbol list can't be set to empty") self._defaultSymbolList = [v.lower() for v in value]