社区首页 >问答首页 >使用熊猫和matplotlib的Python外汇模拟器

使用熊猫和matplotlib的Python外汇模拟器
EN

Code Review用户
提问于 2020-01-02 20:55:35
回答 1查看 709关注 0票数 2

描述:

这将使货币交换模拟器的第一部分--第一阶段--从histdata.com api下载货币历史数据,使用不同的地块类型绘制给定的时间段和给定的时间框架,并在数据中添加一些外汇技术指标。我将张贴跟进,当我完成了进一步的阶段的项目。

反馈:

我需要关于整个程序结构的反馈,并欢迎为改进/优化/特性添加的一般建议。我打算添加一个虚拟货币的模拟功能,并自动化一个运行在历史数据上的机器人,它可以预测未来的价值,最大化利润,或者是一个GUI。我还需要一些建议,预测未来某一时期的未来值,使用机器学习,我不知道,也许是神经网络-回归- nlp。我需要关于焦点的指导(什么库/技术.)建立一个强大的机器学习预测系统,因为我在毫升方面不是很有经验。

链接:

请下载以下压缩文件,并将内容(以“DAT”开头的两个文件夹)解压到与代码相同的文件夹中(以便能够在eurusd对的期间(2017-2018年)运行模拟器):

2017-2018年年欧元M1(1分钟数据)

文件

  • forex_data_handler.py:它用于从histdata.com api下载外汇历史数据(如果您要下载额外的数据,请先使用pip3安装组数据),这是可选的(上面提供的链接用于最小化试运行),当然可以随意下载任何您想要的数据,使用这个模块来尝试额外的示例。
  • fx_simulator.py:这是代码的模拟部分,因为它是项目的第一部分,它包含以下特性:( A) FxSimulator构造函数接受诸如货币对、年份和一些其他参数(您可以在docstring中找到一切) get_interval()方法,它返回特定的时间框架熊猫DF。M1 =1 min,D5 =5天。查一下文件。C) compare_years()compare_year_months()方法,以便能够使用intervalcomparison_value等参数进行月份和年份间的比较。( D)用plot_initial_data()方法绘制历史数据(离散、线、直方图)。( E) add_indicators()法向熊猫df中添加外汇技术指标值。指标包括(Bollinger带,RSI,移动平均.)
  • pairs.txt:包含一个从histdata.com api下载数据(可选)时可以选择的66个不同货币对的列表。

示例图:

  • 2010-2018年期间欧元兑美元1天收盘(D1)年比较(1图):
  • 2010-2018年期间欧元兑美元1天结束(D1)年比较(多个地块):
  • 2019个月与欧元兑美元收盘日(D1)移动平均线(14天)比较
  • 2019年欧元关闭1天(D1)的季节性分解

forex_data_handler.py

代码语言:javascript
代码运行次数:0
复制
from histdata import download_hist_data
from concurrent.futures import ThreadPoolExecutor, as_completed
from time import perf_counter
import os


def get_folder_name(year, platform, time_frame, pair, month=None, compressed=True):
    """
    Produce folder name in histdata.com download format.
    Args:
        year: ex: 2010
        platform: MT, ASCII, XLSX, NT, MS.
        time_frame: M1 (one minute) or T (tick data).
        pair: ex: 'eurgbp'
        month: int range(1, 12) inclusive
        compressed: If compressed, a folder name ending with '.zip' is returned
    """
    if not month:
        folder_name = '_'.join(['DAT', platform, pair.upper(), time_frame, str(year)])
        if compressed:
            return folder_name + '.zip'
        else:
            return folder_name
    if month and month <= 9:
        month = '0' + str(month)
    folder_name = '_'.join(['DAT', platform, pair.upper(), time_frame, str(year) + str(month)])
    if compressed:
        return folder_name + '.zip'
    if not compressed:
        return folder_name


