Exemple #1
0
    def _generate_price_history(self):
        try:
            price_fbm = FractionalBrownianMotion(t=self._times_to_generate, hurst=self._hurst)
            volume_gen = GaussianNoise(t=self._times_to_generate)
        except:
            self._generate_price_history()

        start_date = pd.to_datetime(self._start_date, format=self._start_date_format)

        price_volatility = price_fbm.sample(self._times_to_generate, zero=False)
        prices = price_volatility + self._base_price
        volume_volatility = volume_gen.sample(self._times_to_generate)
        volumes = volume_volatility * price_volatility + self._base_volume

        price_frame = pd.DataFrame([], columns=['date', 'price'], dtype=float)
        volume_frame = pd.DataFrame(
            [], columns=['date', 'volume'], dtype=float)

        price_frame['date'] = pd.date_range(
            start=start_date, periods=self._times_to_generate, freq="1min")
        price_frame['price'] = abs(prices)

        volume_frame['date'] = price_frame['date'].copy()
        volume_frame['volume'] = abs(volumes)

        price_frame.set_index('date')
        price_frame.index = pd.to_datetime(price_frame.index, unit='m', origin=start_date)

        volume_frame.set_index('date')
        volume_frame.index = pd.to_datetime(volume_frame.index, unit='m', origin=start_date)

        data_frame = price_frame['price'].resample(self._timeframe).ohlc()
        data_frame['volume'] = volume_frame['volume'].resample(self._timeframe).sum()

        self.data_frame = data_frame.astype(self._dtype)
Exemple #2
0
    def __init__(self, commission_percent: float = 0.3, base_precision: float = 2, asset_precision: float = 8, **kwargs):
        super().__init__(commission_percent, base_precision, asset_precision)

        self._initial_balance = kwargs.get('initial_balance', 1E5)
        self.max_allowed_slippage_percent = kwargs.get('max_allowed_slippage_percent', 3.0)
        self.min_order_amount = kwargs.get('min_order_amount', 1E-5)
        self.base_price = kwargs.get('base_price', 3000)
        self.base_volume = kwargs.get('base_volume', 1000)
        self.hurst = kwargs.get('hurst', 0.58)

        self.fbm = FractionalBrownianMotion(t=1, hurst=self.hurst)

        self.reset()
    def __init__(self, **kwargs):
        self.commission_percent = kwargs.get('commission_percent', 0.3)
        self.base_precision = kwargs.get('base_precision', 2)
        self.asset_precision = kwargs.get('asset_precision', 8)
        self._initial_balance = kwargs.get('initial_balance', 1E5)
        self.max_allowed_slippage_percent = kwargs.get(
            'max_allowed_slippage_percent', 3.0)
        self.min_order_amount = kwargs.get('min_order_amount', 1E-5)
        self.base_price = kwargs.get('base_price', 3000)
        self.base_volume = kwargs.get('base_volume', 1000)
        self.hurst = kwargs.get('hurst', 0.58)

        self.fbm = FractionalBrownianMotion(t=1, hurst=self.hurst)

        self.reset()
