forked from hummingbot/hummingbot
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request hummingbot#2956 from CoinAlpha/feat/avellaneda_sto…
…ikov [v0.38] feat / implement Avellaneda-Stoickov in PMM strategy
- Loading branch information
Showing
12 changed files
with
1,615 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
hummingbot/strategy/__utils__/trailing_indicators/average_volatility.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
from .base_trailing_indicator import BaseTrailingIndicator | ||
import numpy as np | ||
|
||
|
||
class AverageVolatilityIndicator(BaseTrailingIndicator): | ||
def __init__(self, sampling_length: int = 30, processing_length: int = 15): | ||
super().__init__(sampling_length, processing_length) | ||
|
||
def _indicator_calculation(self) -> float: | ||
return np.var(self._sampling_buffer.get_as_numpy_array()) | ||
|
||
def _processing_calculation(self) -> float: | ||
processing_array = self._processing_buffer.get_as_numpy_array() | ||
return np.sqrt(np.mean(processing_array)) |
49 changes: 49 additions & 0 deletions
49
hummingbot/strategy/__utils__/trailing_indicators/base_trailing_indicator.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
from abc import ABC, abstractmethod | ||
import numpy as np | ||
import logging | ||
from ..ring_buffer import RingBuffer | ||
|
||
pmm_logger = None | ||
|
||
|
||
class BaseTrailingIndicator(ABC): | ||
@classmethod | ||
def logger(cls): | ||
global pmm_logger | ||
if pmm_logger is None: | ||
pmm_logger = logging.getLogger(__name__) | ||
return pmm_logger | ||
|
||
def __init__(self, sampling_length: int = 30, processing_length: int = 15): | ||
self._sampling_length = sampling_length | ||
self._sampling_buffer = RingBuffer(sampling_length) | ||
self._processing_length = processing_length | ||
self._processing_buffer = RingBuffer(processing_length) | ||
|
||
def add_sample(self, value: float): | ||
self._sampling_buffer.add_value(value) | ||
indicator_value = self._indicator_calculation() | ||
self._processing_buffer.add_value(indicator_value) | ||
|
||
@abstractmethod | ||
def _indicator_calculation(self) -> float: | ||
raise NotImplementedError | ||
|
||
def _processing_calculation(self) -> float: | ||
""" | ||
Processing of the processing buffer to return final value. | ||
Default behavior is buffer average | ||
""" | ||
return np.mean(self._processing_buffer.get_as_numpy_array()) | ||
|
||
@property | ||
def current_value(self) -> float: | ||
return self._processing_calculation() | ||
|
||
@property | ||
def is_sampling_buffer_full(self) -> bool: | ||
return self._sampling_buffer.is_full | ||
|
||
@property | ||
def is_processing_buffer_full(self) -> bool: | ||
return self._processing_buffer.is_full |
17 changes: 17 additions & 0 deletions
17
hummingbot/strategy/__utils__/trailing_indicators/exponential_moving_average.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from base_trailing_indicator import BaseTrailingIndicator | ||
import pandas as pd | ||
|
||
|
||
class ExponentialMovingAverageIndicator(BaseTrailingIndicator): | ||
def __init__(self, sampling_length: int = 30, processing_length: int = 1): | ||
if processing_length != 1: | ||
raise Exception("Exponential moving average processing_length should be 1") | ||
super().__init__(sampling_length, processing_length) | ||
|
||
def _indicator_calculation(self) -> float: | ||
ema = pd.Series(self._sampling_buffer.get_as_numpy_array())\ | ||
.ewm(span=self._sampling_length, adjust=True).mean() | ||
return ema[-1] | ||
|
||
def _processing_calculation(self) -> float: | ||
return self._processing_buffer.get_last_value() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#!/usr/bin/env python | ||
|
||
from .avellaneda_market_making import AvellanedaMarketMakingStrategy | ||
__all__ = [ | ||
AvellanedaMarketMakingStrategy, | ||
] |
73 changes: 73 additions & 0 deletions
73
hummingbot/strategy/avellaneda_market_making/avellaneda_market_making.pxd
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# distutils: language=c++ | ||
|
||
from libc.stdint cimport int64_t | ||
from hummingbot.strategy.strategy_base cimport StrategyBase | ||
|
||
|
||
cdef class AvellanedaMarketMakingStrategy(StrategyBase): | ||
cdef: | ||
object _market_info | ||
object _minimum_spread | ||
object _order_amount | ||
double _order_refresh_time | ||
double _max_order_age | ||
object _order_refresh_tolerance_pct | ||
double _filled_order_delay | ||
object _inventory_target_base_pct | ||
bint _order_optimization_enabled | ||
bint _add_transaction_costs_to_orders | ||
bint _hb_app_notification | ||
bint _is_debug | ||
|
||
double _cancel_timestamp | ||
double _create_timestamp | ||
object _limit_order_type | ||
bint _all_markets_ready | ||
int _filled_buys_balance | ||
int _filled_sells_balance | ||
double _last_timestamp | ||
double _status_report_interval | ||
int64_t _logging_options | ||
object _last_own_trade_price | ||
int _volatility_sampling_period | ||
double _last_sampling_timestamp | ||
bint _parameters_based_on_spread | ||
int _ticks_to_be_ready | ||
object _min_spread | ||
object _max_spread | ||
object _vol_to_spread_multiplier | ||
object _inventory_risk_aversion | ||
object _kappa | ||
object _gamma | ||
object _eta | ||
object _closing_time | ||
object _time_left | ||
object _q_adjustment_factor | ||
object _reserved_price | ||
object _optimal_spread | ||
object _optimal_bid | ||
object _optimal_ask | ||
object _latest_parameter_calculation_vol | ||
str _debug_csv_path | ||
object _avg_vol | ||
|
||
cdef object c_get_mid_price(self) | ||
cdef object c_create_base_proposal(self) | ||
cdef tuple c_get_adjusted_available_balance(self, list orders) | ||
cdef c_apply_order_price_modifiers(self, object proposal) | ||
cdef c_apply_order_amount_eta_transformation(self, object proposal) | ||
cdef c_apply_budget_constraint(self, object proposal) | ||
cdef c_apply_order_optimization(self, object proposal) | ||
cdef c_apply_add_transaction_costs(self, object proposal) | ||
cdef bint c_is_within_tolerance(self, list current_prices, list proposal_prices) | ||
cdef c_cancel_active_orders(self, object proposal) | ||
cdef c_aged_order_refresh(self) | ||
cdef bint c_to_create_orders(self, object proposal) | ||
cdef c_execute_orders_proposal(self, object proposal) | ||
cdef set_timers(self) | ||
cdef double c_get_spread(self) | ||
cdef c_collect_market_variables(self, double timestamp) | ||
cdef bint c_is_algorithm_ready(self) | ||
cdef c_calculate_reserved_price_and_optimal_spread(self) | ||
cdef object c_calculate_target_inventory(self) | ||
cdef c_recalculate_parameters(self) |
Oops, something went wrong.