def download_fx_data(start_year, end_year, pairs, threads=50, time_frame='M1', platform='MT', output_directory='.',
                     current_year=2019, current_month=12):
    """
    Download Forex data over a given time range from histdata api.
    Args:
        start_year: int: The starting year.
        end_year: int: The ending year.
        pairs: A list of pairs ex: ['eurgbp', 'eurusd']
        threads: Number of parallel threads.
        time_frame: M1 (one minute) or T (tick data).
        platform: MT, ASCII, XLSX, NT, MS.
        output_directory: Where to dump the data.
        current_year: Current year.
        current_month: Current month.
    """
    month_pairs = []
    if end_year >= current_year:
        last_year = current_year - 1
    else:
        last_year = end_year
    years_pairs = [(year, pair) for year in range(start_year, last_year + 1) for pair in pairs
                   if get_folder_name(year, platform, time_frame, pair) not in os.listdir(output_directory)]
    if end_year >= current_year:
        month_pairs.extend([(month, pair) for pair in pairs for month in range(1, current_month)
                            if get_folder_name(current_year, platform, time_frame, pair, month)
                            not in os.listdir(output_directory)])
    with ThreadPoolExecutor(max_workers=threads) as executor:
        future_years_data = {executor.submit(download_hist_data, str(year), None, pair, time_frame,
                                             platform, output_directory): (year, pair) for year, pair in years_pairs}
        future_months_data = {executor.submit(download_hist_data, str(current_year), str(month), pair, time_frame,
                                              platform, output_directory): (month, pair) for month, pair in month_pairs}
        for future_file in as_completed(future_years_data):
            try:
                future_file.result()
            except AssertionError:
                print(f'Failure to retrieve {future_years_data[future_file]}')
        for future_file in as_completed(future_months_data):
            try:
                future_file.result()
            except AssertionError:
                print(f'Failure to retrieve {future_months_data[future_file]}')


if __name__ == '__main__':
    start_time = perf_counter()
    # Change the next line for specific choices, this is set to download all the data available.
    # pair_list = [pair.rstrip() for pair in open('pairs.txt').readlines()]
    # download_fx_data(2000, 2020, pair_list)
    end_time = perf_counter()
    print(f'Process finished ... {end_time - start_time} seconds.')

fx_simulator.py

代码语言:javascript
代码运行次数:0
复制
from statsmodels.tsa.seasonal import seasonal_decompose
from forex_data_handler import get_folder_name
import matplotlib.pyplot as plt
import pandas as pd
import os


