def test_release(mock_exchange_class): exchange = mock_exchange_class.return_value exchange.options = ExchangeOptions() exchange.id = "fake_exchange_id" exchange.name = "coinbase" exchange.clock = mock.Mock() exchange.clock.step = 0 exchange.quote_price = mock.Mock(return_value=Decimal(7000.00)) wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)] portfolio = Portfolio(USD, wallets) order = Order(step=0, exchange_pair=ExchangePair(exchange, USD / BTC), side=TradeSide.BUY, trade_type=TradeType.MARKET, quantity=5200.00 * USD, portfolio=portfolio, price=Decimal(7000.00)) order.execute() wallet_usd = portfolio.get_wallet(exchange.id, USD) assert wallet_usd.balance == 4800 * USD assert wallet_usd.locked_balance == 5200 * USD assert order.path_id in wallet_usd.locked.keys() order.release() assert wallet_usd.balance == 10000 * USD assert wallet_usd.locked_balance == 0 * USD assert order.path_id not in wallet_usd.locked.keys()
def test_invalid_deposit(): # Add to free unlocked balance with different instrument wallet = Wallet(exchange, 10000 * USD) with pytest.raises(IncompatibleInstrumentOperation): wallet.deposit(500 * BTC, reason="test")
def test_on_cancel(mock_exchange_class, cancel_listener): exchange = mock_exchange_class.return_value exchange.options = ExchangeOptions() exchange.id = "fake_exchange_id" exchange.name = "bitfinex" exchange.clock = mock.Mock() exchange.clock.step = 0 exchange.quote_price = mock.Mock(return_value=Decimal(7000.00)) wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)] portfolio = Portfolio(USD, wallets) order = Order(step=0, exchange_pair=ExchangePair(exchange, USD / BTC), side=TradeSide.BUY, trade_type=TradeType.MARKET, quantity=5200.00 * USD, portfolio=portfolio, price=Decimal(7000.00)) order.attach(cancel_listener) assert not cancel_listener.listened order.cancel() assert cancel_listener.listened
def test_properties(mock_exchange_class): exchange = mock_exchange_class.return_value exchange.options = ExchangeOptions() exchange.id = "fake_exchange_id" exchange.name = "coinbase" wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)] portfolio = Portfolio(USD, wallets) order = Order(step=0, exchange_pair=ExchangePair(exchange, USD / BTC), side=TradeSide.BUY, trade_type=TradeType.LIMIT, quantity=5000.00 * USD, portfolio=portfolio, price=7000.00) assert order assert order.step == 0 assert order.base_instrument == USD assert order.quote_instrument == BTC assert order.size == 5000.00 * USD assert order.price == 7000.00 assert order.trades == [] assert order.is_buy assert not order.is_sell assert not order.is_market_order assert order.is_limit_order
def test_detach(mock_exchange_class, mock_order_listener_class): exchange = mock_exchange_class.return_value exchange.options = ExchangeOptions() exchange.id = "fake_exchange_id" exchange.name = "coinbase" exchange.clock = mock.Mock() exchange.clock.step = 0 wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)] portfolio = Portfolio(USD, wallets) order = Order(step=0, exchange_pair=ExchangePair(exchange, USD / BTC), side=TradeSide.BUY, trade_type=TradeType.MARKET, quantity=5000.00 * USD, portfolio=portfolio, price=Decimal(7000.00)) listener = mock_order_listener_class.return_value order.attach(listener) assert len(order.listeners) == 1 assert listener in order.listeners order.detach(listener) assert len(order.listeners) == 0 assert listener not in order.listeners
def test_is_complete(mock_exchange_class): exchange = mock_exchange_class.return_value exchange.options = ExchangeOptions() exchange.id = "fake_exchange_id" exchange.name = "coinbase" exchange.clock = mock.Mock() exchange.clock.step = 0 wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)] portfolio = Portfolio(USD, wallets) # Market order order = Order(step=0, exchange_pair=ExchangePair(exchange, USD / BTC), side=TradeSide.BUY, trade_type=TradeType.MARKET, quantity=5000.00 * USD, portfolio=portfolio, price=Decimal(7000.00)) assert not order.is_complete order.remaining = 0 * USD assert order.is_complete
def test_init(mock_exchange_class): exchange = mock_exchange_class.return_value exchange.options = ExchangeOptions() exchange.id = "fake_exchange_id" exchange.name = "coinbase" wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)] portfolio = Portfolio(USD, wallets) order = Order(step=0, exchange_pair=ExchangePair(exchange, USD / BTC), side=TradeSide.BUY, trade_type=TradeType.MARKET, quantity=5000 * USD, price=7000, portfolio=portfolio) assert order assert order.id assert order.path_id assert order.step == 0 assert order.quantity.instrument == USD assert order.remaining == order.quantity assert isinstance(order.pair, TradingPair) assert order.pair.base == USD assert order.pair.quote == BTC
def test_iadd(mock_exchange_class, mock_order_spec_class): exchange = mock_exchange_class.return_value exchange.options = ExchangeOptions() exchange.id = "fake_exchange_id" exchange.name = "coinbase" exchange.clock = mock.Mock() exchange.clock.step = 0 exchange.quote_price = mock.Mock(return_value=Decimal(7000.00)) wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)] portfolio = Portfolio(USD, wallets) # Market order order = Order(step=0, exchange_pair=ExchangePair(exchange, USD / BTC), side=TradeSide.BUY, trade_type=TradeType.MARKET, quantity=5000.00 * USD, portfolio=portfolio, price=Decimal(7000.00)) order_spec = mock_order_spec_class.return_value assert len(order._specs) == 0 order.add_order_spec(order_spec) assert len(order._specs) == 1 assert order_spec in order._specs
def test_on_complete(mock_trade_class, mock_exchange_class, complete_listener): exchange = mock_exchange_class.return_value exchange.options = ExchangeOptions() exchange.id = "fake_exchange_id" exchange.name = "bitfinex" exchange.clock = mock.Mock() exchange.clock.step = 0 exchange.quote_price = mock.Mock(return_value=Decimal(7000.00)) wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)] portfolio = Portfolio(USD, wallets) order = Order(step=0, exchange_pair=ExchangePair(exchange, USD / BTC), side=TradeSide.BUY, trade_type=TradeType.MARKET, quantity=5200.00 * USD, portfolio=portfolio, price=Decimal(7000.00)) order.attach(complete_listener) order.execute() trade = mock_trade_class.return_value trade.size = Decimal(5197.00) trade.quantity = trade.size * USD trade.commission = 3.00 * USD order.fill(trade) assert not complete_listener.listened order.complete() assert complete_listener.listened
def create_env_for_predicting(config): t = price_history['Close'] p = Stream.source(t.tolist(), dtype="float").rename("USD-BTC") bitfinex = Exchange("bitfinex", service=execute_order)(Stream.source( price_history['Close'].tolist(), dtype="float").rename("USD-BTC")) cash = Wallet(bitfinex, 100000 * USD) asset = Wallet(bitfinex, 0 * BTC) portfolio = Portfolio(USD, [cash, asset]) feed = DataFeed([ p, p.rolling(window=10).mean().rename("fast"), p.rolling(window=50).mean().rename("medium"), p.rolling(window=100).mean().rename("slow"), p.log().diff().fillna(0).rename("lr") ]) reward_scheme = PBR(price=p) action_scheme = BSH(cash=cash, asset=asset).attach(reward_scheme) renderer_feed = DataFeed([ Stream.source(price_history['Close'].tolist(), dtype="float").rename("price"), Stream.sensor(action_scheme, lambda s: s.action, dtype="float").rename("action") ]) environment = default.create(feed=feed, portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, renderer_feed=renderer_feed, renderer=PositionChangeChart(), window_size=config["window_size"], max_allowed_loss=0.6) return environment
def create_env(config): x = np.arange(0, 2 * np.pi, 2 * np.pi / 1000) p = Stream.source(50 * np.sin(3 * x) + 100, dtype="float").rename("USD-TTC") bitfinex = Exchange("bitfinex", service=execute_order)(p) cash = Wallet(bitfinex, 100000 * USD) asset = Wallet(bitfinex, 0 * TTC) portfolio = Portfolio(USD, [cash, asset]) feed = DataFeed([ p, p.rolling(window=10).mean().rename("fast"), p.rolling(window=50).mean().rename("medium"), p.rolling(window=100).mean().rename("slow"), p.log().diff().fillna(0).rename("lr") ]) reward_scheme = default.rewards.PBR(price=p) action_scheme = default.actions.BSH(cash=cash, asset=asset).attach(reward_scheme) env = default.create(feed=feed, portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, window_size=config["window_size"], max_allowed_loss=0.6) return env
def test_str(mock_exchange_class): exchange = mock_exchange_class.return_value exchange.options = ExchangeOptions() exchange.id = "fake_exchange_id" exchange.name = "coinbase" exchange.clock = mock.Mock() exchange.clock.step = 0 exchange.quote_price = mock.Mock(return_value=Decimal(7000.00)) wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)] portfolio = Portfolio(USD, wallets) order = Order(step=0, exchange_pair=ExchangePair(exchange, USD / BTC), side=TradeSide.BUY, trade_type=TradeType.MARKET, quantity=5200.00 * USD, portfolio=portfolio, price=Decimal(7000.00)) pattern = re.compile("<[A-Z][a-zA-Z]*:\\s(\\w+=.*,\\s)*(\\w+=.*)>") string = str(order) assert string assert string == pattern.fullmatch(string).string
def create_env(config): x = np.arange(0, 2 * np.pi, 2 * np.pi / 1001) y = 50 * np.sin(3 * x) + 100 x = np.arange(0, 2 * np.pi, 2 * np.pi / 1000) p = Stream.source(y, dtype="float").rename("USD-TTC") coinbase = Exchange("coinbase", service=execute_order)(p) cash = Wallet(coinbase, 100000 * USD) asset = Wallet(coinbase, 0 * TTC) portfolio = Portfolio(USD, [cash, asset]) feed = DataFeed([ p, p.rolling(window=10).mean().rename("fast"), p.rolling(window=50).mean().rename("medium"), p.rolling(window=100).mean().rename("slow"), p.log().diff().fillna(0).rename("lr") ]) reward_scheme = PBR(price=p) action_scheme = BSH(cash=cash, asset=asset).attach(reward_scheme) renderer_feed = DataFeed([ Stream.source(y, dtype="float").rename("price"), Stream.sensor(action_scheme, lambda s: s.action, dtype="float").rename("action") ]) chart_renderer = PlotlyTradingChart( display=True, # show the chart on screen (default) height= 800, # affects both displayed and saved file height. None for 100% height. save_format="html", # save the chart to an HTML file auto_open_html=True, # open the saved HTML chart in a new browser tab ) import uuid uid = uuid.uuid4() callback = LoggingCallback(f'/Users/vkrot/callback-{uid}', chart_renderer) environment = default.create( feed=feed, portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, renderer_feed=renderer_feed, # renderer=PositionChangeChart(), renderer=PositionChangeChart(), window_size=config["window_size"], max_allowed_loss=0.6, callback=callback) return environment
def create_trade_env(quotes, observations, symbol): # Add features features = [] #exclude "date/Column [0]" from observation - start from column 1 for c in data.columns[0:]: s = Stream.source(list(data[c]), dtype="float").rename(data[c].name) features += [s] feed = DataFeed(features) feed.compile() # define exchange - needs to specify Price-Quote Stream exchange = Exchange("sim-exchange", service=execute_order)( Stream.source(list(quotes["close"]), dtype="float").rename(str("USD-{}").format(symbol))) # add current cash, initial-asset cash = Wallet(exchange, 10000 * USD) asset = Wallet(exchange, 0 * Instrument(symbol, 2, symbol)) # initialize portfolio - base currency USD portfolio = Portfolio(base_instrument=USD, wallets=[cash, asset]) # add element for rendered feed renderer_feed = DataFeed([ Stream.source(list(data.index)).rename("date"), Stream.source(list(data["open"]), dtype="float").rename("open"), Stream.source(list(data["high"]), dtype="float").rename("high"), Stream.source(list(data["low"]), dtype="float").rename("low"), Stream.source(list(data["close"]), dtype="float").rename("close") #Stream.source(list(data["volume"]), dtype="float").rename("volume") ]) reward_scheme = default.rewards.SimpleProfit() action_scheme = default.actions.SimpleOrders(trade_sizes=1) ''' # define reward-scheme # define action-scheme action_scheme = default.actions.BSH( cash=cash, asset=asset ) ''' # create env env = default.create( portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, feed=feed, renderer_feed=renderer_feed, #renderer="screen-log", #window_size=20, max_allowed_loss=0.6) return env
def create_env(envs_config=None): features = [] for c in data.columns[5:]: s = Stream.source(list(data[c][-100:]), dtype="float").rename(data[c].name) features += [s] cp = Stream.select(features, lambda s: s.name == "close") features = [cp.log().diff().fillna(0).rename("lr")] + features[1:] feed = DataFeed(features) feed.compile() bitstamp = Exchange("bitstamp", service=execute_order)(Stream.source( list(data["close"]), dtype="float").rename("USD-BTC")) portfolio = Portfolio( USD, [Wallet(bitstamp, 10000 * USD), Wallet(bitstamp, 10 * BTC)]) renderer_feed = DataFeed([ Stream.source(list(data["date"])).rename("date"), Stream.source(list(data["open"]), dtype="float").rename("open"), Stream.source(list(data["high"]), dtype="float").rename("high"), Stream.source(list(data["low"]), dtype="float").rename("low"), Stream.source(list(data["close"]), dtype="float").rename("close"), Stream.source(list(data["volume"]), dtype="float").rename("volume") ]) # reward_scheme = RiskAdjustedReturns( # return_algorithm='sortino', # risk_free_rate=0.025, # target_returns=0.1, # window_size=200 # ) reward_scheme = SimpleProfit(window_size=200) #PBR(price=cp) # action_scheme = BSH( # cash=portfolio.wallets[0], # asset=portfolio.wallets[1] # ).attach(reward_scheme) env = default.create( portfolio=portfolio, action_scheme="managed-risk", reward_scheme=reward_scheme, #"risk-adjusted", feed=feed, renderer_feed=renderer_feed, renderer=default.renderers.PlotlyTradingChart(display=False, save_format='html', path='./agents/charts/'), window_size=40) return env
def test_init_from_wallets(exchange): portfolio = Portfolio( USD, wallets=[Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)]) assert portfolio.base_instrument == USD assert portfolio.base_balance == 10000 * USD assert portfolio.initial_balance == 10000 * USD assert len(portfolio.wallets) == 2
def test_add(portfolio, exchange): wallet_bch = Wallet(exchange, 1000 * BCH) portfolio.add(wallet_bch) assert wallet_bch in portfolio.wallets
def test_init(): wallet = Wallet(exchange, 10000*USD) assert wallet.balance == 10000*USD assert wallet.exchange == exchange assert wallet.instrument == USD assert len(wallet.locked) == 0
def test_proportion_order_init(mock_exchange_class): exchange = mock_exchange_class.return_value exchange.options = ExchangeOptions() exchange.id = "fake_id" exchange.name = "fake_exchange" wallet_usd = Wallet(exchange, 10000 * USD) wallet_btc = Wallet(exchange, 0 * BTC) portfolio = Portfolio(USD, [wallet_usd, wallet_btc]) order = proportion_order(portfolio=portfolio, source=wallet_usd, target=wallet_btc, proportion=1.0) assert order
def create_env_sin(config): x = np.arange(0, 2 * np.pi, 2 * np.pi / 1001) y = 50 * np.sin(3 * x) + 100 x = np.arange(0, 2 * np.pi, 2 * np.pi / 1000) p = Stream.source(y, dtype="float").rename("USD-TTC") bitfinex = Exchange("bitfinex", service=execute_order)(p) cash = Wallet(bitfinex, 10000 * USD) asset = Wallet(bitfinex, 0 * TTC) portfolio = Portfolio(USD, [cash, asset]) feed = DataFeed([ p, p.rolling(window=10).mean().rename("fast"), p.rolling(window=50).mean().rename("medium"), p.rolling(window=100).mean().rename("slow"), p.log().diff().fillna(0).rename("lr") ]) reward_scheme = default.rewards.PBREX(price=p) #action_scheme = default.actions.BSHEX( # cash=cash, # asset=asset #).attach(reward_scheme) action_scheme = default.actions.SimpleOrders( trade_sizes=3).attach(reward_scheme) renderer_feed = DataFeed([ Stream.source(y, dtype="float").rename("price"), Stream.sensor(action_scheme, lambda s: s.action, dtype="float").rename("action") ]) environment = default.create(feed=feed, portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, renderer_feed=renderer_feed, renderer=PositionChangeChart(), window_size=config["window_size"], max_allowed_loss=0.6) return environment
def execute_sell_order(order: 'Order', base_wallet: 'Wallet', quote_wallet: 'Wallet', current_price: float, options: 'ExchangeOptions', clock: 'Clock') -> 'Trade': """Executes a sell order on the exchange. Parameters ---------- order : `Order` The order that is being filled. base_wallet : `Wallet` The wallet of the base instrument. quote_wallet : `Wallet` The wallet of the quote instrument. current_price : float The current price of the exchange pair. options : `ExchangeOptions` The exchange options. clock : `Clock` The clock for the trading process.. Returns ------- `Trade` The executed trade that was made. """ if order.type == TradeType.LIMIT and order.price > current_price: return None filled = order.remaining.contain(order.exchange_pair) commission = options.commission * filled quantity = filled - commission if commission.size < Decimal(10)**-quantity.instrument.precision: logging.warning( "Commission is less than instrument precision. Canceling order. " "Consider defining a custom instrument with a higher precision.") order.cancel("COMMISSION IS LESS THAN PRECISION.") return None # Transfer Funds from Quote Wallet to Base Wallet transfer = Wallet.transfer(source=quote_wallet, target=base_wallet, quantity=quantity, commission=commission, exchange_pair=order.exchange_pair, reason="SELL") trade = Trade(order_id=order.id, step=clock.step, exchange_pair=order.exchange_pair, side=TradeSide.SELL, trade_type=order.type, quantity=transfer.quantity, price=transfer.price, commission=transfer.commission) return trade
def portfolio(): df1 = pd.read_csv("tests/data/input/bitfinex_(BTC,ETH)USD_d.csv").tail(100) df1 = df1.rename({"Unnamed: 0": "date"}, axis=1) df1 = df1.set_index("date") df2 = pd.read_csv("tests/data/input/bitstamp_(BTC,ETH,LTC)USD_d.csv").tail( 100) df2 = df2.rename({"Unnamed: 0": "date"}, axis=1) df2 = df2.set_index("date") ex1 = Exchange("bitfinex", service=execute_order)( Stream.source(list(df1['BTC:close']), dtype="float").rename("USD-BTC"), Stream.source(list(df1['ETH:close']), dtype="float").rename("USD-ETH")) ex2 = Exchange("binance", service=execute_order)( Stream.source(list(df2['BTC:close']), dtype="float").rename("USD-BTC"), Stream.source(list(df2['ETH:close']), dtype="float").rename("USD-ETH"), Stream.source(list(df2['LTC:close']), dtype="float").rename("USD-LTC")) p = Portfolio(USD, [ Wallet(ex1, 10000 * USD), Wallet(ex1, 10 * BTC), Wallet(ex1, 5 * ETH), Wallet(ex2, 1000 * USD), Wallet(ex2, 5 * BTC), Wallet(ex2, 20 * ETH), Wallet(ex2, 3 * LTC), ]) return p
def test_create_from_buy_order(mock_order_class, mock_exchange_class): exchange = mock_exchange_class.return_value exchange.options = ExchangeOptions() exchange.id = "fake_exchange_id" exchange.name = "bitfinex" exchange.clock = mock.Mock() exchange.clock.step = 0 exchange.quote_price = mock.Mock(return_value=Decimal(7000.00)) wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 2 * BTC)] portfolio = Portfolio(USD, wallets) order = mock_order_class.return_value order.portfolio = portfolio order.exchange_pair = ExchangePair(exchange, USD / BTC) order.path_id = "fake_path_id" order.price = Decimal(7000.00) wallet_btc = portfolio.get_wallet(exchange.id, BTC) wallet_btc.lock( quantity=0.4 * BTC, order=order, reason="test" ) assert float(wallet_btc.balance.size) == 1.6 assert float(wallet_btc.locked[order.path_id].size) == 0.4 order_spec = OrderSpec( side=TradeSide.SELL, trade_type=TradeType.MARKET, exchange_pair=ExchangePair(exchange, USD / BTC) ) next_order = order_spec.create_order(order) assert next_order assert next_order.side == TradeSide.SELL assert next_order.type == TradeType.MARKET assert next_order.exchange_pair == ExchangePair(exchange, USD / BTC) assert next_order.path_id == order.path_id assert next_order.quantity.path_id == order.path_id assert next_order.quantity.instrument == BTC
def test_from_tuple(): wallet_tuple = (exchange, USD, 10000) wallet = Wallet.from_tuple(wallet_tuple) assert wallet.balance == 10000*USD assert wallet.exchange == exchange assert wallet.instrument == USD assert len(wallet.locked) == 0
def create_env(config): df = load_csv('btc_usdt_m5_history.csv') y = df['close'].tolist() p = Stream.source(y, dtype="float").rename("USD-TTC") bitfinex = Exchange("bitfinex", service=execute_order)(p) cash = Wallet(bitfinex, 100000 * USD) asset = Wallet(bitfinex, 0 * TTC) portfolio = Portfolio(USD, [cash, asset]) feed = DataFeed([ p, p.rolling(window=10).mean().rename("fast"), p.rolling(window=50).mean().rename("medium"), p.rolling(window=100).mean().rename("slow"), p.log().diff().fillna(0).rename("lr") ]) reward_scheme = SimpleProfit(window_size=12) action_scheme = ManagedRiskOrders() renderer_feed = DataFeed([ Stream.source(y, dtype="float").rename("price"), Stream.sensor(action_scheme, lambda s: s.action, dtype="float").rename("action") ]) environment = default.create( feed=feed, portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, renderer_feed=renderer_feed, renderer=default.renderers.PlotlyTradingChart(), window_size=config["window_size"], max_allowed_loss=0.6) return environment
def test_complete_basic_order(mock_order_listener_class, mock_trade_class, mock_exchange_class): exchange = mock_exchange_class.return_value exchange.options = ExchangeOptions() exchange.id = "fake_exchange_id" exchange.name = "coinbase" exchange.clock = mock.Mock() exchange.clock.step = 0 wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)] portfolio = Portfolio(USD, wallets) order = Order(step=0, exchange_pair=ExchangePair(exchange, USD / BTC), side=TradeSide.BUY, trade_type=TradeType.MARKET, quantity=5200.00 * USD, portfolio=portfolio, price=Decimal(7000.00)) listener = mock_order_listener_class.return_value listener.on_complete = mock.Mock(return_value=None) order.attach(listener) order.execute() trade = mock_trade_class.return_value trade.size = Decimal(5197.00) trade.quantity = 5197.00 * USD trade.commission = 3.00 * USD order.fill(trade) assert order.status == OrderStatus.PARTIALLY_FILLED next_order = order.complete() assert order.status == OrderStatus.FILLED listener.on_complete.assert_called_once_with(order) assert not next_order
def test_to_json(mock_exchange_class): exchange = mock_exchange_class.return_value exchange.options = ExchangeOptions() exchange.id = "fake_exchange_id" exchange.name = "coinbase" exchange.clock = mock.Mock() exchange.clock.step = 0 exchange.quote_price = mock.Mock(return_value=Decimal(7000.00)) wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)] portfolio = Portfolio(USD, wallets) order = Order(step=0, exchange_pair=ExchangePair(exchange, USD / BTC), side=TradeSide.BUY, trade_type=TradeType.MARKET, quantity=5200.00 * USD, portfolio=portfolio, price=Decimal(7000.00)) d = { "id": str(order.id), "step": int(order.step), "exchange_pair": str(order.exchange_pair), "status": str(order.status), "type": str(order.type), "side": str(order.side), "base_symbol": str(order.pair.base.symbol), "quote_symbol": str(order.pair.quote.symbol), "quantity": str(order.quantity), "size": float(order.size), "remaining": str(order.remaining), "price": float(order.price), "criteria": str(order.criteria), "path_id": str(order.path_id), "created_at": str(order.created_at) } assert order.to_json() == d
def test_on_fill(mock_trade_class, mock_exchange_class): exchange = mock_exchange_class.return_value exchange.options.max_trade_size = 1e6 exchange.id = "fake_exchange_id" exchange.name = "bitfinex" exchange.quote_price = lambda pair: Decimal(7000.00) broker = Broker() broker.exchanges = [exchange] wallets = [Wallet(exchange, 10000 * USD), Wallet(exchange, 0 * BTC)] portfolio = Portfolio(USD, wallets) order = Order(step=0, exchange_pair=ExchangePair(exchange, USD / BTC), side=TradeSide.BUY, trade_type=TradeType.MARKET, quantity=5200.00 * USD, portfolio=portfolio, price=7000.00) order.attach(broker) order.execute() broker.executed[order.id] = order trade = mock_trade_class.return_value trade.quantity = 5197.00 * USD trade.commission = 3.00 * USD trade.order_id = order.id assert order.status == OrderStatus.OPEN order.fill(trade) assert order.status == OrderStatus.FILLED assert order.remaining == 0 assert trade in broker.trades[order.id]
def create_env(config): x = np.arange(0, 2 * np.pi, 2 * np.pi / 1001) y = 50 * np.sin(3 * x) + 100 p = Stream.source(y, dtype="float").rename("USD-TTC") coinbase = Exchange("coinbase", service=execute_order)(p) cash = Wallet(coinbase, 10000 * USD) asset = Wallet(coinbase, 0 * TTC) portfolio = Portfolio(USD, [cash, asset]) feed = DataFeed([ p, p.ewm(span=10).mean().rename("fast"), p.ewm(span=50).mean().rename("medium"), p.ewm(span=100).mean().rename("slow"), p.log().diff().fillna(0).rename("lr") ]) reward_scheme = PBR(price=p) action_scheme = BSH(cash=cash, asset=asset).attach(reward_scheme) renderer_feed = DataFeed([ Stream.source(y, dtype="float").rename("price"), Stream.sensor(action_scheme, lambda s: s.action, dtype="float").rename("action") ]) environment = default.create(feed=feed, portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, renderer_feed=renderer_feed, renderer=PositionChangeChart(), window_size=config["window_size"], max_allowed_loss=0.6) return environment
def test_total_balance(): wallet = Wallet(exchange, 10000 * USD) wallet.deposit(quantity=Quantity(USD, 500, path_id=path_id), reason="test") wallet.deposit(quantity=Quantity(USD, 700, path_id=other_id), reason="test") assert wallet.total_balance == 11200 * USD