コード例 #1
0
ファイル: risk.py プロジェクト: winfieldtian/AlephNull
def sortino_ratio(algorithm_returns, algorithm_period_return, mar):
    """
    http://en.wikipedia.org/wiki/Sortino_ratio

    Args:
        algorithm_returns (np.array-like):
            Returns from algorithm lifetime.
        algorithm_period_return (float):
            Algorithm return percentage from latest period.
        mar (float): Minimum acceptable return.

    Returns:
        float. The Sortino ratio.
    """
    if len(algorithm_returns) == 0:
        return 0.0

    rets = algorithm_returns
    downside = (rets[rets < mar] - mar)**2
    dr = np.sqrt(downside.sum() / len(rets))

    if zp_math.tolerant_equals(dr, 0):
        return 0.0

    return (algorithm_period_return - mar) / dr
コード例 #2
0
ファイル: cumulative.py プロジェクト: CarterBain/AlephNull
def sharpe_ratio(algorithm_volatility, annualized_return, treasury_return):
    """
    http://en.wikipedia.org/wiki/Sharpe_ratio

    Args:
        algorithm_volatility (float): Algorithm volatility.
        algorithm_return (float): Algorithm return percentage.
        treasury_return (float): Treasury return percentage.

    Returns:
        float. The Sharpe ratio.
    """
    if zp_math.tolerant_equals(algorithm_volatility, 0):
        return np.nan

    return (
        (annualized_return - treasury_return)
        # The square of the annualization factor is in the volatility,
        # because the volatility is also annualized,
        # i.e. the sqrt(annual factor) is in the volatility's numerator.
        # So to have the the correct annualization factor for the
        # Sharpe value's numerator, which should be the sqrt(annual factor).
        # The square of the sqrt of the annual factor, i.e. the annual factor
        # itself, is needed in the numerator to factor out the division by
        # its square root.
        / algorithm_volatility)
コード例 #3
0
ファイル: cumulative.py プロジェクト: cosmicz/AlephNull
def information_ratio(algo_volatility, algorithm_return, benchmark_return):
    """
    http://en.wikipedia.org/wiki/Information_ratio

    Args:
        algorithm_returns (np.array-like):
            All returns during algorithm lifetime.
        benchmark_returns (np.array-like):
            All benchmark returns during algo lifetime.

    Returns:
        float. Information ratio.
    """
    if zp_math.tolerant_equals(algo_volatility, 0):
        return np.nan

    return (
        (algorithm_return - benchmark_return)
        # The square of the annualization factor is in the volatility,
        # because the volatility is also annualized,
        # i.e. the sqrt(annual factor) is in the volatility's numerator.
        # So to have the the correct annualization factor for the
        # Sharpe value's numerator, which should be the sqrt(annual factor).
        # The square of the sqrt of the annual factor, i.e. the annual factor
        # itself, is needed in the numerator to factor out the division by
        # its square root.
        / algo_volatility)
コード例 #4
0
ファイル: cumulative.py プロジェクト: cosmicz/AlephNull
def sharpe_ratio(algorithm_volatility, annualized_return, treasury_return):
    """
    http://en.wikipedia.org/wiki/Sharpe_ratio

    Args:
        algorithm_volatility (float): Algorithm volatility.
        algorithm_return (float): Algorithm return percentage.
        treasury_return (float): Treasury return percentage.

    Returns:
        float. The Sharpe ratio.
    """
    if zp_math.tolerant_equals(algorithm_volatility, 0):
        return np.nan

    return (
        (annualized_return - treasury_return)
        # The square of the annualization factor is in the volatility,
        # because the volatility is also annualized,
        # i.e. the sqrt(annual factor) is in the volatility's numerator.
        # So to have the the correct annualization factor for the
        # Sharpe value's numerator, which should be the sqrt(annual factor).
        # The square of the sqrt of the annual factor, i.e. the annual factor
        # itself, is needed in the numerator to factor out the division by
        # its square root.
        / algorithm_volatility)