class FxSimulator:
    """A tool for conducting forex backtesting and simulation."""
    def __init__(self, pair, years, history_data_path='.', platform='MT', time_frame='M1', current_year=2019,
                 current_month=12):
        """
        Initialize year data.
        Args:
            pair: A string of currency pair ex: 'eurusd'
            years: a list of years.
            history_data_path: Folder path containing the historical data.
            platform: MT, ASCII, XLSX, NT, MS.
            time_frame: M1 or T
            current_year: Current year ex: 2019
            current_month: Current month ex: 8
        """
        not_supported_years = [yr for yr in years if yr not in range(2000, current_year + 1) or yr > current_year]
        if not_supported_years:
            raise ValueError(f'Invalid year {not_supported_years[0]}'
                             f'\nYears supported are in range 2000-current year.')
        self.currency_pair = pair
        self.years = years
        self.path = history_data_path
        self.platform = platform
        self.time_frame = time_frame
        self.current_year = current_year
        self.current_month = current_month
        self.column_names = {'M1': ['Date', 'Time', 'Open', 'High', 'Low', 'Close', 'Volume']}

    def combine_frames(self, folders, sep=','):
        """
        Combine folder data.
        Args:
            folders: A list of folders.
            sep: Separator of the csv file.
        Return:
            A data frame of all folders combined.
        """
        frames = []
        for folder_name in folders:
            try:
                os.chdir(self.path + folder_name)
                current_frame = pd.read_csv(folder_name + '.csv', sep=sep, names=self.column_names[self.time_frame],
                                            parse_dates=True)
                frames.append(current_frame)
            except FileNotFoundError:
                print(f'Folder: {folder_name} not found.')
        if frames:
            return pd.concat(frames)

    def load_data(self, sep=',', year=None):
        """
        Load data of the given year range from csv.
        Args:
            sep: Separator of the csv file.
            year: To load a particular year data.
        Return:
            A data frame with the following columns (check self.column_names)
        """
        current_year_month_folders = [get_folder_name(
            self.current_year, self.platform, self.time_frame, self.currency_pair, month, False)
            for month in range(1, self.current_month)]
        if year:
            if year not in self.years:
                raise ValueError(f'Year {year} not included in self.years')
            if year != self.current_year:
                folder_name = get_folder_name(year, self.platform, self.time_frame, self.currency_pair, None, False)
                return self.combine_frames([folder_name], sep)
            if year == self.current_year:
                return self.combine_frames(current_year_month_folders, sep)
        folder_names = [get_folder_name(yr, self.platform, self.time_frame, self.currency_pair, None, False)
                        for yr in self.years if yr != self.current_year]
        if self.current_year in self.years:
            folder_names.extend(current_year_month_folders)
        return self.combine_frames(folder_names, sep)

    def get_interval(self, interval, year=None, day_timing='12:30'):
        """
        Set desired interval.
        Args:
            interval:
                'M' + Minute interval(int 1 - 60) ex: M15 --> 15 minute interval.
                'H' + Hour interval(int 1  - 24) ex: H4 --> 4 hour interval.
                'D' + Day interval(int 1 - 31) ex: D1 --> 1 day interval.
                'W' + Week interval(int 1 - 4)
            year: If year, interval of the year will be returned.
            day_timing: Timing of the day to get intervals.
        Return:
             Adjusted data frame.
        """
        if year:
            period_data = self.load_data(year=year)
        else:
            period_data = self.load_data()
        if 'M' in interval:
            current_minutes = period_data['Time'].apply(lambda timing: int(timing.split(':')[-1]))
            return period_data[current_minutes % int(interval[1:]) == 0]
        if 'H' in interval:
            hour_data = period_data[period_data['Time'].apply(lambda timing: timing.split(':')[-1] == '00')]
            only_hours = hour_data['Time'].apply(lambda timing: int(timing.split(':')[0]))
            valid_hours = only_hours % int(interval[1:]) == 0
            return hour_data[valid_hours]
        if 'D' in interval:
            day_data = period_data[period_data['Time'] == day_timing]
            day_only = day_data['Date'].apply(lambda timing: int(timing.split('.')[-1]))
            return day_data[day_only % int(interval[1:]) == 0]
        if 'W' in interval:
            week_data = period_data[period_data['Date'].apply(lambda timing: int(timing.split('.')[-1]) % 7) == 0]
            valid_weeks = week_data[week_data['Date'].apply(lambda timing:
                                                            int(timing.split('.')[-1]) % int(interval[1:])) == 0]
            return valid_weeks[valid_weeks['Time'] == day_timing]
        raise ValueError(f'Invalid interval: {interval}')

    def compare_years(self, interval, comparison_value):
        """
        Get A monthly indexed data for years in self.years.
        Args:
            interval: Period string indication ex: 'M1', 'D5' ...
            comparison_value: A string indication of value to compare: ex: 'Open', Close ...
        Return:
            A data frame containing year data per month.
        """
        frames = []
        for year in self.years:
            data = self.get_interval(interval, year)
            data['Month'] = data['Date'].apply(lambda timing: timing.split('.')[1])
            data.reset_index(drop=True, inplace=True)
            frames.append(data)
        all_years = pd.concat(frames, axis=1).dropna()
        all_years.set_index('Month', inplace=True)
        all_years.reset_index(inplace=True)
        all_years['Month'] = all_years['Month'].apply(lambda months: set(months).pop())
        years_data = all_years[['Month', comparison_value]]
        years_data.columns = ['Month'] + [comparison_value + '(' + str(yr) + ')' for yr in self.years]
        return years_data

    def compare_year_months(self, year, interval):
        """
        Get A certain year months.
        Args:
            year: A year specified in self.years
            interval: Period string indication ex: 'M1', 'D5' ...
        Return:
             A data frame containing months of a certain year.
        """
        if year not in self.years:
            raise ValueError(f'Year {year} not included in self.years')
        year_data = self.get_interval(interval, year)
        year_data['Month'] = year_data['Date'].apply(lambda timing: timing.split('.')[1])
        return year_data

    def plot_initial_data(self, plot_type, interval, year=None, years=False, comparison_value=None,
                          moving_average=None, **kwargs):
        """
        Plot initial data in several graph forms.
        Args:
            plot_type: A string indication to graph type.
                - li: Line plot.
                - h: Histogram.
                - bw: Box & whiskers plot.
                - lp: Lag plot.
                - ac: Auto-correlation plot.
                - sda: Additive Seasonal decompose(Observed-Trend-Seasonal-Residual).
                - sdm: Multiplicative Seasonal decompose(Observed-Trend-Seasonal-Residual).
            interval: Period string indication ex: 'M1', 'D5' ...
            year: If True, only months of given year will be plotted.
            years: If True, years will be compared.
            comparison_value: If years, this would be a string indication of value to compare against
            ('Open', Close ...)
            moving_average: int representing the moving average window to be displayed (works when a comparison
            value is specified).
            **kwargs: Additional keyword arguments.
        Return:
            None
        """
        if years and not comparison_value:
            raise ValueError(f'Comparison value not specified for years=True')
        if year and years:
            raise ValueError(f'Cannot compare a single year and all years, please specify year or years')
        if moving_average and not comparison_value:
            raise ValueError(f'Comparison value not specified for moving average {moving_average}')
        if plot_type in ['sda', 'sdm'] and not comparison_value:
            raise ValueError(f'Must specify a comparison value for seasonal decomposition')
        period_data = pd.DataFrame()
        if not year and not years:
            period_data = self.get_interval(interval)
            period_data.set_index('Date', inplace=True)
            if comparison_value:
                period_data = period_data.filter(like=comparison_value)
                if moving_average:
                    period_data['Moving Average'] = period_data[comparison_value].rolling(moving_average).mean()
        if years:
            period_data = self.compare_years(interval, comparison_value)
            period_data.set_index('Month', inplace=True)
            if moving_average:
                for column in period_data.columns:
                    if comparison_value in column:
                        period_data['MA ' + column] = period_data[column].rolling(moving_average).mean()
        if year:
            period_data = self.compare_year_months(year, interval)
            period_data.set_index('Month', inplace=True)
            if comparison_value:
                period_data = period_data.filter(like=comparison_value)
                if moving_average:
                    period_data['Moving Average'] = period_data[comparison_value].rolling(moving_average).mean()
        if plot_type == 'li':
            period_data.plot(**kwargs)
        if plot_type == 'h':
            period_data.hist(**kwargs)
        if plot_type == 'bw':
            period_data.boxplot(**kwargs)
        if plot_type == 'sda':
            result = seasonal_decompose(period_data.filter(like=comparison_value), model='additive', freq=1)
            result.plot()
        if plot_type == 'sdm':
            result = seasonal_decompose(period_data.filter(like=comparison_value), model='multiplicative', freq=1)
            result.plot()
        plt.show()

    def add_indicators(self, interval, indicators, significant_value='Close', year=None, day_timing='12:30',
                       rsi_period=14, si_period=14, bb_period=20, kn_period=9, kj_period=26, fast_ema=12,
                       slow_ema=26, signal_line=9, adx_period=14):
        """
        Add Forex technical indicators for the specified interval.
        Args:
            interval:
                'M' + Minute interval(int 1 - 60) ex: M15 --> 15 minute interval.
                'H' + Hour interval(int 1  - 24) ex: H4 --> 4 hour interval.
                'D' + Day interval(int 1 - 31) ex: D1 --> 1 day interval.
                'W' + Week interval(int 1 - 4).
            indicators: A list of Technical indicators including:
                - 'rsi': Relative strength indicator(RSI).
                - 'si': Stochastic oscillator indicator(SI).
                - 'bb': Bollinger Bands indicator.
                - 'ic': Ichimoku Cloud.
                - 'macd': Moving Average Convergence Divergence(MACD).
                - 'pp': Pivot Point.
                - 'adx': Average Directional movement(ADX)
            significant_value: Close - Open - High - Low.
            year: If year, interval of the year will be returned.
            day_timing: Timing of the day to get intervals.
            rsi_period: Period of averaging for the relative strength(RSI) indicator.
            si_period: Period of averaging for the stochastic indicator(SI).
            bb_period: Period of averaging for the Bollinger Bands indicator.
            kn_period: Period of averaging for the Ichimoku Cloud indicator(Kenkan-Sen).
            kj_period: Period of averaging for the Ichimoku Cloud indicator(Kijun Sen).
            fast_ema: Period of exponential moving average(12 days)
            slow_ema: Period of exponential moving average(26 days)
            signal_line: MACD signal line.
            adx_period: Average True Range(ATR) period.
        Return:
             Data frame with the adjusted technical indicators.
        """
        period_data = self.get_interval(interval, year, day_timing).reset_index(drop=True)
        if 'rsi' in indicators:
            period_data['Change'] = period_data[significant_value] - period_data[significant_value].shift(1)
            period_data['Upward Movement'] = period_data['Change'].apply(lambda change: change if change > 0 else 0)
            period_data['Downward Movement'] = period_data['Change'].apply(lambda change: abs(change)
                                                                           if change < 0 else 0)
            period_data['Average Upward Movement'] = period_data['Upward Movement'].rolling(rsi_period).mean()
            period_data['Average Downward Movement'] = period_data['Downward Movement'].rolling(rsi_period).mean()
            period_data['Relative Strength(RS)'] = (period_data['Average Upward Movement']
                                                    / period_data['Average Downward Movement'])
            period_data['Relative Strength Index(RSI)'] = 100 - (100 / (1 + period_data['Relative Strength(RS)']))
        if 'si' in indicators:
            period_data['Lowest Low'] = period_data['Low'].rolling(si_period).min()
            period_data['Highest High'] = period_data['High'].rolling(si_period).max()
            period_data['Stochastic Oscillator Index'] = 100 * (period_data['Close'] - period_data['Lowest Low']) / (
                    period_data['Highest High'] - period_data['Lowest Low'])
        if 'bb' in indicators:
            period_data['Bollinger Middle Band'] = period_data[significant_value].rolling(bb_period).mean()
            period_data['Bollinger Standard Deviation'] = period_data[significant_value].rolling(bb_period).std()
            period_data['Upper Bollinger Band'] = period_data['Bollinger Middle Band'] + (
                2 * period_data['Bollinger Standard Deviation'])
            period_data['Lower Bollinger Band'] = period_data['Bollinger Middle Band'] - (
                2 * period_data['Bollinger Standard Deviation'])
        if 'ic' in indicators:
            period_data['Lowest Low(Kenkan-Sen)'] = period_data['Low'].rolling(kn_period).min()
            period_data['Highest High(Kenkan-Sen)'] = period_data['High'].rolling(kn_period).max()
            period_data['Kenkan-Sen'] = (
                    period_data['Highest High(Kenkan-Sen)'] + period_data['Lowest Low(Kenkan-Sen)']) / 2
            period_data['Lowest Low(Kijun Sen)'] = period_data['Low'].rolling(kj_period).min()
            period_data['Highest High(Kijun Sen)'] = period_data['High'].rolling(kj_period).max()
            period_data['Kijun-Sen'] = (
                period_data['Highest High(Kijun Sen)'] + period_data['Lowest Low(Kijun Sen)']) / 2
            period_data['Chikou-Span'] = period_data[significant_value].shift(-kj_period)
            period_data['Senkou(Span A)'] = ((period_data['Kenkan-Sen'] + period_data['Kijun-Sen']) / 2).shift(
                kj_period)
            period_data['Lowest Low(52)'] = period_data['Low'].rolling(2 * kj_period).min()
            period_data['Highest High(52)'] = period_data['High'].rolling(2 * kj_period).max()
            period_data['Senkou(Span B)'] = ((period_data['Lowest Low(52)'] + period_data['Highest High(52)']) / 2
                                             ).shift(kj_period)
        if 'macd' in indicators:
            period_data['Fast EMA'] = period_data[significant_value].rolling(fast_ema).mean()
            period_data['Slow EMA'] = period_data[significant_value].rolling(slow_ema).mean()
            period_data['MACD'] = period_data['Fast EMA'] - period_data['Slow EMA']
            period_data['MACD Signal'] = period_data['MACD'].rolling(signal_line).mean()
            period_data['MACD Histogram'] = period_data['MACD'] - period_data['MACD Signal']
        if 'pp' in indicators:
            period_data['Pivot point'] = (period_data['High'] + period_data['Low'] + period_data['Close']) / 3
            period_data['First Resistance(R1)'] = (2 * period_data['Pivot point']) - period_data['Low']
            period_data['First Support(S1)'] = (2 * period_data['Pivot point']) - period_data['High']
            period_data['Second Resistance(R2)'] = period_data['Pivot point'] + period_data[
                'High'] - period_data['Low']
            period_data['Second Support(S2)'] = period_data['Pivot point'] - (period_data['High'] - period_data['Low'])
            period_data['Third Resistance(R3)'] = period_data['High'] + 2 * (
                    period_data['Pivot point'] - period_data['Low'])
            period_data['Third Support(S3)'] = period_data['Low'] - 2 * (
                    period_data['High'] - period_data['Pivot point'])
        if 'adx' in indicators:
            period_data['High-Low Difference'] = period_data['High'] - period_data['Low']
            period_data['High-Previous Close Difference'] = period_data['High'] - period_data['Close'].shift(1)
            period_data['Previous Close and Current Low Difference'] = period_data['Close'].shift(1) - period_data[
                'Low']
            period_data['True Range(TR)'] = period_data[['High-Low Difference', 'High-Previous Close Difference',
                                                        'Previous Close and Current Low Difference']].dropna().max(
                axis=1)
            period_data['Average True Range(ATR)'] = period_data['True Range(TR)'].rolling(adx_period).mean()
            period_data['High-Previous High Difference'] = period_data['High'] - period_data['High'].shift(1)
            period_data['Previous Low-Low Difference'] = period_data['Low'].shift(1) - period_data['Low']
            positive_condition = period_data[
                                     'High-Previous High Difference'] > period_data['Previous Low-Low Difference']
            period_data['Positive DX'] = period_data['High-Previous High Difference'][positive_condition]
            period_data['Positive DX'] = period_data['Positive DX'].fillna(0)
            negative_condition = period_data[
                                     'High-Previous High Difference'] < period_data['Previous Low-Low Difference']
            period_data['Negative DX'] = period_data['Previous Low-Low Difference'][negative_condition]
            period_data['Negative DX'] = period_data['Negative DX'].fillna(0)
            period_data['Smooth Positive DX'] = period_data['Positive DX'].rolling(adx_period).mean()
            period_data['Smooth Negative DX'] = period_data['Negative DX'].rolling(adx_period).mean()
            period_data['Positive Directional Movement Index(+DMI)'] = (
                    period_data['Smooth Positive DX'] / period_data['Average True Range(ATR)']) * 100
            period_data['Negative Directional Movement Index(-DMI)'] = (
                    period_data['Smooth Negative DX'] / period_data['Average True Range(ATR)']) * 100
            period_data['Directional Index(DX)'] = abs(
                period_data['Positive Directional Movement Index(+DMI)'] -
                period_data['Negative Directional Movement Index(-DMI)']) / (
                period_data[['Positive Directional Movement Index(+DMI)', 'Negative Directional Movement Index(-DMI)']]
            ).sum(axis=1) * 100
            period_data['Average Directional Index(ADX)'] = period_data['Directional Index(DX)'].rolling(
                adx_period).mean()
        return period_data


