Example #1
0
def compile_asset_market_info():
    """Run through all assets and compose and store market ranking information."""
    mongo_db = config.mongo_db
    
    if not config.CAUGHT_UP:
        logging.warn("Not updating asset market info as CAUGHT_UP is false.")
        return False
    
    #grab the last block # we processed assets data off of
    last_block_assets_compiled = mongo_db.app_config.find_one()['last_block_assets_compiled']
    last_block_time_assets_compiled = util.get_block_time(last_block_assets_compiled)
    #logging.debug("Comping info for assets traded since block %i" % last_block_assets_compiled)
    current_block_index = config.CURRENT_BLOCK_INDEX #store now as it may change as we are compiling asset data :)
    current_block_time = util.get_block_time(current_block_index)

    if current_block_index == last_block_assets_compiled:
        #all caught up -- call again in 10 minutes
        return True

    mps_xcp_btc, xcp_btc_price, btc_xcp_price = get_price_primatives()
    all_traded_assets = list(set(list([config.BTC, config.XCP]) + list(mongo_db.trades.find({}, {'quote_asset': 1, '_id': 0}).distinct('quote_asset'))))
    
    #######################
    #get a list of all assets with a trade within the last 24h (not necessarily just against XCP and BTC)
    # ^ this is important because compiled market info has a 24h vol parameter that designates total volume for the asset across ALL pairings
    start_dt_1d = datetime.datetime.utcnow() - datetime.timedelta(days=1)
    
    assets = list(set(
          list(mongo_db.trades.find({'block_time': {'$gte': start_dt_1d}}).distinct('quote_asset'))
        + list(mongo_db.trades.find({'block_time': {'$gte': start_dt_1d}}).distinct('base_asset'))
    ))
    for asset in assets:
        market_info_24h = compile_24h_market_info(asset)
        mongo_db.asset_market_info.update({'asset': asset}, {"$set": market_info_24h})
    #for all others (i.e. no trade in the last 24 hours), zero out the 24h trade data
    non_traded_assets = list(set(all_traded_assets) - set(assets))
    mongo_db.asset_market_info.update( {'asset': {'$in': non_traded_assets}}, {"$set": {
            '24h_summary': {'vol': 0, 'count': 0},
            '24h_ohlc_in_{}'.format(config.XCP.lower()): {},
            '24h_ohlc_in_{}'.format(config.BTC.lower()): {},
            '24h_vol_price_change_in_{}'.format(config.XCP.lower()): None,
            '24h_vol_price_change_in_{}'.format(config.BTC.lower()): None,
    }}, multi=True)
    logging.info("Block: %s -- Calculated 24h stats for: %s" % (current_block_index, ', '.join(assets)))
    
    #######################
    #get a list of all assets with a trade within the last 7d up against XCP and BTC
    start_dt_7d = datetime.datetime.utcnow() - datetime.timedelta(days=7)
    assets = list(set(
          list(mongo_db.trades.find({'block_time': {'$gte': start_dt_7d}, 'base_asset': {'$in': [config.XCP, config.BTC]}}).distinct('quote_asset'))
        + list(mongo_db.trades.find({'block_time': {'$gte': start_dt_7d}}).distinct('base_asset'))
    ))
    for asset in assets:
        market_info_7d = compile_7d_market_info(asset)
        mongo_db.asset_market_info.update({'asset': asset}, {"$set": market_info_7d})
    non_traded_assets = list(set(all_traded_assets) - set(assets))
    mongo_db.asset_market_info.update( {'asset': {'$in': non_traded_assets}}, {"$set": {
            '7d_history_in_{}'.format(config.XCP.lower()): [],
            '7d_history_in_{}'.format(config.BTC.lower()): [],
    }}, multi=True)
    logging.info("Block: %s -- Calculated 7d stats for: %s" % (current_block_index, ', '.join(assets)))

    #######################
    #update summary market data for assets traded since last_block_assets_compiled
    #get assets that were traded since the last check with either BTC or XCP, and update their market summary data
    assets = list(set(
          list(mongo_db.trades.find({'block_index': {'$gt': last_block_assets_compiled}, 'base_asset': {'$in': [config.XCP, config.BTC]}}).distinct('quote_asset'))
        + list(mongo_db.trades.find({'block_index': {'$gt': last_block_assets_compiled}}).distinct('base_asset'))
    ))
    #update our storage of the latest market info in mongo
    for asset in assets:
        logging.info("Block: %s -- Updating asset market info for %s ..." % (current_block_index, asset))
        summary_info = compile_summary_market_info(asset, mps_xcp_btc, xcp_btc_price, btc_xcp_price)
        mongo_db.asset_market_info.update( {'asset': asset}, {"$set": summary_info}, upsert=True)

    
    #######################
    #next, compile market cap historicals (and get the market price data that we can use to update assets with new trades)
    #NOTE: this algoritm still needs to be fleshed out some...I'm not convinced it's laid out/optimized like it should be
    #start by getting all trades from when we last compiled this data
    trades = mongo_db.trades.find({'block_index': {'$gt': last_block_assets_compiled}}).sort('block_index', pymongo.ASCENDING)
    trades_by_block = [] #tracks assets compiled per block, as we only want to analyze any given asset once per block
    trades_by_block_mapping = {} 
    #organize trades by block
    for t in trades:
        if t['block_index'] in trades_by_block_mapping:
            assert trades_by_block_mapping[t['block_index']]['block_index'] == t['block_index']
            assert trades_by_block_mapping[t['block_index']]['block_time'] == t['block_time']
            trades_by_block_mapping[t['block_index']]['trades'].append(t)
        else:
            e = {'block_index': t['block_index'], 'block_time': t['block_time'], 'trades': [t,]}
            trades_by_block.append(e)
            trades_by_block_mapping[t['block_index']] = e  

    for t_block in trades_by_block:
        #reverse the tradelist per block, and ensure that we only process an asset that hasn't already been processed for this block
        # (as there could be multiple trades in a single block for any specific asset). we reverse the list because
        # we'd rather process a later trade for a given asset, as the market price for that will take into account
        # the earlier trades on that same block for that asset, and we don't want/need multiple cap points per block
        assets_in_block = {}
        mps_xcp_btc, xcp_btc_price, btc_xcp_price = get_price_primatives(end_dt=t_block['block_time'])
        for t in reversed(t_block['trades']):
            assets = []
            if t['base_asset'] not in assets_in_block:
                assets.append(t['base_asset'])
                assets_in_block[t['base_asset']] = True
            if t['quote_asset'] not in assets_in_block:
                assets.append(t['quote_asset'])
                assets_in_block[t['quote_asset']] = True
            if not len(assets): continue
    
            for asset in assets:
                #recalculate the market cap for the asset this trade is for
                asset_info = get_asset_info(asset, at_dt=t['block_time'])
                (price_summary_in_xcp, price_summary_in_btc, price_in_xcp, price_in_btc, aggregated_price_in_xcp, aggregated_price_in_btc
                ) = get_xcp_btc_price_info(asset, mps_xcp_btc, xcp_btc_price, btc_xcp_price, with_last_trades=0, end_dt=t['block_time'])
                market_cap_in_xcp, market_cap_in_btc = calc_market_cap(asset_info, price_in_xcp, price_in_btc)
                #^ this will get price data from the block time of this trade back the standard number of days and trades
                # to determine our standard market price, relative (anchored) to the time of this trade
        
                for market_cap_as in (config.XCP, config.BTC):
                    market_cap = market_cap_in_xcp if market_cap_as == config.XCP else market_cap_in_btc
                    #if there is a previously stored market cap for this asset, add a new history point only if the two caps differ
                    prev_market_cap_history = mongo_db.asset_marketcap_history.find({'market_cap_as': market_cap_as, 'asset': asset,
                        'block_index': {'$lt': t['block_index']}}).sort('block_index', pymongo.DESCENDING).limit(1)
                    prev_market_cap_history = list(prev_market_cap_history)[0] if prev_market_cap_history.count() == 1 else None
                    
                    if market_cap and (not prev_market_cap_history or prev_market_cap_history['market_cap'] != market_cap):
                        mongo_db.asset_marketcap_history.insert({
                            'block_index': t['block_index'],
                            'block_time': t['block_time'],
                            'asset': asset,
                            'market_cap': market_cap,
                            'market_cap_as': market_cap_as,
                        })
                        logging.info("Block %i -- Calculated market cap history point for %s as %s (mID: %s)" % (t['block_index'], asset, market_cap_as, t['message_index']))
    
    mongo_db.app_config.update({}, {'$set': {'last_block_assets_compiled': current_block_index}})
    return True