コード例 #5
0
    def process_trade(self, trade_event):

        if trade_event.type != zp.DATASOURCE_TYPE.TRADE:
            return

        if zp_math.tolerant_equals(trade_event.volume, 0):
            # there are zero volume trade_events bc some stocks trade
            # less frequently than once per minute.
            return

        if 'contract' in trade_event.__dict__:
            sid = (trade_event.sid, trade_event.contract)
        else:
            sid = trade_event.sid

        if sid in self.open_orders:
            orders = self.open_orders[sid]
            orders = sorted(orders, key=lambda o: o.dt)
            # Only use orders for the current day or before
            current_orders = filter(lambda o: o.dt <= trade_event.dt, orders)
        else:
            return

        for order, txn in self.transact(trade_event, current_orders):
            if txn.type == zp.DATASOURCE_TYPE.COMMISSION:
                yield txn, order
                continue

            if 'contract' in order.__dict__:
                self.futures_handle_leverage(txn, order)
            else:
                self.handle_leverage(txn, order)

            transaction_cost = txn.amount * txn.price
            self.portfolio.cash -= transaction_cost
            self.portfolio.positions_value += transaction_cost
            self.portfolio.portfolio_value = self.portfolio.cash + self.portfolio.positions_value

            # if txn.amount == 0:
            #     raise alephnull.errors.TransactionWithNoAmount(txn=txn)

            if math.copysign(1, txn.amount) != order.direction:
                raise alephnull.errors.TransactionWithWrongDirection(
                    txn=txn, order=order)
            if abs(txn.amount) > abs(self.orders[txn.order_id].amount):
                raise alephnull.errors.TransactionVolumeExceedsOrder(
                    txn=txn, order=order)

            order.filled += txn.amount
            # mark the date of the order to match the transaction
            # that is filling it.
            order.dt = txn.dt

            yield txn, order

        # update the open orders for the trade_event's sid
        self.open_orders[sid] = \
            [order for order
             in self.open_orders[sid]
             if order.open]
コード例 #6
0
ファイル: cumulative.py プロジェクト: CarterBain/AlephNull
def information_ratio(algo_volatility, algorithm_return, benchmark_return):
    """
    http://en.wikipedia.org/wiki/Information_ratio

    Args:
        algorithm_returns (np.array-like):
            All returns during algorithm lifetime.
        benchmark_returns (np.array-like):
            All benchmark returns during algo lifetime.

    Returns:
        float. Information ratio.
    """
    if zp_math.tolerant_equals(algo_volatility, 0):
        return np.nan

    return (
        (algorithm_return - benchmark_return)
        # The square of the annualization factor is in the volatility,
        # because the volatility is also annualized,
        # i.e. the sqrt(annual factor) is in the volatility's numerator.
        # So to have the the correct annualization factor for the
        # Sharpe value's numerator, which should be the sqrt(annual factor).
        # The square of the sqrt of the annual factor, i.e. the annual factor
        # itself, is needed in the numerator to factor out the division by
        # its square root.
        / algo_volatility)
コード例 #7
0
ファイル: risk.py プロジェクト: CarterBain/AlephNull
def information_ratio(algorithm_returns, benchmark_returns):
    """
    http://en.wikipedia.org/wiki/Information_ratio

    Args:
        algorithm_returns (np.array-like):
            All returns during algorithm lifetime.
        benchmark_returns (np.array-like):
            All benchmark returns during algo lifetime.

    Returns:
        float. Information ratio.
    """
    relative_returns = algorithm_returns - benchmark_returns

    relative_deviation = relative_returns.std(ddof=1)

    if (
        zp_math.tolerant_equals(relative_deviation, 0)
        or
        np.isnan(relative_deviation)
    ):
        return 0.0

    return np.mean(relative_returns) / relative_deviation
コード例 #8
0
ファイル: risk.py プロジェクト: CarterBain/AlephNull
def sortino_ratio(algorithm_returns, algorithm_period_return, mar):
    """
    http://en.wikipedia.org/wiki/Sortino_ratio

    Args:
        algorithm_returns (np.array-like):
            Returns from algorithm lifetime.
        algorithm_period_return (float):
            Algorithm return percentage from latest period.
        mar (float): Minimum acceptable return.

    Returns:
        float. The Sortino ratio.
    """
    if len(algorithm_returns) == 0:
        return 0.0

    rets = algorithm_returns
    downside = (rets[rets < mar] - mar) ** 2
    dr = np.sqrt(downside.sum() / len(rets))

    if zp_math.tolerant_equals(dr, 0):
        return 0.0

    return (algorithm_period_return - mar) / dr
コード例 #9
0
def transact_stub(slippage, commission, event, open_orders):
    """
    This is intended to be wrapped in a partial, so that the
    slippage and commission models can be enclosed.
    """
    for order, transaction in slippage(event, open_orders):
        if (transaction
                and not zp_math.tolerant_equals(transaction.amount, 0)):
            direction = math.copysign(1, transaction.amount)
            per_share, total_commission = commission.calculate(transaction)
            transaction.price = transaction.price + (per_share * direction)
            transaction.commission = total_commission
        yield order, transaction
