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)
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()
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)
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)
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
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)