def compile_asset_market_info():
    """Run through all assets and compose and store market ranking information."""
    mongo_db = config.mongo_db
    
    if not config.CAUGHT_UP:
        logging.warn("Not updating asset market info as CAUGHT_UP is false.")
        return False
    
    #grab the last block # we processed assets data off of
    last_block_assets_compiled = mongo_db.app_config.find_one()['last_block_assets_compiled']
    last_block_time_assets_compiled = util.get_block_time(last_block_assets_compiled)
    #logging.debug("Comping info for assets traded since block %i" % last_block_assets_compiled)
    current_block_index = config.CURRENT_BLOCK_INDEX #store now as it may change as we are compiling asset data :)
    current_block_time = util.get_block_time(current_block_index)

    if current_block_index == last_block_assets_compiled:
        #all caught up -- call again in 10 minutes
        return True

    mps_xlt_ltc, xlt_ltc_price, ltc_xlt_price = get_price_primatives()
    all_traded_assets = list(set(list([config.LTC, config.XLT]) + list(mongo_db.trades.find({}, {'quote_asset': 1, '_id': 0}).distinct('quote_asset'))))
    
    #######################
    #get a list of all assets with a trade within the last 24h (not necessarily just against XLT and LTC)
    # ^ this is important because compiled market info has a 24h vol parameter that designates total volume for the asset across ALL pairings
    start_dt_1d = datetime.datetime.utcnow() - datetime.timedelta(days=1)
    
    assets = list(set(
          list(mongo_db.trades.find({'block_time': {'$gte': start_dt_1d}}).distinct('quote_asset'))
        + list(mongo_db.trades.find({'block_time': {'$gte': start_dt_1d}}).distinct('base_asset'))
    ))
    for asset in assets:
        market_info_24h = compile_24h_market_info(asset)
        mongo_db.asset_market_info.update({'asset': asset}, {"$set": market_info_24h})
    #for all others (i.e. no trade in the last 24 hours), zero out the 24h trade data
    non_traded_assets = list(set(all_traded_assets) - set(assets))
    mongo_db.asset_market_info.update( {'asset': {'$in': non_traded_assets}}, {"$set": {
            '24h_summary': {'vol': 0, 'count': 0},
            '24h_ohlc_in_{}'.format(config.XLT.lower()): {},
            '24h_ohlc_in_{}'.format(config.LTC.lower()): {},
            '24h_vol_price_change_in_{}'.format(config.XLT.lower()): None,
            '24h_vol_price_change_in_{}'.format(config.LTC.lower()): None,
    }}, multi=True)
    logging.info("Block: %s -- Calculated 24h stats for: %s" % (current_block_index, ', '.join(assets)))
    
    #######################
    #get a list of all assets with a trade within the last 7d up against XLT and LTC
    start_dt_7d = datetime.datetime.utcnow() - datetime.timedelta(days=7)
    assets = list(set(
          list(mongo_db.trades.find({'block_time': {'$gte': start_dt_7d}, 'base_asset': {'$in': [config.XLT, config.LTC]}}).distinct('quote_asset'))
        + list(mongo_db.trades.find({'block_time': {'$gte': start_dt_7d}}).distinct('base_asset'))
    ))
    for asset in assets:
        market_info_7d = compile_7d_market_info(asset)
        mongo_db.asset_market_info.update({'asset': asset}, {"$set": market_info_7d})
    non_traded_assets = list(set(all_traded_assets) - set(assets))
    mongo_db.asset_market_info.update( {'asset': {'$in': non_traded_assets}}, {"$set": {
            '7d_history_in_{}'.format(config.XLT.lower()): [],
            '7d_history_in_{}'.format(config.LTC.lower()): [],
    }}, multi=True)
    logging.info("Block: %s -- Calculated 7d stats for: %s" % (current_block_index, ', '.join(assets)))

    #######################
    #update summary market data for assets traded since last_block_assets_compiled
    #get assets that were traded since the last check with either LTC or XLT, and update their market summary data
    assets = list(set(
          list(mongo_db.trades.find({'block_index': {'$gt': last_block_assets_compiled}, 'base_asset': {'$in': [config.XLT, config.LTC]}}).distinct('quote_asset'))
        + list(mongo_db.trades.find({'block_index': {'$gt': last_block_assets_compiled}}).distinct('base_asset'))
    ))
    #update our storage of the latest market info in mongo
    for asset in assets:
        logging.info("Block: %s -- Updating asset market info for %s ..." % (current_block_index, asset))
        summary_info = compile_summary_market_info(asset, mps_xlt_ltc, xlt_ltc_price, ltc_xlt_price)
        mongo_db.asset_market_info.update( {'asset': asset}, {"$set": summary_info}, upsert=True)

    
    #######################
    #next, compile market cap historicals (and get the market price data that we can use to update assets with new trades)
    #NOTE: this algoritm still needs to be fleshed out some...I'm not convinced it's laid out/optimized like it should be
    #start by getting all trades from when we last compiled this data
    trades = mongo_db.trades.find({'block_index': {'$gt': last_block_assets_compiled}}).sort('block_index', pymongo.ASCENDING)
    trades_by_block = [] #tracks assets compiled per block, as we only want to analyze any given asset once per block
    trades_by_block_mapping = {} 
    #organize trades by block
    for t in trades:
        if t['block_index'] in trades_by_block_mapping:
            assert trades_by_block_mapping[t['block_index']]['block_index'] == t['block_index']
            assert trades_by_block_mapping[t['block_index']]['block_time'] == t['block_time']
            trades_by_block_mapping[t['block_index']]['trades'].append(t)
        else:
            e = {'block_index': t['block_index'], 'block_time': t['block_time'], 'trades': [t,]}
            trades_by_block.append(e)
            trades_by_block_mapping[t['block_index']] = e  

    for t_block in trades_by_block:
        #reverse the tradelist per block, and ensure that we only process an asset that hasn't already been processed for this block
        # (as there could be multiple trades in a single block for any specific asset). we reverse the list because
        # we'd rather process a later trade for a given asset, as the market price for that will take into account
        # the earlier trades on that same block for that asset, and we don't want/need multiple cap points per block
        assets_in_block = {}
        mps_xlt_ltc, xlt_ltc_price, ltc_xlt_price = get_price_primatives(end_dt=t_block['block_time'])
        for t in reversed(t_block['trades']):
            assets = []
            if t['base_asset'] not in assets_in_block:
                assets.append(t['base_asset'])
                assets_in_block[t['base_asset']] = True
            if t['quote_asset'] not in assets_in_block:
                assets.append(t['quote_asset'])
                assets_in_block[t['quote_asset']] = True
            if not len(assets): continue
    
            for asset in assets:
                #recalculate the market cap for the asset this trade is for
                asset_info = get_asset_info(asset, at_dt=t['block_time'])
                (price_summary_in_xlt, price_summary_in_ltc, price_in_xlt, price_in_ltc, aggregated_price_in_xlt, aggregated_price_in_ltc
                ) = get_xlt_ltc_price_info(asset, mps_xlt_ltc, xlt_ltc_price, ltc_xlt_price, with_last_trades=0, end_dt=t['block_time'])
                market_cap_in_xlt, market_cap_in_ltc = calc_market_cap(asset_info, price_in_xlt, price_in_ltc)
                #^ this will get price data from the block time of this trade back the standard number of days and trades
                # to determine our standard market price, relative (anchored) to the time of this trade
        
                for market_cap_as in (config.XLT, config.LTC):
                    market_cap = market_cap_in_xlt if market_cap_as == config.XLT else market_cap_in_ltc
                    #if there is a previously stored market cap for this asset, add a new history point only if the two caps differ
                    prev_market_cap_history = mongo_db.asset_marketcap_history.find({'market_cap_as': market_cap_as, 'asset': asset,
                        'block_index': {'$lt': t['block_index']}}).sort('block_index', pymongo.DESCENDING).limit(1)
                    prev_market_cap_history = list(prev_market_cap_history)[0] if prev_market_cap_history.count() == 1 else None
                    
                    if market_cap and (not prev_market_cap_history or prev_market_cap_history['market_cap'] != market_cap):
                        mongo_db.asset_marketcap_history.insert({
                            'block_index': t['block_index'],
                            'block_time': t['block_time'],
                            'asset': asset,
                            'market_cap': market_cap,
                            'market_cap_as': market_cap_as,
                        })
                        logging.info("Block %i -- Calculated market cap history point for %s as %s (mID: %s)" % (t['block_index'], asset, market_cap_as, t['message_index']))
    
    mongo_db.app_config.update({}, {'$set': {'last_block_assets_compiled': current_block_index}})
    return True