コード例 #10
0
ファイル: stddev.py プロジェクト: CarterBain/AlephNull
    def get_stddev(self):
        # Sample standard deviation is undefined for a single event or
        # no events.
        if len(self) <= 1:
            return None

        else:
            average = self.sum / len(self)
            s_squared = (self.sum_sqr - self.sum * average) \
                / (len(self) - 1)

            if zp_math.tolerant_equals(0, s_squared):
                return 0.0
            stddev = sqrt(s_squared)
        return stddev
コード例 #11
0
ファイル: stddev.py プロジェクト: winfieldtian/AlephNull
    def get_stddev(self):
        # Sample standard deviation is undefined for a single event or
        # no events.
        if len(self) <= 1:
            return None

        else:
            average = self.sum / len(self)
            s_squared = (self.sum_sqr - self.sum * average) \
                / (len(self) - 1)

            if zp_math.tolerant_equals(0, s_squared):
                return 0.0
            stddev = sqrt(s_squared)
        return stddev
コード例 #12
0
ファイル: risk.py プロジェクト: winfieldtian/AlephNull
def sharpe_ratio(algorithm_volatility, algorithm_return, treasury_return):
    """
    http://en.wikipedia.org/wiki/Sharpe_ratio

    Args:
        algorithm_volatility (float): Algorithm volatility.
        algorithm_return (float): Algorithm return percentage.
        treasury_return (float): Treasury return percentage.

    Returns:
        float. The Sharpe ratio.
    """
    if zp_math.tolerant_equals(algorithm_volatility, 0):
        return 0.0

    return (algorithm_return - treasury_return) / algorithm_volatility
コード例 #13
0
ファイル: slippage.py プロジェクト: CarterBain/AlephNull
def transact_stub(slippage, commission, event, open_orders):
    """
    This is intended to be wrapped in a partial, so that the
    slippage and commission models can be enclosed.
    """
    for order, transaction in slippage(event, open_orders):
        if (
            transaction
        and not
        zp_math.tolerant_equals(transaction.amount, 0)
        ):
            direction = math.copysign(1, transaction.amount)
            per_share, total_commission = commission.calculate(transaction)
            transaction.price = transaction.price + (per_share * direction)
            transaction.commission = total_commission
        yield order, transaction
コード例 #14
0
ファイル: risk.py プロジェクト: CarterBain/AlephNull
def sharpe_ratio(algorithm_volatility, algorithm_return, treasury_return):
    """
    http://en.wikipedia.org/wiki/Sharpe_ratio

    Args:
        algorithm_volatility (float): Algorithm volatility.
        algorithm_return (float): Algorithm return percentage.
        treasury_return (float): Treasury return percentage.

    Returns:
        float. The Sharpe ratio.
    """
    if zp_math.tolerant_equals(algorithm_volatility, 0):
        return 0.0

    return (algorithm_return - treasury_return) / algorithm_volatility
コード例 #15
0
ファイル: cumulative.py プロジェクト: cosmicz/AlephNull
def sortino_ratio(annualized_algorithm_return, treasury_return, downside_risk):
    """
    http://en.wikipedia.org/wiki/Sortino_ratio

    Args:
        algorithm_returns (np.array-like):
            Returns from algorithm lifetime.
        algorithm_period_return (float):
            Algorithm return percentage from latest period.
        mar (float): Minimum acceptable return.

    Returns:
        float. The Sortino ratio.
    """
    if np.isnan(downside_risk) or zp_math.tolerant_equals(downside_risk, 0):
        return 0.0

    return (annualized_algorithm_return - treasury_return) / downside_risk
コード例 #16
0
ファイル: cumulative.py プロジェクト: CarterBain/AlephNull
def sortino_ratio(annualized_algorithm_return, treasury_return, downside_risk):
    """
    http://en.wikipedia.org/wiki/Sortino_ratio

    Args:
        algorithm_returns (np.array-like):
            Returns from algorithm lifetime.
        algorithm_period_return (float):
            Algorithm return percentage from latest period.
        mar (float): Minimum acceptable return.

    Returns:
        float. The Sortino ratio.
    """
    if np.isnan(downside_risk) or zp_math.tolerant_equals(downside_risk, 0):
        return 0.0

    return (annualized_algorithm_return - treasury_return) / downside_risk