if __name__ == '__main__':
    test_years = [year for year in range(2017, 2019)]
    x = FxSimulator('eurusd', test_years)
    x.plot_initial_data('li', 'D1', comparison_value='Close')
    plt.show()

pairs.txt

代码语言:javascript
代码运行次数:0
复制
eurusd
eurchf
eurgbp
eurjpy
euraud
usdcad
usdchf
usdjpy
usdmxn
gbpchf
gbpjpy
gbpusd
audjpy
audusd
chfjpy
nzdjpy
nzdusd
xauusd
eurcad
audcad
cadjpy
eurnzd
grxeur
nzdcad
sgdjpy
usdhkd
usdnok
usdtry
xauaud
audchf
auxaud
eurhuf
eurpln
frxeur
hkxhkd
nzdchf
spxusd
usdhuf
usdpln
usdzar
xauchf
zarjpy
bcousd
etxeur
eurczk
eursek
gbpaud
gbpnzd
jpxjpy
udxusd
usdczk
usdsek
wtiusd
xaueur
audnzd
cadchf
eurdkk
eurnok
eurtry
gbpcad
nsxusd
ukxgbp
usddkk
usdsgd
xagusd
xaugbp
EN

回答 1

Code Review用户

发布于 2020-01-03 04:09:21

那你的

