def __init__(self, feed, bitshares_instance=None): self.bitshares = bitshares_instance or shared_bitshares_instance() if len(feed) == 2: super(PriceFeed, self).__init__({ "witness": Witness(feed[0], lazy=True), "date": parse_time(feed[1][0]), "maintenance_collateral_ratio": feed[1][1]["maintenance_collateral_ratio"], "maximum_short_squeeze_ratio": feed[1][1]["maximum_short_squeeze_ratio"], "settlement_price": Price(feed[1][1]["settlement_price"]), "core_exchange_rate": Price(feed[1][1]["core_exchange_rate"]) }) else: super(PriceFeed, self).__init__({ "maintenance_collateral_ratio": feed["maintenance_collateral_ratio"], "maximum_short_squeeze_ratio": feed["maximum_short_squeeze_ratio"], "settlement_price": Price(feed["settlement_price"]), "core_exchange_rate": Price(feed["core_exchange_rate"]) })
def __init__(self, order, bitshares_instance=None, **kwargs): self.bitshares = bitshares_instance or shared_bitshares_instance() if isinstance(order, dict) and "price" in order: super(FilledOrder, self).__init__( order.get("price"), base=kwargs.get("base"), quote=kwargs.get("quote"), ) self["time"] = formatTimeString(order["date"]) elif isinstance(order, dict): # filled orders from account history if "op" in order: order = order["op"] base_asset = kwargs.get("base_asset", order["receives"]["asset_id"]) super(FilledOrder, self).__init__( order, base_asset=base_asset, ) if "time" in order: self["time"] = formatTimeString(order["time"]) if "account_id" in order: self["account_id"] = order["account_id"] else: raise ValueError("Couldn't parse 'Price'.")
def __init__(self, account, lazy=False, full=False, bitshares_instance=None): self.cached = False self.full = full self.bitshares = bitshares_instance or shared_bitshares_instance() if isinstance(account, Account): super(Account, self).__init__(account) self.name = account["name"] elif isinstance(account, str): self.name = account.strip().lower() else: raise ValueError( "Account() expects an account name, id or an instance of Account" ) if self.name in Account.accounts_cache and not self.full: super(Account, self).__init__(Account.accounts_cache[self.name]) self.cached = True elif not lazy and not self.cached: self.refresh() self.cached = True
def __init__( self, accounts=[], markets=[], objects=[], on_tx=None, on_object=None, on_block=None, on_account=None, on_market=None, bitshares_instance=None, ): # Events super(Notify, self).__init__() self.events = Events() # BitShares instance self.bitshares = bitshares_instance or shared_bitshares_instance() # Markets market_ids = [] for market_name in markets: market = Market(market_name, bitshares_instance=self.bitshares) market_ids.append([ market["base"]["id"], market["quote"]["id"], ]) # Accounts account_ids = [] for account_name in accounts: account = Account(account_name, bitshares_instance=self.bitshares) account_ids.append(account["id"]) # Callbacks if on_tx: self.on_tx += on_tx if on_object: self.on_object += on_object if on_block: self.on_block += on_block if on_account: self.on_account += on_account if on_market: self.on_market += on_market # Open the websocket self.websocket = BitSharesWebsocket( urls=self.bitshares.rpc.urls, user=self.bitshares.rpc.user, password=self.bitshares.rpc.password, accounts=account_ids, markets=market_ids, objects=objects, on_tx=on_tx, on_object=on_object, on_block=on_block, on_account=self.process_account, on_market=self.process_market, )
def __init__(self, asset, lazy=False, full=False, bitshares_instance=None): self.cached = False self.full = full self.asset = None self.bitshares = bitshares_instance or shared_bitshares_instance() if isinstance(asset, Asset): self.asset = asset.get("symbol") super(Asset, self).__init__(asset) self.cached = True self._cache(asset) elif isinstance(asset, str): self.asset = asset if self.asset in Asset.assets_cache: if (not full or (full and "dynamic_asset_data" in Asset.assets_cache[self.asset])): super(Asset, self).__init__(Asset.assets_cache[self.asset]) else: self.refresh() self.cached = True elif not lazy and not self.cached: self.refresh() self.cached = True else: raise ValueError( "Asset() expects a symbol, id or an instance of Asset")
def __init__( self, config, name, onAccount=None, onOrderMatched=None, onOrderPlaced=None, onMarketUpdate=None, onUpdateCallOrder=None, ontick=None, bitshares_instance=None, *args, **kwargs ): # BitShares instance self.bitshares = bitshares_instance or shared_bitshares_instance() # Storage Storage.__init__(self, name) # Statemachine StateMachine.__init__(self, name) # Events Events.__init__(self) if ontick: self.ontick += ontick if onMarketUpdate: self.onMarketUpdate += onMarketUpdate if onAccount: self.onAccount += onAccount if onOrderMatched: self.onOrderMatched += onOrderMatched if onOrderPlaced: self.onOrderPlaced += onOrderPlaced if onUpdateCallOrder: self.onUpdateCallOrder += onUpdateCallOrder # Redirect this event to also call order placed and order matched self.onMarketUpdate += self._callbackPlaceFillOrders self.config = config self.bot = config["bots"][name] self._account = Account( self.bot["account"], full=True, bitshares_instance=self.bitshares ) self._market = Market( config["bots"][name]["market"], bitshares_instance=self.bitshares ) # Settings for bitshares instance self.bitshares.bundle = bool(self.bot.get("bundle", False)) # disabled flag - this flag can be flipped to True by a bot and # will be reset to False after reset only self.disabled = False
def __init__(self, *args, bitshares_instance=None, **kwargs): self.bitshares = bitshares_instance or shared_bitshares_instance() if (len(args) == 1 and isinstance(args[0], str)): order = self.bitshares.rpc.get_objects([args[0]])[0] if order: super(Order, self).__init__(order["sell_price"]) self["seller"] = order["seller"] self["id"] = order.get("id") self["deleted"] = False else: self["id"] = args[0] self["deleted"] = True self["quote"] = None self["base"] = None self["price"] = None self["seller"] = None elif (isinstance(args[0], dict) and "sell_price" in args[0]): super(Order, self).__init__(args[0]["sell_price"]) self["id"] = args[0].get("id") elif (isinstance(args[0], dict) and "min_to_receive" in args[0] and "amount_to_sell" in args[0]): super(Order, self).__init__( Amount(args[0]["min_to_receive"], bitshares_instance=self.bitshares), Amount(args[0]["amount_to_sell"], bitshares_instance=self.bitshares), ) self["id"] = args[0].get("id") elif isinstance(args[0], Amount) and isinstance(args[1], Amount): super(Order, self).__init__(*args, **kwargs) else: raise ValueError("Unkown format to load Order")
def __init__(self, name, config=None, _account=None, _market=None, fee_asset_symbol=None, bitshares_instance=None, bitshares_bundle=None, *args, **kwargs): # BitShares instance self.bitshares = bitshares_instance or shared_bitshares_instance() # Dex instance used to get different fees for the market self.dex = Dex(self.bitshares) # Storage Storage.__init__(self, name) # Events Events.__init__(self) # Redirect this event to also call order placed and order matched self.onMarketUpdate += self._callbackPlaceFillOrders if config: self.config = config else: self.config = Config.get_worker_config_file(name) self._market = _market self._account = _account # Recheck flag - Tell the strategy to check for updated orders self.recheck_orders = False # Count of orders to be fetched from the API self.fetch_depth = 8 self.fee_asset = fee_asset_symbol # CER cache self.core_exchange_rate = None # Ticker self.ticker = self._market.ticker # Settings for bitshares instance self.bitshares.bundle = bitshares_bundle # Disabled flag - this flag can be flipped to True by a worker and will be reset to False after reset only self.disabled = False # Order expiration time in seconds self.expiration = 60 * 60 * 24 * 365 * 5 # buy/sell actions will return order id by default self.returnOrderId = 'head'
def __init__(self, from_account, to_account, bitshares_instance=None): self.bitshares = bitshares_instance or shared_bitshares_instance() self.to_account = Account(to_account, bitshares_instance=self.bitshares) self.from_account = Account(from_account, bitshares_instance=self.bitshares)
def __init__(self, member, bitshares_instance=None, lazy=False): self.cached = False self.member = member self.bitshares = bitshares_instance or shared_bitshares_instance() if not lazy: self.refresh()
def __init__(self, tx={}, proposer=None, bitshares_instance=None): self.bitshares = bitshares_instance or shared_bitshares_instance() self.clear() if not isinstance(tx, dict): raise ValueError("Invalid TransactionBuilder Format") super(TransactionBuilder, self).__init__(tx) # Do we need to reconstruct the tx from self.ops? self._require_reconstruction = True
def __init__(self, account_name, bitshares_instance=None): self.bitshares = bitshares_instance or shared_bitshares_instance() account = Account(account_name) self.workers = self.bitshares.rpc.get_workers_by_account(account["id"]) super(Workers, self).__init__([ Worker(x, lazy=True, bitshares_instance=self.bitshares) for x in self.workers ])
def __init__(self, config, bitshares_instance=None, view=None): """Initialise variables. But no bot setup, therefore fast""" super().__init__() # BitShares instance self.bitshares = bitshares_instance or shared_bitshares_instance() self.config = config self.view = view self.jobs = set()
def __init__(self, bitshares_instance=None, mode="irreversible"): self.bitshares = bitshares_instance or shared_bitshares_instance() if mode == "irreversible": self.mode = 'last_irreversible_block_num' elif mode == "head": self.mode = "head_block_number" else: raise ValueError("invalid value for 'mode'!")
def __init__(self, block, bitshares_instance=None, lazy=False): self.bitshares = bitshares_instance or shared_bitshares_instance() self.cached = False self.block = block if isinstance(block, Block): super(Block, self).__init__(block) self.cached = True elif not lazy: self.refresh()
def __init__(self, bitshares_instance=None): self.bitshares = bitshares_instance or shared_bitshares_instance() self.schedule = self.bitshares.rpc.get_object("2.12.0").get("current_shuffled_witnesses", []) super(Witnesses, self).__init__( [ Witness(x, lazy=True, bitshares_instance=self.bitshares) for x in self.schedule ] )
def __init__(self, data, bitshares_instance=None): self.bitshares = bitshares_instance or shared_bitshares_instance() if isinstance(data, dict): super(AccountUpdate, self).__init__(data) else: account = Account(data, bitshares_instance=self.bitshares) update = self.bitshares.rpc.get_objects( ["2.6.%s" % (account["id"].split(".")[2])])[0] super(AccountUpdate, self).__init__(update)
def __init__(self, config, name, onAccount=None, onOrderMatched=None, onOrderPlaced=None, onMarketUpdate=None, onUpdateCallOrder=None, ontick=None, bitshares_instance=None, *args, **kwargs): # BitShares instance self.bitshares = bitshares_instance or shared_bitshares_instance() # Storage Storage.__init__(self, name) # Statemachine StateMachine.__init__(self, name) # Events Events.__init__(self) if ontick: self.ontick += ontick if onMarketUpdate: self.onMarketUpdate += onMarketUpdate if onAccount: self.onAccount += onAccount if onOrderMatched: self.onOrderMatched += onOrderMatched if onOrderPlaced: self.onOrderPlaced += onOrderPlaced if onUpdateCallOrder: self.onUpdateCallOrder += onUpdateCallOrder # Redirect this event to also call order placed and order matched self.onMarketUpdate += self._callbackPlaceFillOrders self.config = config self.bot = config["bots"][name] self._account = Account(self.bot["account"], full=True, bitshares_instance=self.bitshares) self._market = Market(config["bots"][name]["market"], bitshares_instance=self.bitshares) # Settings for bitshares instance self.bitshares.bundle = bool(self.bot.get("bundle", False)) # disabled flag - this flag can be flipped to True by a bot and # will be reset to False after reset only self.disabled = False
def __init__(self, market, bitshares_instance=None): self.market = market self.ticker = self.market.ticker self.disabled = False # flag for suppress errors # Count of orders to be fetched from the API self.fetch_depth = 8 # BitShares instance self.bitshares = bitshares_instance or shared_bitshares_instance() self.log = logging.LoggerAdapter( logging.getLogger('dexbot.pricefeed_log'), {})
def __init__(self, call, bitshares_instance=None, **kwargs): self.bitshares = bitshares_instance or shared_bitshares_instance() if isinstance(call, dict) and "call_price" in call: super(UpdateCallOrder, self).__init__( call.get("call_price"), base=call["call_price"].get("base"), quote=call["call_price"].get("quote"), ) else: raise ValueError("Couldn't parse 'Call'.")
def fees_parser(self, start_date, end_date, csv_file="Untitled"): """ This parses the BitShares blockchain and aggregates historical fee data by type. The user is expected to input start and end dates on the user interface, which will be passed into this method. The dates need to be in datetime format.""" # This will pass in the start date and retrieve the block number for the first block to parse begin = self.block_search(start_date) # This will pass in the end date and retrieve the block number for # the last block to parse. As we want to fully capture the transactions # of the last day, we will pass in the next day's date and stop at the block just prior. stop = self.block_search(end_date + timedelta(days=1)) - 1 # List to temporarily hold the dictionaries until we store them in a dataframe storage = [] # We will iterate through the blocks and store relevant block information in a dictionary for blocknum in range(begin, stop + 1): # Dictionary to store block information block_data = dict() # To retrieve the blocks from the blockchain block = shared_bitshares_instance().rpc.get_block(blocknum) # Record the dates ts = pd.Timestamp(block["timestamp"]) block_data["Date"] = datetime.date(ts) # Iterating through the data within each block for tx in block["transactions"]: for op in tx["operations"]: key = getOperationNameForId(op[0]) # If the fee was paid in BTS, add the fee amount to the running total for each operation type if op[1]["fee"].get("asset_id") == "1.3.0": block_data[key] = block_data.get( key, 0) + op[1]["fee"].get("amount") # Append the dictionaries to the list for each block so that the data won't be lost storage.append(block_data) # Creating a dataframe to store the fee information data = pd.DataFrame(storage) data.fillna(0, inplace=True) # Aggregating at the daily level daily = data.groupby("Date") daily = daily.sum() daily.to_csv(str(csv_file) + ".csv")
def __init__(self, proposer, proposal_expiration=None, proposal_review=None, parent=None, bitshares_instance=None, *args, **kwargs): self.bitshares = bitshares_instance or shared_bitshares_instance() self.set_expiration(proposal_expiration or 2 * 24 * 60 * 60) self.set_review(proposal_review) self.set_parent(parent) self.set_proposer(proposer) self.ops = list()
def __init__(self, tx={}, proposer=None, expiration=None, bitshares_instance=None): self.bitshares = bitshares_instance or shared_bitshares_instance() self.clear() if tx and isinstance(tx, dict): super(TransactionBuilder, self).__init__(tx) # Load operations self.ops = tx["operations"] self._require_reconstruction = False else: self._require_reconstruction = True self.set_expiration(expiration)
def __init__( self, *args, bitshares_instance=None, **kwargs ): # BitShares instance self.bitshares = bitshares_instance or shared_bitshares_instance() # make sure the memo key is added to the instance memo_key = Config.get("bitshares", "exchange_account_memo_key") if not self.bitshares.wallet.created() or\ memo_key in self.bitshares.wallet.keys: self.bitshares.wallet.setKeys(memo_key) # Get configuration self.config = Config.get_config() # The watch_mode tells us where to look at "recent" blocks in the # blockchain self.watch_mode = self.config["bitshares"].get( "watch_mode", "irreversible") # Storage factory self.storage = kwargs.pop("storage", None) if not self.storage: self.storage = get_operation_storage( self.config["operation_storage"]["use"] ) # Obtain data from the Blockchain about our account self.my_account = Account( self.config["bitshares"]["exchange_account_name"], bitshares_instance=self.bitshares ) # Test my_account assert self.my_account["id"] == self.config["bitshares"]["exchange_account_id"], ( "account id for exchange_account_name does not match exchange_acount_id! " "({} != {})".format( self.my_account["id"], self.config["bitshares"]["exchange_account_id"] ) ) # More (optional) parameters provided on instantiation self.start_block = kwargs.pop("start_block", None) self.stop_block = kwargs.pop("stop_block", None)
def __init__(self, *args, bitshares_instance=None, **kwargs): self.bitshares = bitshares_instance or shared_bitshares_instance() # Compatibility after name change from wif->keys if "wif" in kwargs and "keys" not in kwargs: kwargs["keys"] = kwargs["wif"] if "keys" in kwargs: self.setKeys(kwargs["keys"]) else: """ If no keys are provided manually we load the SQLite keyStorage """ from .storage import (keyStorage, MasterPassword) self.MasterPassword = MasterPassword self.keyStorage = keyStorage
def __init__(self, *args, base=None, quote=None, bitshares_instance=None, **kwargs): self.bitshares = bitshares_instance or shared_bitshares_instance() if len(args) == 1 and isinstance(args[0], str): import re quote_symbol, base_symbol = re.split("[/-:]", args[0]) quote = Asset(quote_symbol, bitshares_instance=self.bitshares) base = Asset(base_symbol, bitshares_instance=self.bitshares) super(Market, self).__init__({"base": base, "quote": quote}) if len(args) == 0 and base and quote: super(Market, self).__init__({"base": base, "quote": quote})
def __init__(self, data, klass=None, space_id=1, object_id=None, lazy=False, use_cache=True, bitshares_instance=None, *args, **kwargs): self.bitshares = bitshares_instance or shared_bitshares_instance() self.cached = False self.identifier = None # We don't read lists, sets, or tuples if isinstance(data, (list, set, tuple)): raise ValueError( "Cannot interpret lists! Please load elements individually!") if klass and isinstance(data, klass): self.identifier = data.get("id") super().__init__(data) elif isinstance(data, dict): self.identifier = data.get("id") super().__init__(data) elif isinstance(data, int): # This is only for block number bascially self.identifier = data if not lazy and not self.cached: self.refresh() # make sure to store the blocknumber for caching self["id"] = str(data) # Set identifier again as it is overwritten in super() in refresh() self.identifier = data else: self.identifier = data if self.test_valid_objectid(self.identifier): # Here we assume we deal with an id self.testid(self.identifier) if self.iscached(data): super().__init__(self.getcache(data)) elif not lazy and not self.cached: self.refresh() if use_cache and not lazy: self.cache() self.cached = True
def __init__( self, worker, lazy=False, bitshares_instance=None, ): self.bitshares = bitshares_instance or shared_bitshares_instance() self.cached = False if isinstance(worker, (Worker, dict)): self.identifier = worker["id"] super(Worker, self).__init__(worker) self.cached = True else: self.identifier = worker if not lazy: self.refresh()
def __init__(self, *args, base=None, quote=None, bitshares_instance=None, **kwargs): self.bitshares = bitshares_instance or shared_bitshares_instance() if len(args) == 1 and isinstance(args[0], str): quote_symbol, base_symbol = self._get_assets_from_string(args[0]) quote = Asset(quote_symbol, bitshares_instance=self.bitshares) base = Asset(base_symbol, bitshares_instance=self.bitshares) super(Market, self).__init__({"base": base, "quote": quote}) elif len(args) == 0 and base and quote: super(Market, self).__init__({"base": base, "quote": quote}) else: raise ValueError("Unknown Market Format: %s" % str(args))
def __init__(self, *args, bitshares_instance=None, **kwargs): self.bitshares = bitshares_instance or shared_bitshares_instance() if ( len(args) == 1 and isinstance(args[0], str) ): """ Load from id """ order = self.bitshares.rpc.get_objects([args[0]])[0] if order: super(Order, self).__init__(order["sell_price"]) self["seller"] = order["seller"] self["id"] = order.get("id") self["deleted"] = False else: self["id"] = args[0] self["deleted"] = True self["quote"] = None self["base"] = None self["price"] = None self["seller"] = None elif ( isinstance(args[0], dict) and "sell_price" in args[0] ): """ Load from object 1.7.xxx """ super(Order, self).__init__(args[0]["sell_price"]) self["id"] = args[0].get("id") elif ( isinstance(args[0], dict) and "min_to_receive" in args[0] and "amount_to_sell" in args[0] ): """ Load from an operation """ super(Order, self).__init__( Amount(args[0]["min_to_receive"], bitshares_instance=self.bitshares), Amount(args[0]["amount_to_sell"], bitshares_instance=self.bitshares), ) self["id"] = args[0].get("id") else: # Try load Order as Price super(Order, self).__init__(*args, **kwargs)
def __init__( self, config, bitshares_instance=None, ): # BitShares instance self.bitshares = bitshares_instance or shared_bitshares_instance() self.config = config # Load all accounts and markets in use to subscribe to them accounts = set() markets = set() for botname, bot in config["bots"].items(): if "account" not in bot: raise ValueError("Bot %s has no account" % botname) if "market" not in bot: raise ValueError("Bot %s has no market" % botname) accounts.add(bot["account"]) markets.add(bot["market"]) # Create notification instance # Technically, this will multiplex markets and accounts and # we need to demultiplex the events after we have received them self.notify = Notify( markets=list(markets), accounts=list(accounts), on_market=self.on_market, on_account=self.on_account, on_block=self.on_block, bitshares_instance=self.bitshares ) # Initialize bots: for botname, bot in config["bots"].items(): klass = getattr( importlib.import_module(bot["module"]), bot["bot"] ) self.bots[botname] = klass( config=config, name=botname, bitshares_instance=self.bitshares )
def __init__(self, config, bitshares_instance=None, view=None): super().__init__() # BitShares instance self.bitshares = bitshares_instance or shared_bitshares_instance() self.config = copy.deepcopy(config) self.view = view self.jobs = [] self.notify = None self.config_lock = threading.RLock() self.workers = {} self.accounts = set() self.markets = set() # Set the module search path user_worker_path = os.path.expanduser("~/bots") if os.path.exists(user_worker_path): sys.path.append(user_worker_path)