def post(self, color: int): millis, ts = utils.get_utc_timestamp() msgs = [] success = False return_code = 403 dim = constants.CANVAS_DIMENSION batch = fs.initializeBatch() cells = [] for row in range(dim): for col in range(dim): cell_id = 'row{}col{}'.format(row, col) cell_data = {'updated': millis, 'value': color} fs.updateMatrixCellBatched(batch, cell_id, cell_data) cells.append(cell_data) fs.commitBatch(batch) success = True response_obj = {'timestamp': millis, 'msgs': msgs, 'success': success} if success: return_code = 200 return response_obj, return_code
def get(self, row: int): millis, ts = utils.get_utc_timestamp() msgs = [] success = False return_code = 403 matrix = fs.getMatrix(row) if matrix is not None: indicators = [] for cell in matrix: indicators.append(cell) success = True response_obj = {'timestamp': millis, 'msgs': msgs, 'success': success} if success: return_code = 200 response_obj.update({ 'matrix': indicators }) return response_obj, return_code
def update_participant(event): """ Update a participant's name and/or url :param event: Lambda event containing the API Gateway request body including updated name or url and the path parameters wheel_id and participant_id { "pathParameters": { "wheel_id": string ID of the wheel (DDB Hash Key) "participant_id": string ID of the participant (DDB Hash Key) }, "body": { "id": string ID of the participant (DDB Hash Key), "name": string name of the wheel (optional), "url: Valid URL for the participant (optional), } } :return: response dictionary containing the updated participant object if successful { "body": { "id": string ID of the participant (DDB Hash Key), "wheel_id": string ID of the wheel (DDB Hash Key), "name": string name of the wheel, "url: URL for the participant, "created_at": creation timestamp, "updated_at": updated timestamp, } } """ wheel_id = event['pathParameters']['wheel_id'] participant_id = event['pathParameters']['participant_id'] # Check that the participant exists participant = WheelParticipant.get_existing_item(Key={ 'id': participant_id, 'wheel_id': wheel_id }) body = event['body'] params = {'updated_at': get_utc_timestamp()} if not check_string(body.get('name', 'Not Specified')) or not check_string( body.get('url', 'Not Specified')): raise base.BadRequestError( "Participants names and urls must be at least 1 character in length" ) if 'name' in body: params['name'] = body['name'] if 'url' in body: params['url'] = body['url'] WheelParticipant.update_item(Key={ 'id': participant_id, 'wheel_id': wheel_id }, **to_update_kwargs(params)) participant.update(params) return participant
def create_genesis_block(self): """ A function to generate genesis block and appends it to the chain. The block has index 0, previous_hash as 0, and a valid hash. """ genesis_block = Block(0, [], get_utc_timestamp(), "0") self.proof_of_work(genesis_block) self.chain.append(genesis_block.__str__())
def create_participant(event): """ Create a participant :param event: Lambda event containing the API Gateway request body including a name and a url and the path parameter wheel_id { "pathParameters": { "wheel_id": string ID of the wheel (DDB Hash Key) }, "body": { "name": participant name string, "url: Valid URL for the participant, } } :return: response dictionary containing new participant object if successful { "body": { "id": string ID of the participant (DDB Hash Key), "wheel_id": string ID of the wheel (DDB Hash Key), "name": string name of the wheel, "url: URL for the participant, "created_at": creation timestamp, "updated_at": updated timestamp, } } """ wheel_id = event['pathParameters']['wheel_id'] body = event['body'] if not check_string(body.get('name', None)) or not check_string( body.get('url', None)): raise base.BadRequestError( "Participants require a name and url which must be at least 1 character in length" ) wheel = Wheel.get_existing_item(Key={'id': wheel_id}) create_timestamp = get_utc_timestamp() participant = { 'wheel_id': wheel_id, 'id': get_uuid(), 'name': body['name'], 'url': body['url'], 'created_at': create_timestamp, 'updated_at': create_timestamp, } with choice_algorithm.wrap_participant_creation(wheel, participant): WheelParticipant.put_item(Item=participant) return participant
def root(): millis, ts = utils.get_utc_timestamp() msgs = [] success = False return_code = 403 msgs.append('forbidden') response_obj = {'timestamp': millis, 'msgs': msgs, 'success': success} response = jsonify(response_obj) return response, return_code
def post(self): millis, ts = utils.get_utc_timestamp() msgs = [] success = False return_code = 403 dim = 5 batch = fs.initializeBatch() order_to_be_read = 0 cells = [] for row in range(dim): for col in range(dim): cell_id = 'row{}col{}'.format(row, col) cell_data = { 'created': millis, 'updated': millis, 'id': cell_id, 'position': order_to_be_read, 'row': row, 'col': col, 'value': 0 } fs.setMatrixCellBatched(batch, cell_id, cell_data) cells.append(cell_data) order_to_be_read += 1 fs.commitBatch(batch) success = True response_obj = {'timestamp': millis, 'msgs': msgs, 'success': success} if success: return_code = 200 response_obj.update({ 'matrix': cells }) return response_obj, return_code
def send_message(): try: if request.method == 'GET': return render_template('./sendmessage.html', title="Send Message") elif request.method == 'POST': values = request.form # Check that the required fields are in the POST'ed data required = ['sender', 'private_key', 'message'] if not all(values[k] != "" for k in required): return 'Missing values', 400 sender = values['sender'] sender_private_key = values['private_key'] user = users.get_user(sender) if user == "Username does not exist": return user, 400 sender_public_key = user['public_key'] msg = Message(user["username"], user['name'], values["message"], get_utc_timestamp()) # Create a new Transaction signature = blockchain.sign_transaction(sender_private_key, msg.__str__()) if len(signature) == 2: return signature[0], 400 transaction_result = blockchain.submit_transaction( sender, sender_public_key, msg.__str__(), signature) if not transaction_result: return 'Invalid Transaction!', 406 else: response = { 'message': 'Transaction will be added to Block ' + str(transaction_result), 'signature': signature } return jsonify(response), 200 except Exception as e: return "Error in format", 400
def update_wheel(event): """ Update the name of the wheel and/or refresh its participant count :param event: Lambda event containing the API Gateway request path parameter wheel_id { "pathParameters": { "wheel_id": string ID of the wheel (DDB Hash Key) }, "body": { "id": string ID of the wheel (DDB Hash Key), "name": string name of the wheel, } } :return: response dictionary containing the updated wheel object if successful { "body": { "id": string ID of the wheel (DDB Hash Key), "name": string name of the wheel, "participant_count": number of participants in the wheel, "created_at": creation timestamp, "updated_at": updated timestamp, } } """ wheel_id = event['pathParameters']['wheel_id'] key = {'id': wheel_id} # Make sure wheel exists wheel = Wheel.get_existing_item(Key=key) name = event['body'].get('name', None) if not check_string(name): raise base.BadRequestError( "Updating a wheel requires a new name of at least 1 character in length" ) update = {'name': name, 'updated_at': get_utc_timestamp()} Wheel.update_item(Key=key, **to_update_kwargs(update)) # Represent the change locally for successful responses wheel.update(update) return wheel
def mine(self): """ This function serves as an interface to add the pending transactions to the blockchain by adding them to the block and figuring out Proof Of Work. """ if not self.unconfirmed_transactions: return False last_block = json.loads(self.last_block) new_block = Block(index=last_block['index'] + 1, transactions=self.unconfirmed_transactions, timestamp=get_utc_timestamp(), previous_hash=Block.compute_hash(last_block)) proof = self.proof_of_work(new_block) self.add_block(new_block, proof) self.unconfirmed_transactions = [] return new_block.index
def post(self, row: int, col: int, color: int): millis, ts = utils.get_utc_timestamp() msgs = [] success = False return_code = 403 time.sleep(constants.DELAY_IN_SECS) cell_id = 'row{}col{}'.format(row, col) cell_data = {'updated': millis, 'value': color} fs.updateMatrixCell(cell_id, cell_data) success = True response_obj = {'timestamp': millis, 'msgs': msgs, 'success': success} if success: return_code = 200 return response_obj, return_code
def submit_transaction(self, sender_username, sender_address, data, signature): """ Add a transaction to transactions array if the signature verified """ transaction = OrderedDict({ 'sender_username': sender_username, 'sender_address': sender_address, 'data': data, 'timestamp': get_utc_timestamp() }) transaction_verification = self.verify_transaction_signature( sender_address, signature, data) if transaction_verification: self.unconfirmed_transactions.append(transaction) return len(self.chain) + 1 else: return False
def create_wheel(event): """ Create a wheel. Requires a name :param event: Lambda event containing the API Gateway request body including a name { "body": { "name": string wheel name, } } :return: response dictionary containing new wheel object if successful { "body": { "id": string ID of the wheel (DDB Hash Key), "name": string name of the wheel, "participant_count": number of participants in the wheel, "created_at": creation timestamp, "updated_at": updated timestamp, } } """ create_timestamp = get_utc_timestamp() body = event['body'] if body is None or not check_string(body.get('name', None)): raise base.BadRequestError( f"New wheels require a name that must be a string with a length of at least 1. Got: {body}" ) wheel = { 'id': get_uuid(), 'name': body['name'], 'created_at': create_timestamp, 'updated_at': create_timestamp, } with choice_algorithm.wrap_wheel_creation(wheel): Wheel.put_item(Item=wheel) return wheel
def plot_rolling_returns(returns, factor_returns=None, live_start_date=None, cone_std=None, legend_loc='best', volatility_match=False, cone_function=ts_metrics.forecast_cone_bootstrap, ax=None, **kwargs): """ Plots cumulative rolling returns versus some benchmarks'. Backtest returns are in green, and out-of-sample (live trading) returns are in red. Additionally, a non-parametric cone plot may be added to the out-of-sample returns region. Parameters ---------- returns : pd.Series Daily returns of the strategy, noncumulative. factor_returns : pd.Series, optional Daily noncumulative returns of a risk factor. - This is in the same style as returns. live_start_date : datetime, optional The date when the strategy began live trading, after its backtest period. This date should be normalized. cone_std : float, or tuple, optional If float, The standard deviation to use for the cone plots. If tuple, Tuple of standard deviation values to use for the cone plots - See timeseries.forecast_cone_bounds for more details. legend_loc : matplotlib.loc, optional The location of the legend on the plot. volatility_match : bool, optional Whether to normalize the volatility of the returns to those of the benchmark returns. This helps compare strategies with different volatilities. Requires passing of benchmark_rets. cone_function : function, optional Function to use when generating forecast probability cone. The function signiture must follow the form: def cone(in_sample_returns (pd.Series), days_to_project_forward (int), cone_std= (float, or tuple), starting_value= (int, or float)) See ts_metrics.forecast_cone_bootstrap for an example. ax : matplotlib.Axes, optional Axes upon which to plot. **kwargs, optional Passed to plotting function. Returns ------- ax : matplotlib.Axes The axes that were plotted on. """ if ax is None: ax = plt.gca() if volatility_match and factor_returns is None: raise ValueError('volatility_match requires passing of' 'factor_returns.') elif volatility_match and factor_returns is not None: bmark_vol = factor_returns.loc[returns.index].std() returns = (returns / returns.std()) * bmark_vol cum_rets = ts_metrics.cum_returns(returns, 1.0) y_axis_formatter = FuncFormatter(utils.one_dec_places) ax.yaxis.set_major_formatter(FuncFormatter(y_axis_formatter)) if factor_returns is not None: cum_factor_returns = ts_metrics.cum_returns( factor_returns[cum_rets.index], 1.0) cum_factor_returns.plot(lw=2, color='gray', label=factor_returns.name, alpha=0.60, ax=ax, **kwargs) if live_start_date is not None: live_start_date = utils.get_utc_timestamp(live_start_date) is_cum_returns = cum_rets.loc[cum_rets.index < live_start_date] oos_cum_returns = cum_rets.loc[cum_rets.index >= live_start_date] else: is_cum_returns = cum_rets oos_cum_returns = pd.Series([]) is_cum_returns.plot(lw=3, color='forestgreen', alpha=0.6, label='Backtest', ax=ax, **kwargs) if len(oos_cum_returns) > 0: oos_cum_returns.plot(lw=4, color='red', alpha=0.6, label='Live', ax=ax, **kwargs) if cone_std is not None: if isinstance(cone_std, (float, int)): cone_std = [cone_std] is_returns = returns.loc[returns.index < live_start_date] cone_bounds = cone_function( is_returns,len(oos_cum_returns), cone_std=cone_std, starting_value=is_cum_returns[-1]) cone_bounds = cone_bounds.set_index(oos_cum_returns.index) for std in cone_std: ax.fill_between(cone_bounds.index, cone_bounds[float(std)], cone_bounds[float(-std)], color='steelblue', alpha=0.5) if legend_loc is not None: ax.legend(loc=legend_loc) ax.axhline(1.0, linestyle='--', color='black', lw=2) ax.set_ylabel('Cumulative returns') ax.set_xlabel('') return ax
def post(self): millis, ts = utils.get_utc_timestamp() msgs = [] success = False return_code = 403 body = request.json if body is not None and 'paint' in body: colors = [] start_painting_at = body[ 'start_painting_at'] if 'start_painting_at' in body else 0 start_posteffects_at = body[ 'start_posteffects_at'] if 'start_posteffects_at' in body else 0 next_posteffect_at = body[ 'next_posteffect_at'] if 'next_posteffect_at' in body else 0 unreliable = body['unreliable'] if 'unreliable' in body else None unreliable_prob = body[ 'unreliable_probability'] if 'unreliable_probability' in body else None unreliable_fill = body[ 'unreliable_fill'] if 'unreliable_fill' in body else None if 'fill' in body: payload = {'action': 'fill', 'value': body['fill']} if unreliable_fill is not None: payload.update({ 'unreliable': unreliable_fill, 'probability': unreliable_prob }) utils.postCloudTask(constants.PAINTER_QUEUE, '/matrix/task', payload=payload, start_in=0) cells = body['paint'] for row, cols in enumerate(cells): for col, value in enumerate(cols): colors.append(value) if 'delay' in body: delay = body['delay'] else: delay = constants.DELAY_IN_SECS payload = { 'action': 'paint', 'row': row, 'col': col, 'value': value } if unreliable is not None: payload.update({ 'unreliable': unreliable, 'probability': unreliable_prob }) if delay > 0: utils.postCloudTask( constants.PAINTER_QUEUE, '/matrix/delayedtask/{}'.format(delay), payload=payload, start_in=start_painting_at) else: utils.postCloudTask(constants.PAINTER_QUEUE, '/matrix/task', payload=payload, start_in=start_painting_at) if 'posteffects' in body: start_at = start_posteffects_at posteffects = body['posteffects'] for effect in posteffects: payload = {'action': 'posteffect', 'effect': effect} utils.postCloudTask(constants.PAINTER_QUEUE, '/matrix/task', payload=payload, start_in=start_at) start_at += next_posteffect_at success = True response_obj = {'timestamp': millis, 'msgs': msgs, 'success': success} if success: return_code = 200 response_obj.update({'colors': colors}) return response_obj, return_code
def post(self, **kwargs): millis, ts = utils.get_utc_timestamp() msgs = [] success = False return_code = 403 if 'delay' in kwargs: delay = kwargs['delay'] msg = 'applying a delay of {}s'.format(delay) logging.warning(msg) msgs.append(msg) time.sleep(delay) payload = request.get_data(as_text=True) or None if payload is not None: payload = json.loads(payload) # print(payload) action = payload['action'] probability = 100 - payload[ 'probability'] if 'probability' in payload else constants.DEFAULT_PROBABILITY if probability > 100: probability = 100 if probability < 0: probability = 0 unreliable = random.randint( 0, 100) > probability if 'unreliable' in payload and payload[ 'unreliable'] else False label = '?' if unreliable else '' if unreliable: msg = '{} UNRELIABLE'.format(action) logging.warning(msg) msgs.append(msg) if action == 'posteffect' and payload['effect'] == 'b&w': dim = constants.CANVAS_DIMENSION matrix = fs.getMatrixAll() if matrix is not None: batch = fs.initializeBatch() cells = [] for row in range(dim): for col in range(dim): # TODO: use position! color = matrix[dim * row + col]['value'] if color >= 0: if unreliable: color = constants.LUT_LENGTH - color if color == 5: color = 4 # due to inverse of 5 being 5 color += 100 cell_id = 'row{}col{}'.format(row, col) cell_data = { 'updated': millis, 'label': label, 'value': color } fs.updateMatrixCellBatched( batch, cell_id, cell_data) cells.append(cell_data) fs.commitBatch(batch) success = True else: msg = 'matrix is null' logging.error(msg) msgs.append(msg) if (action == 'invert_fill') or (action == 'posteffect' and payload['effect'] == 'invert'): dim = constants.CANVAS_DIMENSION matrix = fs.getMatrixAll() if matrix is not None: batch = fs.initializeBatch() cells = [] for row in range(dim): for col in range(dim): # TODO: use position! color = matrix[dim * row + col]['value'] if color >= 0: color = constants.LUT_LENGTH - color if unreliable: color = constants.LUT_LENGTH - color if color == 5: color = 4 # due to inverse of 5 being 5 cell_id = 'row{}col{}'.format(row, col) cell_data = { 'updated': millis, 'label': label, 'value': color } fs.updateMatrixCellBatched( batch, cell_id, cell_data) cells.append(cell_data) fs.commitBatch(batch) success = True else: msg = 'matrix is null' logging.error(msg) msgs.append(msg) if action == 'fill': color = payload['value'] if color >= 0 and unreliable: color = constants.LUT_LENGTH - color if color == 5: color = 4 # due to inverse of 5 being 5 dim = constants.CANVAS_DIMENSION batch = fs.initializeBatch() cells = [] for row in range(dim): for col in range(dim): if color >= 0: cell_id = 'row{}col{}'.format(row, col) cell_data = { 'updated': millis, 'label': label, 'value': color } fs.updateMatrixCellBatched(batch, cell_id, cell_data) cells.append(cell_data) fs.commitBatch(batch) success = True if action == 'paint': color = payload['value'] row = payload['row'] col = payload['col'] if color >= 0: if unreliable: color = constants.LUT_LENGTH - color if color == 5: color = 4 # due to inverse of 5 being 5 cell_id = 'row{}col{}'.format(row, col) cell_data = { 'updated': millis, 'label': label, 'value': color } fs.updateMatrixCell(cell_id, cell_data) print('{} -> {}'.format(cell_id, color)) success = True if action == 'invert': row = payload['row'] col = payload['col'] cell = fs.getMatrixByCoords(row, col) if cell is not None: color = cell[0]['value'] if color >= 0: color = constants.LUT_LENGTH - color if unreliable: color = constants.LUT_LENGTH - color cell_id = 'row{}col{}'.format(row, col) cell_data = { 'updated': millis, 'label': label, 'value': color } fs.updateMatrixCell(cell_id, cell_data) success = True else: msg = 'unable to read cell at {},{}'.format(row, col) logging.error(msg) msgs.append(msg) response_obj = {'timestamp': millis, 'msgs': msgs, 'success': success} if success: return_code = 200 if unreliable: return_code = 404 return response_obj, return_code