程序结构和改进/优化/特性的一般建议

我发现了真实/错误的评估和docString的弱点,并建议您遵循一些代码风格的指南,如谷歌。此外,您还可以对每个匹林特文件调用.py,就像在forex_data_handler.py pylint forex_data_handler.py上执行那样,并获得下一个输出:

代码语言:javascript
代码运行次数:0
复制
************* Module forex_data_handler
forex_data_handler.py:33:0: C0301: Line too long (115/100) (line-too-long)
forex_data_handler.py:54:0: C0301: Line too long (108/100) (line-too-long)
forex_data_handler.py:61:0: C0301: Line too long (117/100) (line-too-long)
forex_data_handler.py:62:0: C0301: Line too long (114/100) (line-too-long)
forex_data_handler.py:63:0: C0301: Line too long (120/100) (line-too-long)
forex_data_handler.py:82:0: C0304: Final newline missing (missing-final-newline)
forex_data_handler.py:1:0: C0114: Missing module docstring (missing-module-docstring)
forex_data_handler.py:1:0: E0401: Unable to import 'histdata' (import-error)
forex_data_handler.py:7:0: R0913: Too many arguments (6/5) (too-many-arguments)
forex_data_handler.py:20:8: R1705: Unnecessary "else" after "return" (no-else-return)
forex_data_handler.py:7:0: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements)
forex_data_handler.py:33:0: R0913: Too many arguments (9/5) (too-many-arguments)
forex_data_handler.py:33:0: R0914: Too many local variables (16/15) (too-many-locals)
forex_data_handler.py:77:4: C0103: Constant name "start_time" doesn't conform to UPPER_CASE naming style (invalid-name)
forex_data_handler.py:81:4: C0103: Constant name "end_time" doesn't conform to UPPER_CASE naming style (invalid-name)
forex_data_handler.py:2:0: C0411: standard import "from concurrent.futures import ThreadPoolExecutor, as_completed" should be placed before "from histdata import download_hist_data" (wrong-import-order)
forex_data_handler.py:3:0: C0411: standard import "from time import perf_counter" should be placed before "from histdata import download_hist_data" (wrong-import-order)
forex_data_handler.py:4:0: C0411: standard import "import os" should be placed before "from histdata import download_hist_data" (wrong-import-order)