コード例 #17
0
    def simulate(self, event, current_orders):

        self._volume_for_bar = 0

        for order in current_orders:

            open_amount = order.amount - order.filled

            if zp_math.tolerant_equals(open_amount, 0):
                continue

            order.check_triggers(event)
            if not order.triggered:
                continue

            txn = self.process_order(event, order)
            if txn:
                self._volume_for_bar += abs(txn.amount)
                yield order, txn
コード例 #18
0
ファイル: slippage.py プロジェクト: CarterBain/AlephNull
    def simulate(self, event, current_orders):

        self._volume_for_bar = 0

        for order in current_orders:

            open_amount = order.amount - order.filled

            if zp_math.tolerant_equals(open_amount, 0):
                continue

            order.check_triggers(event)
            if not order.triggered:
                continue

            txn = self.process_order(event, order)
            if txn:
                self._volume_for_bar += abs(txn.amount)
                yield order, txn
コード例 #19
0
ファイル: risk.py プロジェクト: winfieldtian/AlephNull
def information_ratio(algorithm_returns, benchmark_returns):
    """
    http://en.wikipedia.org/wiki/Information_ratio

    Args:
        algorithm_returns (np.array-like):
            All returns during algorithm lifetime.
        benchmark_returns (np.array-like):
            All benchmark returns during algo lifetime.

    Returns:
        float. Information ratio.
    """
    relative_returns = algorithm_returns - benchmark_returns

    relative_deviation = relative_returns.std(ddof=1)

    if (zp_math.tolerant_equals(relative_deviation, 0)
            or np.isnan(relative_deviation)):
        return 0.0

    return np.mean(relative_returns) / relative_deviation
コード例 #20
0
ファイル: blotter.py プロジェクト: CarterBain/AlephNull
    def process_trade(self, trade_event):

        if trade_event.type != zp.DATASOURCE_TYPE.TRADE:
            return

        if zp_math.tolerant_equals(trade_event.volume, 0):
            # there are zero volume trade_events bc some stocks trade
            # less frequently than once per minute.
            return

        if 'contract' in trade_event.__dict__:
            sid = (trade_event.sid, trade_event.contract)
        else:
            sid = trade_event.sid

        if sid in self.open_orders:
            orders = self.open_orders[sid]
            orders = sorted(orders, key=lambda o: o.dt)
            # Only use orders for the current day or before
            current_orders = filter(
                lambda o: o.dt <= trade_event.dt,
                orders)
        else:
            return

        for order, txn in self.transact(trade_event, current_orders):
            if txn.type == zp.DATASOURCE_TYPE.COMMISSION:
                yield txn, order
                continue

            if 'contract' in order.__dict__:
                self.futures_handle_leverage(txn, order)
            else:
                self.handle_leverage(txn, order)

            transaction_cost = txn.amount * txn.price
            self.portfolio.cash -= transaction_cost
            self.portfolio.positions_value += transaction_cost
            self.portfolio.portfolio_value = self.portfolio.cash + self.portfolio.positions_value

            # if txn.amount == 0:
            #     raise alephnull.errors.TransactionWithNoAmount(txn=txn)

            if math.copysign(1, txn.amount) != order.direction:
                raise alephnull.errors.TransactionWithWrongDirection(
                    txn=txn, order=order)
            if abs(txn.amount) > abs(self.orders[txn.order_id].amount):
                raise alephnull.errors.TransactionVolumeExceedsOrder(
                    txn=txn, order=order)

            order.filled += txn.amount
            # mark the date of the order to match the transaction
            # that is filling it.
            order.dt = txn.dt

            yield txn, order

        # update the open orders for the trade_event's sid
        self.open_orders[sid] = \
            [order for order
             in self.open_orders[sid]
             if order.open]
コード例 #21
0
def round_for_minimum_price_variation(x, is_buy, diff=(0.0095 - .005)):
    # relies on rounding half away from zero, unlike numpy's bankers' rounding
    rounded = round(x - (diff if is_buy else -diff), 2)
    if zp_math.tolerant_equals(rounded, 0.0):
        return 0.0
    return rounded
コード例 #22
0
ファイル: blotter.py プロジェクト: CarterBain/AlephNull
def round_for_minimum_price_variation(x, is_buy, diff=(0.0095 - .005)):
    # relies on rounding half away from zero, unlike numpy's bankers' rounding
    rounded = round(x - (diff if is_buy else -diff), 2)
    if zp_math.tolerant_equals(rounded, 0.0):
        return 0.0
    return rounded