def get(self) -> Response: """Endpoint (private) provides the historical candle data for a given asset. Returns: Response -- The flask Response object. """ args = HISTORICAL_DAILY_PARSER.parse_args() asset = Asset.get_by_id(args['asset_id']) if asset is None: return abort(400, "Invalid {asset_id} given.") if args['start_date'] is None: start_date = None else: try: start_date = parser.parse(args['start_date']) except Exception: abort(400, "Invalid {start_date} given.") if args['end_date'] is None: end_date = None else: try: end_date = parser.parse(args['end_date']) except Exception: abort(400, "Invalid {end_date} given.") candles = asset.get_candles_within(start=start_date, finish=end_date, exclude_filler=True) candles_dict = [candle.as_dict() for candle in candles] return make_response(jsonify(candles_dict), 200)
def get(self) -> Response: """Endpoint (private) for providing the Google Trends data associated with an Asset. Returns: Response -- The Flask response object. """ args = TRENDS_READ_PARSER.parse_args() asset = Asset.get_by_id(args['asset_id']) if asset is None: return abort(400, "Invalid {asset_id} given.") if args['start_date'] is None: start_date = None else: try: start_date = parser.parse(args['start_date']) except Exception: abort(400, "Invalid {start_date} given.") if args['end_date'] is None: end_date = None else: try: end_date = parser.parse(args['end_date']) except Exception: abort(400, "Invalid {end_date} given.") trends = asset.get_trends(start=start_date, finish=end_date) trends_dict = [trend.as_dict() for trend in trends] return make_response(jsonify(trends_dict), 200)
def get(self) -> Response: """Endpoint (private) provides the price of a specified asset on a given day. Returns: Response -- The flask Response object. """ args = PRICING_PARSER.parse_args() asset = Asset.get_by_id(args['asset_id']) if asset is None: return abort(400, "Invalid {asset_id} given.") if args['date'] is None: return make_response(jsonify({"price": asset.get_price()}), 200) try: date = parser.parse(args['date']) except Exception: abort(400, "Invalid {date} given.") candle = asset.get_daily_candle(date.date()) if candle is None: if date.date() == datetime.utcnow().date(): return make_response(jsonify({"price": asset.get_price()}), 200) return abort( 400, "The specified {date} is outside the data available for the asset." ) return make_response(jsonify({"price": candle.get_close()}), 200)
def get(self) -> Response: """Endpoint (private) provides the performance of a specified asset over the current and previous day. Returns: Response -- The flask Response object. """ args = PERFORMANCE_DAILY_PARSER.parse_args() asset = Asset.get_by_id(args['asset_id']) if asset is None: return abort(400, "Invalid {asset_id} given.") return make_response(jsonify(asset.get_daily_performance()), 200)
def get(self) -> Response: """Endpoint (private) provides the data associated with an Asset. Returns: Response -- The flask Response object. """ args = READ_ASSET_PARSER.parse_args() asset = Asset.get_by_id(args['asset_id']) if asset is None: return abort(400, "Invalid {asset_id} given.") asset_dict = asset.as_dict() return make_response(jsonify(asset_dict), 200)
def patch(self) -> Response: """Endpoint (private) allows a User to update their profile details. Returns: Response -- The Flask response object. """ args = UPDATE_PARSER.parse_args() user = User.get_by_email(get_jwt_identity()) if user is None: return abort(401, "You are not permitted to access this endpoint.") if args['fullname'] is not None: if args['fullname'] == "": return abort(400, "Your {fullname} cannot be empty.") user.set_name(args['fullname']) if args['currency_id'] is not None: currency = Asset.get_by_id(args['currency_id']) if currency is None: return abort(400, "An invalid {currency_id} was given as a base currency.") if currency.get_asset_class() != "Currency": return abort(400, "The provided {currency_id} is not a currency.") user.set_base_currency(currency) user.save() return make_response(jsonify({"msg": "The user details have been successfully updated."}), 200)
def post(self) -> Response: """Endpoint (private) responsible for allowing a User to create a Transaction. Returns: Response -- The Flask response object. """ args = CREATE_PARSER.parse_args() user = User.get_by_email(get_jwt_identity()) if user is None: return abort(403, "You are not permitted to create a transaction.") asset = Asset.get_by_id(args['asset_id']) if asset is None: return abort(400, "Invalid {asset_id} has been specified.") try: asset_quantity = float(args['quantity']) except Exception: return abort(400, "Invalid asset {quantity} specified.") if asset_quantity <= 0: return abort(400, "The {quantity} cannot be less than or equal to 0.") try: date_purchased = parser.parse(args['date_purchased']) date_purchased = date_purchased.replace(tzinfo=None) except Exception: return abort(400, "Invalid {date_purchased} specified.") if date_purchased > datetime.utcnow(): return abort(400, "The {date_purchased} cannot be ahead of time.") purchase_candle = asset.get_daily_candle(date_purchased) if purchase_candle is None and date_purchased.date( ) != datetime.utcnow().date(): return abort( 400, "The given {date_purchased} is prior to the platform's pricing history for the asset." ) if args['price_purchased'] is None: if purchase_candle is None: price_purchased = asset.get_price() else: price_purchased = purchase_candle.get_close() else: try: price_purchased = float(args['price_purchased']) except Exception: return abort(400, "Invalid {price_purchased} given.") if price_purchased <= 0: return abort( 400, "The {price_purchased} cannot be less than or equal to 0.") if args['date_sold'] is None or args['date_sold'] == "": date_sold = None price_sold = None else: try: date_sold = parser.parse(args['date_sold']) date_sold = date_sold.replace(tzinfo=None) except Exception: return abort(400, "Invalid {date_sold} specified.") if date_sold > datetime.utcnow(): return abort(400, "The {date_sold} cannot be ahead of time.") if date_sold <= date_purchased: return abort( 400, "The {date_sold} must be further in time than the {date_purchased}." ) if args['price_sold'] is None: if date_sold.date() == datetime.utcnow().date(): price_sold = asset.get_price() else: sell_candle = asset.get_daily_candle(date_sold) if sell_candle is None: return abort( 400, "The given {date_sold} has no data for the asset in the platform's pricing history." ) price_sold = sell_candle.get_close() else: if date_sold.date() != datetime.utcnow().date(): sell_candle = asset.get_daily_candle(date_sold) if sell_candle is None: return abort( 400, "The given {date_sold} has no data for the asset in the platform's pricing history." ) try: price_sold = float(args['price_sold']) except Exception: return abort(400, "Invalid {price_sold} given.") if price_sold < 0: return abort(400, "The {price_sold} cannot be less than 0.") new_transaction = Transaction.create(user, asset, asset_quantity, date_purchased, date_sold, price_purchased, price_sold) if new_transaction is None: return abort(500, "An error occurred in creating the transaction.") return make_response( jsonify({"msg": "The transaction has been successfully created."}), 200)
def patch(self) -> Response: """Endpoint (private) responsible for updating the details of a User's Transaction. Returns: Response -- The Flask response object. """ args = UPDATE_PARSER.parse_args() transaction = Transaction.get_by_id(args['transaction_id']) if transaction is None: return abort(400, "Invalid {transaction_id} specified.") if transaction.get_user().get_email() != get_jwt_identity(): return abort(401, "You are not authorised to update this transaction.") if args['asset_id'] is not None: asset = Asset.get_by_id(args['asset_id']) if asset is None: return abort(400, "Invalid {asset_id} specified.") transaction.set_asset(asset) if args['quantity'] is not None: try: quantity = float(args['quantity']) except Exception: return abort(400, "Invalid {quantity} specified.") if quantity <= 0: return abort( 400, "The {quantity} cannot be less than or equal to 0.") transaction.set_quantity(quantity) if args['date_purchased'] is not None: try: date_purchased = parser.parse(args['date_purchased']) date_purchased = date_purchased.replace(tzinfo=None) except Exception: return abort(400, "Invalid {date_purchased} specified.") if date_purchased > datetime.utcnow(): return abort(400, "The {date_purchased} cannot be ahead of time.") purchase_candle = transaction.get_asset().get_daily_candle( date_purchased) if purchase_candle is None and (date_purchased.date() != datetime.utcnow().date()): return abort( 400, "The given {date_purchased} is prior to the platform's pricing history for the asset." ) transaction.set_buy_date(date_purchased) if args['price_purchased'] is not None: try: price_purchased = float(args['price_purchased']) except Exception: return abort(400, "Invalid {price_purchased} specified.") if price_purchased <= 0: return abort( 400, "The {price_purchased} cannot be less than or equal to 0.") transaction.set_buy_price(price_purchased) else: if args['date_purchased'] is not None: if purchase_candle is None: transaction.set_buy_price( transaction.get_asset().get_price()) else: transaction.set_buy_price(purchase_candle.get_close()) if args['date_sold'] is not None: if args['date_sold'] == "": transaction.set_sell_date(None) transaction.set_sell_price(None) else: try: date_sold = parser.parse(args['date_sold']) date_sold = date_sold.replace(tzinfo=None) except Exception: return abort(400, "Invalid {date_sold} specified.") if date_sold > datetime.utcnow(): return abort(400, "The {date_sold} cannot be ahead of time.") if date_sold <= transaction.get_buy_date(): return abort( 400, "The {date_sold} must be further ahead in time than the {date_purchased}." ) sell_candle = transaction.get_asset().get_daily_candle( date_sold) if sell_candle is None and date_sold.date() != datetime.utcnow( ).date(): return abort( 400, "The given {date_sold} is outside the platform's pricing history for the asset." ) transaction.set_sell_date(date_sold) if args['price_sold'] is not None: if transaction.get_sell_date() is None: return abort( 400, "The {price_sold} field cannot be set while {date_sold} hasn't been set." ) try: price_sold = float(args['price_sold']) except Exception: return abort(400, "Invalid {price_sold} specified.") if price_sold < 0: return abort(400, "The {price_sold} cannot be less than 0.") transaction.set_sell_price(price_sold) else: if transaction.get_sell_date() is not None: if date_sold.date() == datetime.utcnow().date(): transaction.set_sell_price( transaction.get_asset().get_price()) else: sell_candle = transaction.get_asset().get_daily_candle( date_sold) if sell_candle is None: return abort( 400, "The given {date_sold} has no data for the asset in the platform's pricing history." ) transaction.set_sell_price(sell_candle.get_close()) transaction.save() user = transaction.user.fetch() user.set_portfolio_historical(None) user.save() return make_response( jsonify({"msg": "The transaction was successfully updated."}), 200)