Example #3
0
def compile_asset_market_info():
    """Run through all assets and compose and store market ranking information."""
    mongo_db = config.mongo_db

    if not config.CAUGHT_UP:
        logging.warn("Not updating asset market info as CAUGHT_UP is false.")
        return False

    #grab the last block # we processed assets data off of
    last_block_assets_compiled = mongo_db.app_config.find_one(
    )['last_block_assets_compiled']
    last_block_time_assets_compiled = util.get_block_time(
        last_block_assets_compiled)
    current_block_index = config.CURRENT_BLOCK_INDEX  #store now as it may change as we are compiling asset data :)
    current_block_time = util.get_block_time(current_block_index)

    if current_block_index == last_block_assets_compiled:
        #all caught up -- call again in 10 minutes
        return True

    mps_xcp_btc, xcp_btc_price, btc_xcp_price = get_price_primatives()
    all_traded_assets = list(
        set(
            list([config.BTC, config.XCP]) + list(
                mongo_db.trades.find({}, {
                    'quote_asset': 1,
                    '_id': 0
                }).distinct('quote_asset'))))

    start_dt_1d = datetime.datetime.utcnow() - datetime.timedelta(days=1)

    assets = list(
        set(
            list(
                mongo_db.trades.find({
                    'block_time': {
                        '$gte': start_dt_1d
                    }
                }).distinct('quote_asset')) + list(
                    mongo_db.trades.find({
                        'block_time': {
                            '$gte': start_dt_1d
                        }
                    }).distinct('base_asset'))))
    for asset in assets:
        market_info_24h = compile_24h_market_info(asset)
        mongo_db.asset_market_info.update({'asset': asset},
                                          {"$set": market_info_24h})
    #for all others (i.e. no trade in the last 24 hours), zero out the 24h trade data
    non_traded_assets = list(set(all_traded_assets) - set(assets))
    mongo_db.asset_market_info.update({'asset': {
        '$in': non_traded_assets
    }}, {
        "$set": {
            '24h_summary': {
                'vol': 0,
                'count': 0
            },
            '24h_ohlc_in_{}'.format(config.XCP.lower()): {},
            '24h_ohlc_in_{}'.format(config.BTC.lower()): {},
            '24h_vol_price_change_in_{}'.format(config.XCP.lower()): None,
            '24h_vol_price_change_in_{}'.format(config.BTC.lower()): None,
        }
    },
                                      multi=True)
    logging.info("Block: %s -- Calculated 24h stats for: %s" %
                 (current_block_index, ', '.join(assets)))

    start_dt_7d = datetime.datetime.utcnow() - datetime.timedelta(days=7)
    assets = list(
        set(
            list(
                mongo_db.trades.find({
                    'block_time': {
                        '$gte': start_dt_7d
                    },
                    'base_asset': {
                        '$in': [config.XCP, config.BTC]
                    }
                }).distinct('quote_asset')) + list(
                    mongo_db.trades.find({
                        'block_time': {
                            '$gte': start_dt_7d
                        }
                    }).distinct('base_asset'))))
    for asset in assets:
        market_info_7d = compile_7d_market_info(asset)
        mongo_db.asset_market_info.update({'asset': asset},
                                          {"$set": market_info_7d})
    non_traded_assets = list(set(all_traded_assets) - set(assets))
    mongo_db.asset_market_info.update({'asset': {
        '$in': non_traded_assets
    }}, {
        "$set": {
            '7d_history_in_{}'.format(config.XCP.lower()): [],
            '7d_history_in_{}'.format(config.BTC.lower()): [],
        }
    },
                                      multi=True)
    logging.info("Block: %s -- Calculated 7d stats for: %s" %
                 (current_block_index, ', '.join(assets)))

    assets = list(
        set(
            list(
                mongo_db.trades.find({
                    'block_index': {
                        '$gt': last_block_assets_compiled
                    },
                    'base_asset': {
                        '$in': [config.XCP, config.BTC]
                    }
                }).distinct('quote_asset')) + list(
                    mongo_db.trades.find({
                        'block_index': {
                            '$gt': last_block_assets_compiled
                        }
                    }).distinct('base_asset'))))
    for asset in assets:
        logging.info("Block: %s -- Updating asset market info for %s ..." %
                     (current_block_index, asset))
        summary_info = compile_summary_market_info(asset, mps_xcp_btc,
                                                   xcp_btc_price,
                                                   btc_xcp_price)
        mongo_db.asset_market_info.update({'asset': asset},
                                          {"$set": summary_info},
                                          upsert=True)

    trades = mongo_db.trades.find({
        'block_index': {
            '$gt': last_block_assets_compiled
        }
    }).sort('block_index', pymongo.ASCENDING)
    trades_by_block = [
    ]  #tracks assets compiled per block, as we only want to analyze any given asset once per block
    trades_by_block_mapping = {}
    #organize trades by block
    for t in trades:
        if t['block_index'] in trades_by_block_mapping:
            assert trades_by_block_mapping[
                t['block_index']]['block_index'] == t['block_index']
            assert trades_by_block_mapping[
                t['block_index']]['block_time'] == t['block_time']
            trades_by_block_mapping[t['block_index']]['trades'].append(t)
        else:
            e = {
                'block_index': t['block_index'],
                'block_time': t['block_time'],
                'trades': [
                    t,
                ]
            }
            trades_by_block.append(e)
            trades_by_block_mapping[t['block_index']] = e

    for t_block in trades_by_block:
        assets_in_block = {}
        mps_xcp_btc, xcp_btc_price, btc_xcp_price = get_price_primatives(
            end_dt=t_block['block_time'])
        for t in reversed(t_block['trades']):
            assets = []
            if t['base_asset'] not in assets_in_block:
                assets.append(t['base_asset'])
                assets_in_block[t['base_asset']] = True
            if t['quote_asset'] not in assets_in_block:
                assets.append(t['quote_asset'])
                assets_in_block[t['quote_asset']] = True
            if not len(assets): continue

            for asset in assets:
                #recalculate the market cap for the asset this trade is for
                asset_info = get_asset_info(asset, at_dt=t['block_time'])
                if not asset_info: continue
                (price_summary_in_xcp, price_summary_in_btc, price_in_xcp,
                 price_in_btc, aggregated_price_in_xcp,
                 aggregated_price_in_btc) = get_xcp_btc_price_info(
                     asset,
                     mps_xcp_btc,
                     xcp_btc_price,
                     btc_xcp_price,
                     with_last_trades=0,
                     end_dt=t['block_time'])
                market_cap_in_xcp, market_cap_in_btc = calc_market_cap(
                    asset_info, price_in_xcp, price_in_btc)

                for market_cap_as in (config.XCP, config.BTC):
                    market_cap = market_cap_in_xcp if market_cap_as == config.XCP else market_cap_in_btc
                    #if there is a previously stored market cap for this asset, add a new history point only if the two caps differ
                    prev_market_cap_history = mongo_db.asset_marketcap_history.find(
                        {
                            'market_cap_as': market_cap_as,
                            'asset': asset,
                            'block_index': {
                                '$lt': t['block_index']
                            }
                        }).sort('block_index', pymongo.DESCENDING).limit(1)
                    prev_market_cap_history = list(
                        prev_market_cap_history
                    )[0] if prev_market_cap_history.count() == 1 else None

                    if market_cap and (not prev_market_cap_history
                                       or prev_market_cap_history['market_cap']
                                       != market_cap):
                        mongo_db.asset_marketcap_history.insert({
                            'block_index':
                            t['block_index'],
                            'block_time':
                            t['block_time'],
                            'asset':
                            asset,
                            'market_cap':
                            market_cap,
                            'market_cap_as':
                            market_cap_as,
                        })
                        logging.info(
                            "Block %i -- Calculated market cap history point for %s as %s (mID: %s)"
                            % (t['block_index'], asset, market_cap_as,
                               t['message_index']))

    mongo_db.app_config.update(
        {}, {'$set': {
            'last_block_assets_compiled': current_block_index
        }})
    return True