------------------------------------------------------------------
Your code has been rated at 4.76/10 (previous run: 8.81/10, -4.05)
```
代码语言:javascript
代码运行次数:0
复制
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/234985

复制
相关文章
Firebase 如何创建登录 Token
Firebase 的 token 可以使用 firebase 命令行工具来进行创建。
HoneyMoose
2021/04/02
2.5K0
Firebase 如何创建登录 Token
Google 的 Firebase 如何删除项目
https://www.ossez.com/t/google-firebase/13792
HoneyMoose
2021/11/02
3.2K0
Google 的 Firebase 如何删除项目
firebase怎么用_firebase是什么
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/168361.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/20
4.2K0
firebase怎么用_firebase是什么
ETCD存储满了如何处理?
当运行 ETCD 日志报 Erro: mvcc database space exceeded 时,说明ETCD存储不足了(默认ETCD存储是2G),配额会触发告警,然后 Etcd 系统将进入操作受限的维护模式。
YP小站
2022/12/01
2.8K1
如何将你的Hexo博客部署到Google Firebase上
博主最近在 白嫖万恶的资本 将博客部署到新的CDN上,所以在寻找免费的静态Web应用部署工具,发现了Google Firebase。
pai233
2022/04/26
1.3K0
如何将你的Hexo博客部署到Google Firebase上
Android Firebase 服务简介
Firebase初步了解 什么事Firebase? Firebase成立于2011年,在被Google收购之前,Firebase是一个协助开发者快速构建App,能够提供行动应用专用开发平台及SDK的一款产品,简单的说大概就是一套集成后台服务工具。早在2014年,谷歌收购了Firebase,这主要是一种面向应用程序开发人员的数据库。Firebase基本上向广大的应用程序开发人员提供不同的服务,比如存储、消息传递、通知和身份验证等服务。 在今年的I/O大会上,谷歌发表了新版的Firebase,新的Firebas
xiangzhihong
2018/02/05
22.8K0
Android  Firebase 服务简介
如何将firebase应用转为supabase应用(之一)
用supabase实时数据库替换mapus协作地图里的firebase_q平面人的博客-CSDN博客
hotqin888
2022/11/16
5.5K0
与 FireBase 亲密接触
正常的 App 都是属于网络应用,数据都是从服务器上获取的。这就需要有专业的后台开发人员开发后台业务服务器,然后为我们 App 提供数据。自从云出现之后,各大云主机厂商提供了一个云服务 PAAS(Platform-as-a-Service的缩写),意思是平台即服务。PaaS是一个执行代码以及管理应用运行环境的开发平台,用户通过SVN或者Git之类的代码版本管理工具与平台交互。但这也是开发人员具备后台开发的能力。因此,
猴哥yuri
2018/08/16
16K0
我们弃用 Firebase 了
作者 | John Considine 译者 | 平川 策划 | 刘燕 我们已经在 Firebase 上发布了 10 几款应用程序,几乎用到了该平台每个方面的特性,并设计了一个可以实现优雅扩展的手册。可以说,事实已经证明,Firebase 对 K-Optional Software 而言是非常宝贵的工具。 就在 2022 年 3 月,我们的开发人员还在为 Firebase Extensions 等创新欢呼。遗憾的是,过去几个月的三个主要变化破坏了开发体验,因此,在新项目中,K-Optional 将
深度学习与Python
2023/03/29
32.7K0
我们弃用 Firebase 了
C++如何处理图的存储方式
稀疏图,就是点数的平方与边数差的特别多,边数少,但点数多,就不行了,因为空间占用太大了。
苏州程序大白
2022/04/14
4340
C++如何处理图的存储方式
POSTGRESQL 如何存储树形数据 处理树形数据
树形数据是一种什么体现,形式, 这里先提前的展示一下,为下面的postgresql操作树形数据做一个铺垫.
AustinDatabases
2020/07/01
3.1K0
爬虫异常处理之如何处理连接丢失和数据存储异常
在爬虫开发过程中,我们可能会遇到各种异常情况,如连接丢失、数据存储异常等。本文将介绍如何处理这些异常,并提供具体的解决代码。我们将以Python语言为例,使用requests库进行网络请求和sqlite3库进行数据存储。
华科云商小徐
2023/08/28
2430
Spring Boot 与 Kotlin 上传文件
如果我们做一个小型的web站,而且刚好选择的kotlin 和Spring Boot技术栈,那么上传文件的必不可少了,当然,如果你做一个中大型的web站,那建议你使用云存储,能省不少事情。
全科
2018/08/15
9830
做什么样的软件系列之Firebase
为什么要写这一篇? 做为一个iOS开发者我没有精力自己实现一套,登陆系统后台,广告系统后台,自己尝试写过身份认证系统,但是忘记密码之类的写的又丑又简陋。同时写后端和app又不能兼顾。
于欣轩
2018/05/25
4.4K0
如何应对高频监控?利用预处理和仅存储趋势数据
当我们在监控环境中,构建高频率监控时,有许多设计选择需要考虑。要考虑如何减少性能影响?存储空间的数据保留策略是什么?有哪些现成的功能可以解决这些潜在的问题?
Zabbix
2022/06/14
5090
如何应对高频监控?利用预处理和仅存储趋势数据
Kubernetes 的网络、存储和运行时该如何处理?
技术的发展,总是解决了现有的问题,进而引入新的问题,继而继续解决,如此周而复始,Docker 公司在2013年成立,将容器的概念迅速扩散。正如当年集装箱点燃了全球的货运革命一样,当时的船运公司使用这种大型的金属集装箱替代了过去纷杂的货运装置,以适应在卡车、船舶、铁路三者之间匹配。装什么无所谓,重要的是装载本身有了标准。和现实世界的集装箱运输一样,Linux 容器创建了对于应用最为基本的封装,使之可以运行在任何的基础设施平台上。一时之间,容器风靡世界。到今天为止,几乎所有的企业都有意愿将他们的应用跑在容器之上,即使是他们自己的内部的服务器,也同样在考虑。尽管容器仅仅是管理现代的应用程序的一种更好的方式,因为它们通常被分割成无数的组件(微服务),但仍然需要能够在服务器之间进行容易的移植和访问。
CNCF
2019/12/04
1.3K0
Kubernetes 的网络、存储和运行时该如何处理?
对象存储COS媒体处理实践
如何让自己的产品更好的提供音视频服务,如何使音视频文件适配众多终端设备,适配各种网络环境,如何方便快捷的对音视频文件进行处理,这些问题成为巨大的挑战。
用户4693941
2021/02/22
1.3K0
[SpingBoot guides系列翻译]文件上传
mkdir -p src/main/java/hello,其实也就是在IntelliJ里面新建一个空的Java项目,然后添加一个main.java.hellopackage。
_淡定_
2019/05/15
10.2K0
[SpingBoot guides系列翻译]文件上传
flutter中多flavors方案以及添加firebase​
有想做海外市场的同学们,可能需要用到firebase。今天我们讲讲怎么使用「FlutterFire CLI」添加 firebase以及如何设置「flavors」
用户1974410
2022/09/20
9.9K0
flutter中多flavors方案以及添加firebase​
点击加载更多

相似问题

Firebase StorageException下载时

24

Firebase E/ StorageException :发生StorageException。位置处不存在对象

129

Firebase - StorageException: StorageException已发生,->对象在位置上不存在

17

已发生StorageException。位置处不存在对象。存储FireBase

93

即使我处理它,firebase StorageException也会打印出来

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文