0

我在网上找到了这个 python 脚本,它通过想要的日期、资产和时间间隔从 Binance api 获取 OHLCV 历史数据。该脚本当前返回 UTC 时间的数据。

我想修改它,以便它根据指定的时区(每天/每小时)返回数据。我想只需要更改一个函数或添加一个参数,但我无法正确地做到这一点。

如何更改它以返回 UTC+2(或任何其他时区)的数据?

谢谢!盖伊

import time
import dateparser
import pytz
import os
from datetime import datetime
import binance
print(binance.__file__)
from binance.client import Client
import time
import pandas as pd


def date_to_milliseconds(date_str):
    """Convert UTC date to milliseconds

    If using offset strings add "UTC" to date string e.g. "now UTC", "11 hours ago UTC"

    See dateparse docs for formats http://dateparser.readthedocs.io/en/latest/

    :param date_str: date in readable format, i.e. "January 01, 2018", "11 hours ago UTC", "now UTC"
    :type date_str: str
    """
    # get epoch value in UTC
    epoch = datetime.utcfromtimestamp(0).replace(tzinfo=pytz.utc)
    # parse our date string
    d = dateparser.parse(date_str)
    # if the date is not timezone aware apply UTC timezone
    if d.tzinfo is None or d.tzinfo.utcoffset(d) is None:
        d = d.replace(tzinfo=pytz.utc)

    # return the difference in time
    return int((d - epoch).total_seconds() * 1000.0)


def interval_to_milliseconds(interval):
    """Convert a Binance interval string to milliseconds

    :param interval: Binance interval string 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w
    :type interval: str

    :return:
         None if unit not one of m, h, d or w
         None if string not in correct format
         int value of interval in milliseconds
    """
    ms = None
    seconds_per_unit = {
        "m": 60,
        "h": 60 * 60,
        "d": 24 * 60 * 60,
        "w": 7 * 24 * 60 * 60
    }

    unit = interval[-1]
    if unit in seconds_per_unit:
        try:
            ms = int(interval[:-1]) * seconds_per_unit[unit] * 1000
        except ValueError:
            pass
    return ms

def GetUpdateData(kline):
     Time = time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime(kline[0]/1000))
     Open = kline[1]
     High = kline[2]
     Low = kline[3]
     Close = kline[4]
     Volume = kline[5]
     Close_time = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime(kline[6]/1000))
     Quote_asset_volume = kline[7]
     Number_of_trades = kline[8]  
     Taker_buy_base_asset_volume = kline[9] 
     Taker_buy_quote_asset_volume = kline[10] 
     return Time,Open,High,Low,Close,Volume,Close_time,Quote_asset_volume,Number_of_trades,Taker_buy_base_asset_volume,Taker_buy_quote_asset_volume
def get_historical_klines(symbol, interval, start_str, end_str=None):
    """Get Historical Klines from Binance

    See dateparse docs for valid start and end string formats http://dateparser.readthedocs.io/en/latest/

    If using offset strings for dates add "UTC" to date string e.g. "now UTC", "11 hours ago UTC"

    :param symbol: Name of symbol pair e.g BNBBTC
    :type symbol: str
    :param interval: Biannce Kline interval
    :type interval: str
    :param start_str: Start date string in UTC format
    :type start_str: str
    :param end_str: optional - end date string in UTC format
    :type end_str: str

    :return: list of OHLCV values

    """
    # create the Binance client, no need for api key
    client = Client("", "")

    # init our list
    output_data = []

    # setup the max limit
    limit = 500

    # convert interval to useful value in seconds
    timeframe = interval_to_milliseconds(interval)

    # convert our date strings to milliseconds
    start_ts = date_to_milliseconds(start_str)

    # if an end time was passed convert it
    end_ts = None
    if end_str:
        end_ts = date_to_milliseconds(end_str)

    idx = 0
    # it can be difficult to know when a symbol was listed on Binance so allow start time to be before list date
    symbol_existed = False
    while True:
        # fetch the klines from start_ts up to max 500 entries or the end_ts if set
        temp_data = client.get_klines(
            symbol=symbol,
            interval=interval,
            limit=limit,
            startTime=start_ts,
            endTime=end_ts
        )

        # handle the case where our start date is before the symbol pair listed on Binance
        if not symbol_existed and len(temp_data):
            symbol_existed = True

        if symbol_existed:
            # append this loops data to our output data
            output_data += temp_data

            # update our start timestamp using the last value in the array and add the interval timeframe
            start_ts = temp_data[len(temp_data) - 1][0] + timeframe
        else:
            # it wasn't listed yet, increment our start date
            start_ts += timeframe

        idx += 1
        # check if we received less than the required limit and exit the loop
        if len(temp_data) < limit:
            # exit the while loop
            break

        # sleep after every 3rd call to be kind to the API
        if idx % 3 == 0:
            time.sleep(1)

    return output_data