Exemple #4
0
def fbm(base_price: int = 1,
        base_volume: int = 1,
        start_date: str = '2010-01-01',
        start_date_format: str = '%Y-%m-%d',
        times_to_generate: int = 1000,
        hurst: float = 0.61,
        time_frame: str = '1h'):

    times_to_generate = scale_times_to_generate(times_to_generate, time_frame)

    price_fbm = FractionalBrownianMotion(t=times_to_generate, hurst=hurst)
    price_volatility = price_fbm.sample(times_to_generate, zero=False)
    prices = price_volatility + base_price

    volume_gen = GaussianNoise(times_to_generate)
    volume_volatility = volume_gen.sample(times_to_generate)
    volumes = volume_volatility * price_volatility + base_volume

    start_date = pd.to_datetime(start_date, format=start_date_format)
    price_frame = pd.DataFrame([], columns=['date', 'price'], dtype=float)
    volume_frame = pd.DataFrame([], columns=['date', 'volume'], dtype=float)

    price_frame['date'] = pd.date_range(start=start_date,
                                        periods=times_to_generate,
                                        freq="1min")
    price_frame['price'] = abs(prices)

    volume_frame['date'] = price_frame['date'].copy()
    volume_frame['volume'] = abs(volumes)

    price_frame.set_index('date')
    price_frame.index = pd.to_datetime(price_frame.index,
                                       unit='m',
                                       origin=start_date)

    volume_frame.set_index('date')
    volume_frame.index = pd.to_datetime(volume_frame.index,
                                        unit='m',
                                        origin=start_date)

    data_frame = price_frame['price'].resample(time_frame).ohlc()
    data_frame['volume'] = volume_frame['volume'].resample(time_frame).sum()

    return data_frame
def test_get_all_information():
    """ Checks to see if we've recieved all observations through the main pipeline"""
    # Create an objective with a name

    objective_one = Objective("sample_reward", {}, Ranking("sample_reward"))


    motion = FractionalBrownianMotion()
    motion_two = FractionalBrownianMotion()
    motion_sample = motion.sample(1000) + 1.2
    motion_sample_two = motion_two.sample(1000) + 1.1


    motion_sample = motion_sample * 1000
    motion_sample_two = motion_sample_two * 1000
    manifold = Manifold(objectives=[objective_one])
    
    for i in range(len(motion_sample)):
        value_dict = [dict(name="sample_reward", value=motion_sample[i], ambient=motion_sample_two[i])]
        reward = manifold.step(value_dict)
        print(reward)
Exemple #6
0
import pytest

##################
# Simulated data #
##################

sampling_period = 30
frequency = pd.Timedelta(sampling_period, unit='s')
start_time = '01/01/2018 00:00:00'
N = 7 * 1440 * 2  # *sampling_period
n_array = np.geomspace(5, 1000, num=40, endpoint=True, dtype=int)
q_array = [-5, -3, -1, 0, 1, 3, 5]

# Stochastic generators
bn = BrownianNoise(t=1)
fbm = FractionalBrownianMotion(hurst=0.9, t=1)
fgn = FractionalGaussianNoise(hurst=0.6, t=1)

np.random.seed(0)

# Brownian noise: h(q) = 1+H with H=0.5
bn_sample = generate_series(bn.sample(N - 1),
                            start=start_time,
                            sampling_period=sampling_period)

# Fractional Brownian motion: h(q) = 1+H with H = 0.9 (in this example)
fbm_sample = generate_series(fbm.sample(N - 1),
                             start=start_time,
                             sampling_period=sampling_period)

# Fractional Gaussian noise: h(q) = H with H = 0.6 (in this example)
def test_fractional_brownian_motion_str_repr(hurst, t):
    instance = FractionalBrownianMotion(hurst, t)
    assert isinstance(repr(instance), str)
    assert isinstance(str(instance), str)
def test_fractional_brownian_motion_sample(hurst, t, n, zero, threshold):
    instance = FractionalBrownianMotion(hurst, t)
    s = instance.sample(n, zero)
    assert len(s) == n + int(zero)
class FBMExchange(AssetExchange):
    def __init__(self, **kwargs):
        self.commission_percent = kwargs.get('commission_percent', 0.3)
        self.base_precision = kwargs.get('base_precision', 2)
        self.asset_precision = kwargs.get('asset_precision', 8)
        self._initial_balance = kwargs.get('initial_balance', 1E5)
        self.max_allowed_slippage_percent = kwargs.get(
            'max_allowed_slippage_percent', 3.0)
        self.min_order_amount = kwargs.get('min_order_amount', 1E-5)
        self.base_price = kwargs.get('base_price', 3000)
        self.base_volume = kwargs.get('base_volume', 1000)
        self.hurst = kwargs.get('hurst', 0.58)

        self.fbm = FractionalBrownianMotion(t=1, hurst=self.hurst)

        self.reset()

    def reset(self):
        self._balance = self._initial_balance

        self._portfolio = {}
        self._trades = pd.DataFrame(
            [], columns=['step', 'symbol', 'type', 'amount', 'price'])
        self._performance = pd.DataFrame([], columns=['balance', 'net_worth'])

        self.data_frame = pd.DataFrame(
            [], columns=['open', 'high', 'low', 'close', 'volume'])
        self.data_frame.reset_index(drop=True)

        self.current_step = 1

    def net_worth(self, output_symbol: str = 'USD') -> float:
        return super().net_worth(output_symbol=output_symbol)

    def profit_loss_percent(self, output_symbol: str = 'USD') -> float:
        return super().profit_loss_percent(output_symbol=output_symbol)

    def initial_balance(self, symbol: str = 'USD') -> float:
        return self._initial_balance

    def balance(self, symbol: str = 'USD') -> float:
        return self._balance

    def portfolio(self) -> Dict[str, float]:
        return self._portfolio

    def trades(self) -> pd.DataFrame:
        return self._trades

    def performance(self) -> pd.DataFrame:
        return self._performance

    def observation_space(self):
        return spaces.Box(low=0, high=1, shape=(1, 5), dtype=self.dtype)

    def current_price(self, symbol: str, output_symbol: str = 'USD'):
        if len(self.data_frame) is 0:
            self.next_observation()

        return float(self.data_frame['close'].values[-1])

    def _update_account(self, symbol: str, trade_type: TradeType,
                        fill_amount: float, fill_price: float):
        self._trades = self._trades.append(
            {
                'step': self.current_step,
                'symbol': symbol,
                'type': trade_type,
                'amount': fill_amount,
                'price': fill_price
            },
            ignore_index=True)

        if trade_type is TradeType.BUY:
            self._balance -= fill_amount * fill_price
            self._portfolio[symbol] = self._portfolio.get(symbol,
                                                          0) + fill_amount
        elif trade_type is TradeType.SELL:
            self._balance += fill_amount * fill_price
            self._portfolio[symbol] -= fill_amount

        self._performance.append(
            {
                'balance': self._balance,
                'net_worth': self.net_worth(),
            },
            ignore_index=True)

    def execute_trade(self, symbol: str, trade_type: TradeType, amount: float,
                      price: float):
        current_price = self.current_price(symbol=symbol)

        commission = self.commission_percent / 100
        slippage = np.random.uniform(0,
                                     self.max_allowed_slippage_percent) / 100

        fill_amount = 0

        if trade_type == TradeType.BUY and amount >= self.min_order_amount and self._balance >= amount * price:
            price_adjustment = price_adjustment = (1 + commission) * (1 +
                                                                      slippage)
            fill_price = round(current_price * price_adjustment,
                               self.base_precision)
            fill_amount = round((price * amount) / fill_price,
                                self.asset_precision)
        elif trade_type == TradeType.SELL and amount >= self.min_order_amount and self._portfolio.get(
                symbol, 0) >= amount:
            price_adjustment = (1 - commission) * (1 - slippage)
            fill_price = round(current_price * price_adjustment,
                               self.base_precision)
            fill_amount = round(amount, self.asset_precision)

        if fill_amount > 0:
            self._update_account(symbol=symbol,
                                 trade_type=trade_type,
                                 fill_amount=fill_amount,
                                 fill_price=fill_price)

    def has_next_observation(self):
        return True

    def next_observation(self):
        dates = np.linspace(0, 1, 2)
        prices = self.fbm.sample(1)
        volumes = self.fbm.sample(1)

        price_frame = pd.DataFrame([], columns=['date', 'price'], dtype=float)
        volume_frame = pd.DataFrame([],
                                    columns=['date', 'volume'],
                                    dtype=float)

        price_frame['date'] = pd.to_datetime(dates, unit="m")
        price_frame['price'] = prices

        volume_frame['date'] = pd.to_datetime(dates, unit="m")
        volume_frame['volume'] = volumes

        price_frame.set_index('date')
        price_frame.index = pd.to_datetime(price_frame.index, unit='s')

        volume_frame.set_index('date')
        volume_frame.index = pd.to_datetime(price_frame.index, unit='s')

        ohlc = price_frame['price'].resample('1min').ohlc()
        volume = volume_frame['volume'].resample('1min').sum()

        ohlc.reset_index(drop=True)
        volume.reset_index(drop=True)

        self.data_frame = self.data_frame.append(
            {
                'open': float(ohlc['open'].values[-1] * self.base_price),
                'high': float(ohlc['high'].values[-1] * self.base_price),
                'low': float(ohlc['low'].values[-1] * self.base_price),
                'close': float(ohlc['close'].values[-1] * self.base_price),
                'volume': float(volume.values[-1] * self.base_volume),
            },
            ignore_index=True)

        self.current_step += 1

        scaler = MinMaxScaler()
        scaled_frame = scaler.fit_transform(self.data_frame.values)

        return scaled_frame[-1].astype(self.dtype)