start = "01 January, 2017"
end = "01 February, 2017"
symbols = ['ETHBTC']
interval = '1d'#Client.KLINE_INTERVAL_15MIN
for symbol in symbols:
    klines = get_historical_klines(symbol, interval, start, end)

    times = []
    Opens = []
    Highs = []
    Lows  = []
    Closes = [] 
    Volumes = []
    Close_times = []
    Quote_asset_volumes = []
    Number_of_tradess = []
    Taker_buy_base_asset_volumes = []
    Taker_buy_quote_asset_volumes = []
    for k in klines:
        Time,Open,High,Low,Close,Volume,Close_time,Quote_asset_volume,Number_of_trades,Taker_buy_base_asset_volume,Taker_buy_quote_asset_volume = GetUpdateData(k)
        times.append(Time)
        Opens.append(Open)
        Highs.append(High)
        Lows.append(Low)
        Closes.append(Close)
        Volumes.append(Volume)
        Close_times.append(Close_time)
        Quote_asset_volumes.append(Quote_asset_volume)
        Number_of_tradess.append(Number_of_trades)
        Taker_buy_base_asset_volumes.append(Taker_buy_base_asset_volume)
        Taker_buy_quote_asset_volumes.append(Taker_buy_quote_asset_volume)


    DataStruct = pd.DataFrame()
    DataStruct['time'] = times
    DataStruct['Open'] = Opens
    DataStruct['High'] = Highs
    DataStruct['Low'] = Lows
    DataStruct['Close'] = Closes
    DataStruct['Volume'] = Volumes
    DataStruct['Close_time'] = Close_times
    DataStruct['Quote_asset_volume'] = Quote_asset_volumes
    DataStruct['Number_of_trades'] = Number_of_tradess
    DataStruct['Taker_buy_base_asset_volume'] = Taker_buy_base_asset_volumes
    DataStruct['Taker_buy_quote_asset_volume'] = Taker_buy_quote_asset_volumes

    FileName = symbol+ '_' + start+ '_' + end + ' .csv'
    FileName = FileName.replace(' ','_')
    FileName = FileName.replace(',','')
    Path2Save = os.path.normpath(r'')
    SaveStrFile = os.path.normpath(Path2Save+ '\\' +FileName)
    #save FeatureWeights to CSV file
    D_S_header = ['time','Open','High','Low','Close','Volume','Close_time','Quote_asset_volume','Number_of_trades','Taker_buy_base_asset_volume','Taker_buy_quote_asset_volume']
    DataStruct.to_csv(path_or_buf = SaveStrFile, header = D_S_header )
4

1 回答 1

0

在这些行中,您会看到正在定义的时区:

# get epoch value in UTC
epoch = datetime.utcfromtimestamp(0).replace(tzinfo=pytz.utc)

只需在那里重新定义时区。对于支持的时区列表,pytz您可以使用pytz.all_timezones.

于 2020-04-03T20:09:15.013 回答