Exemple #10
0
def fbm(base_price: int = 1,
        base_volume: int = 1,
        start_date: str = '2010-01-01',
        start_date_format: str = '%Y-%m-%d',
        times_to_generate: int = 1000,
        hurst: float = 0.61,
        time_frame: str = '1h') -> 'pd.DataFrame':
    """Generates price data from the FBM process.

    Parameters
    ----------
    base_price : int, default 1
        The base price to use for price generation.
    base_volume : int, default 1
        The base volume to use for volume generation.
    start_date : str, default '2010-01-01'
        The start date of the generated data
    start_date_format : str, default '%Y-%m-%d'
        The format for the start date of the generated data.
    times_to_generate : int, default 1000
        The number of bars to make.
    hurst : float, default 0.61
        The hurst parameter for the FBM process.
    time_frame : str, default '1h'
        The time frame.

    Returns
    -------
    `pd.DataFrame`
        The generated data frame containing the OHLCV bars.

    References
    ----------
    [1] https://en.wikipedia.org/wiki/Fractional_Brownian_motion
    """

    times_to_generate = scale_times_to_generate(times_to_generate, time_frame)

    price_fbm = FractionalBrownianMotion(t=times_to_generate, hurst=hurst)
    price_volatility = price_fbm.sample(times_to_generate, zero=False)
    prices = price_volatility + base_price

    volume_gen = GaussianNoise(times_to_generate)
    volume_volatility = volume_gen.sample(times_to_generate)
    volumes = volume_volatility * price_volatility + base_volume

    start_date = pd.to_datetime(start_date, format=start_date_format)
    price_frame = pd.DataFrame([], columns=['date', 'price'], dtype=float)
    volume_frame = pd.DataFrame([], columns=['date', 'volume'], dtype=float)

    price_frame['date'] = pd.date_range(start=start_date,
                                        periods=times_to_generate,
                                        freq="1min")
    price_frame['price'] = abs(prices)

    volume_frame['date'] = price_frame['date'].copy()
    volume_frame['volume'] = abs(volumes)

    price_frame.set_index('date')
    price_frame.index = pd.to_datetime(price_frame.index,
                                       unit='m',
                                       origin=start_date)

    volume_frame.set_index('date')
    volume_frame.index = pd.to_datetime(volume_frame.index,
                                        unit='m',
                                        origin=start_date)

    data_frame = price_frame['price'].resample(time_frame).ohlc()
    data_frame['volume'] = volume_frame['volume'].resample(time_frame).sum()

    return data_frame
Exemple #11
0
def fractional_brownian(t=1, hurst=0.7, n=300):
    model = FractionalBrownianMotion(t=t, hurst=hurst)
    times = model.times(n)
    samples = model.sample(n)
    return (times, samples)