From 1963d2720bff22b2d6ccc94d01d47251c0fd1488 Mon Sep 17 00:00:00 2001 From: blade <8019068@qq.com> Date: Tue, 16 Sep 2025 14:31:15 +0800 Subject: [PATCH] updae for datetime --- auto_schedule.py | 17 ++++-- auto_update_market_data.py | 17 ++++-- config.py | 5 ++ core/biz/huge_volume_chart.py | 5 +- core/biz/market_data.py | 86 ++++++++++++++++++++++++--- core/biz/market_data_from_itick.py | 2 +- core/biz/market_monitor.py | 3 + core/biz/strategy.py | 5 +- core/biz/trade_data.py | 5 +- core/db/db_manager.py | 5 +- core/logger.py | 8 +-- core/statistics/price_volume_stats.py | 5 +- core/trade/ma_break_statistics.py | 7 ++- core/utils.py | 9 ++- huge_volume_main.py | 22 +++---- market_data_from_itick_main.py | 5 +- market_data_main.py | 5 +- market_monitor_main.py | 20 ++++++- orb_trade_main.py | 7 ++- requirements.txt | 4 +- test_binance.py | 39 ++++++++++++ trade_sandbox_main.py | 7 ++- 22 files changed, 226 insertions(+), 62 deletions(-) create mode 100644 test_binance.py diff --git a/auto_schedule.py b/auto_schedule.py index 225f26c..426d4eb 100644 --- a/auto_schedule.py +++ b/auto_schedule.py @@ -1,20 +1,27 @@ import schedule import time -import datetime +from core.utils import get_current_date_time import core.logger as logging import subprocess import os +import sys logger = logging.logger # 定义要执行的任务 def run_script(): start_time = time.time() - logger.info(f"Executing script at: {datetime.datetime.now()}") + logger.info(f"Executing script at: {get_current_date_time()}") output_file = r'./output/auto_schedule.txt' with open(output_file, 'a') as f: - f.write(f"Task ran at {datetime.datetime.now()}\n") - python_path = r"D:\miniconda3\envs\okx\python.exe" - script_path = r"D:\python_projects\crypto_quant\monitor_schedule.py" + f.write(f"Task ran at {get_current_date_time()}\n") + current_dir = os.getcwd() + python_path = sys.executable + if current_dir.endswith('crypto_quant'): + script_path = r'./monitor_schedule.py' + elif current_dir.endswith(r'python_projects'): + script_path = f'{current_dir}/crypto_quant/monitor_schedule.py' + else: + script_path = f'{current_dir}/monitor_schedule.py' subprocess.run([python_path, script_path]) end_time = time.time() logger.info(f"Script execution time: {end_time - start_time} seconds") diff --git a/auto_update_market_data.py b/auto_update_market_data.py index 0e880ee..e853bf5 100644 --- a/auto_update_market_data.py +++ b/auto_update_market_data.py @@ -1,20 +1,27 @@ import schedule import time -import datetime +from core.utils import get_current_date_time import core.logger as logging import subprocess import os +import sys logger = logging.logger # 定义要执行的任务 def run_script(): start_time = time.time() - logger.info(f"Executing script at: {datetime.datetime.now()}") + logger.info(f"Executing script at: {get_current_date_time()}") output_file = r'./output/auto_schedule.txt' with open(output_file, 'a') as f: - f.write(f"Task ran at {datetime.datetime.now()}\n") - python_path = r"D:\miniconda3\envs\okx\python.exe" - script_path = r"D:\python_projects\crypto_quant\huge_volume_main.py" + f.write(f"Task ran at {get_current_date_time()}\n") + python_path = sys.executable + current_dir = os.getcwd() + if current_dir.endswith('crypto_quant'): + script_path = r'./huge_volume_main.py' + elif current_dir.endswith(r'python_projects'): + script_path = f'{current_dir}/crypto_quant/huge_volume_main.py' + else: + script_path = f'{current_dir}/huge_volume_main.py' subprocess.run([python_path, script_path]) end_time = time.time() logger.info(f"Script execution time: {end_time - start_time} seconds") diff --git a/config.py b/config.py index 39307bc..a15a78c 100644 --- a/config.py +++ b/config.py @@ -12,6 +12,11 @@ SECRET_KEY = "F7AD69272FBF7C44E69CC110D2EDDB7A" PASSPHRASE = "Bengbu!2001" SANDBOX = False +# API_KEY = "12d911b6-f28a-4595-b177-70cb8fbdc369" +# SECRET_KEY = "C32DF88A975EE08631D0BE6B6B5A33E7" +# PASSPHRASE = "Bengbu@2001" +# SANDBOX = False + # 模拟盘API密钥配置 # API_KEY = "f309e789-3497-4ed3-896f-d18bdc4d9817" # SECRET_KEY = "9152809391B110E2E647FDE12A37E96D" diff --git a/core/biz/huge_volume_chart.py b/core/biz/huge_volume_chart.py index 8c80e2b..6a158e4 100644 --- a/core/biz/huge_volume_chart.py +++ b/core/biz/huge_volume_chart.py @@ -7,7 +7,8 @@ from openpyxl import Workbook from openpyxl.drawing.image import Image from PIL import Image as PILImage import core.logger as logging -from datetime import datetime +from datetime import datetime, timezone, timedelta +from core.utils import get_current_date_time import pandas as pd import os import re @@ -403,7 +404,7 @@ class HugeVolumeChart: } """ logger.info(f"输出Excel文件,包含所有{chart_type}图表") - file_name = f"huge_volume_{chart_type}_{datetime.now().strftime('%Y%m%d%H%M%S')}.xlsx" + file_name = f"huge_volume_{chart_type}_{get_current_date_time()}.xlsx" file_path = os.path.join(self.output_folder, file_name) # Create Excel file and worksheet diff --git a/core/biz/market_data.py b/core/biz/market_data.py index e968893..d0d70ee 100644 --- a/core/biz/market_data.py +++ b/core/biz/market_data.py @@ -1,12 +1,17 @@ import time -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone +from core.utils import get_current_date_time from typing import Optional import pandas as pd +import requests +import json + import okx.MarketData as Market import okx.TradingData as TradingData from core.utils import transform_date_time_to_timestamp, timestamp_to_datetime from core.biz.market_data_from_itick import MarketDataFromItick import core.logger as logging +import sys logger = logging.logger @@ -23,9 +28,18 @@ class MarketData: self.passphrase = passphrase self.market_api = Market.MarketAPI( api_key=api_key, api_secret_key=secret_key, passphrase=passphrase, - flag=self.flag + flag=self.flag, ) self.is_us_stock = is_us_stock + # 当前操作系统是windows还是linux + self.is_windows = sys.platform == "win32" + if not self.is_us_stock: + # 如果当前操作系统是windows,则is_binance为False,否则为True + # 因为LINUX服务器,目前访问不了欧易的API + if self.is_windows: + self.is_binance = False + else: + self.is_binance = True # self.trade_api = TradingData.TradingDataAPI( # api_key=api_key, api_secret_key=secret_key, passphrase=passphrase, @@ -48,11 +62,21 @@ class MarketData: if end_time is None: logger.error(f"end_time参数解析失败: {end_time}") return None - response = self.get_realtime_candlesticks_from_api(symbol, bar, end_time, limit) + if self.is_binance: + if symbol == "XCH-USDT": + return None + response = self.get_realtime_candlesticks_from_binance(symbol, bar, end_time, limit) + else: + response = self.get_realtime_candlesticks_from_api(symbol, bar, end_time, limit) + if response: candles = response["data"] - from_time = int(candles[-1][0]) - to_time = int(candles[0][0]) + if self.is_binance: + from_time = int(candles[0][0]) + to_time = int(candles[-1][0]) + else: + from_time = int(candles[-1][0]) + to_time = int(candles[0][0]) from_time_str = pd.to_datetime(from_time, unit='ms', utc=True).tz_convert('Asia/Shanghai') to_time_str = pd.to_datetime(to_time, unit='ms', utc=True).tz_convert('Asia/Shanghai') logger.info(f"已获取{symbol}, 周期:{bar} {len(candles)} 条数据,从: {from_time_str} 到: {to_time_str}") @@ -68,7 +92,7 @@ class MarketData: candles_pd['symbol'] = symbol # 添加bar列,内容为bar candles_pd['bar'] = bar - candles_pd['create_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + candles_pd['create_time'] = get_current_date_time() candles_pd = candles_pd[['symbol', 'bar', 'timestamp', 'date_time', 'open', 'high', 'low', 'close', 'volume', 'volCcy', 'volCCyQuote', 'create_time']] candles_pd.sort_values('timestamp', inplace=True) candles_pd.reset_index(drop=True, inplace=True) @@ -197,7 +221,7 @@ class MarketData: df['symbol'] = symbol # 添加bar列,内容为bar df['bar'] = bar - df['create_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + df['create_time'] = get_current_date_time() if self.is_us_stock: # 如果是美股数据,则仅保留date_time_us字中,在开盘时间内的数据,即开盘时间为美国时间9:30到16:00 @@ -280,6 +304,54 @@ class MarketData: time.sleep(10) return response + def get_realtime_candlesticks_from_binance(self, symbol, bar, end_time, limit): + # API 端点:币安现货 K 线数据 + base_url = "https://api.binance.com" + endpoint = "/api/v3/klines" + params = { + "symbol": symbol.replace("-", ""), + "interval": bar, + "limit": limit + } + response = None + count = 0 + data = None + while True: + try: + # 发送 GET 请求 + response = requests.get(base_url + endpoint, params=params) + if response.status_code == 200: + data = response.json() + break + except Exception as e: + logger.error(f"请求出错: {e}") + count += 1 + if count > 3: + break + time.sleep(10) + if data: + # 每条数据格式:[开盘时间, 开盘价, 最高价, 最低价, 收盘价, 成交量, 收盘时间, 报价成交量, 成交笔数, 主动买入成交量, 主动买入报价成交量, 忽略] + columns = ["timestamp", "open", "high", "low", "close", "volume", "volCcy", "volCCyQuote", "confirm"] + data_list = [] + # [开盘时间, 开盘价, 最高价, 最低价, 收盘价, 成交量, 报价成交量, 是否收盘] + for record in data: + record = [ + int(record[6]), + float(record[1]), + float(record[2]), + float(record[3]), + float(record[4]), + float(record[5]), + float(record[7]), + float(record[7]), + "1" + ] + data_list.append(record) + return {"data": data_list} + else: + logger.warning(f"未获取到{symbol}, {bar} 最新数据,请稍后再试") + return None + def get_realtime_candlesticks_from_api(self, symbol, bar, end_time, limit): response = None count = 0 diff --git a/core/biz/market_data_from_itick.py b/core/biz/market_data_from_itick.py index a26f3d3..791f58d 100644 --- a/core/biz/market_data_from_itick.py +++ b/core/biz/market_data_from_itick.py @@ -63,7 +63,7 @@ class MarketDataFromItick: # 设置默认时间范围 if end_time is None: - end_time = int(datetime.now().strftime('%Y-%m-%d %H:%M:%S').timestamp()) + end_time = int(datetime.now().timestamp()) if isinstance(end_time, str): end_time = int(datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S').timestamp()) self.end_time = end_time diff --git a/core/biz/market_monitor.py b/core/biz/market_monitor.py index b98cd48..70ae5c5 100644 --- a/core/biz/market_monitor.py +++ b/core/biz/market_monitor.py @@ -16,6 +16,7 @@ def create_metrics_report( only_output_huge_volume: bool = False, only_output_rise: bool = False, now_datetime_str: str = None, + is_binance: bool = False, ): """ 创建指标报告 @@ -61,6 +62,8 @@ def create_metrics_report( brief = f"{symbol} {bar} 量率: {volume_ratio} {change}: {pct_chg}% 异动 价: {close}" else: brief = f"{symbol} {bar} 量率: {volume_ratio} {change}: {pct_chg}% 价: {close}" + if is_binance: + brief += " 币安" if huge_volume == 1: contents.append(f"## {brief} 交易巨量报告") diff --git a/core/biz/strategy.py b/core/biz/strategy.py index cd17f7a..1fd1938 100644 --- a/core/biz/strategy.py +++ b/core/biz/strategy.py @@ -1,5 +1,6 @@ import time -from datetime import datetime +from datetime import datetime, timezone, timedelta +from core.utils import get_current_date_time import core.logger as logging from typing import Optional import pandas as pd @@ -177,7 +178,7 @@ class QuantStrategy: logger.info(f"开始运行{strategy}策略,间隔{interval}秒") while True: try: - logger.info(datetime.now().strftime('%Y-%m-%d %H:%M:%S')) + logger.info(get_current_date_time()) try: self.quant_trader.get_account_balance() except Exception as e: diff --git a/core/biz/trade_data.py b/core/biz/trade_data.py index 97cc230..c33b639 100644 --- a/core/biz/trade_data.py +++ b/core/biz/trade_data.py @@ -1,5 +1,6 @@ import time -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone +from core.utils import get_current_date_time from typing import Optional import pandas as pd import okx.MarketData as Market @@ -87,7 +88,7 @@ class TradeData: df.rename(columns={"instId": "symbol"}, inplace=True) df["date_time"] = df["ts"].apply(lambda x: timestamp_to_datetime(x)) df["tradeId"] = df["tradeId"].astype(str) - df["create_time"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + df["create_time"] = get_current_date_time() df = df[["symbol", "ts", "date_time", "tradeId", "side", "sz", "px", "create_time"]] self.db_trade_data.insert_data_to_mysql(df) diff --git a/core/db/db_manager.py b/core/db/db_manager.py index 1a64776..4be1921 100644 --- a/core/db/db_manager.py +++ b/core/db/db_manager.py @@ -1,6 +1,7 @@ import pandas as pd from sqlalchemy import create_engine, exc, text -import re, datetime +import re +from core.utils import get_current_date_time import core.logger as logging from core.utils import transform_data_type @@ -12,7 +13,7 @@ class DBData: ): self.table_name = table_name self.temp_table_name = ( - f"temp_{table_name}_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}" + f"temp_{table_name}_{get_current_date_time()}" ) self.columns = columns if self.columns is None: diff --git a/core/logger.py b/core/logger.py index 62df942..b9c123d 100644 --- a/core/logger.py +++ b/core/logger.py @@ -12,11 +12,11 @@ class Logger: # log文件存储路径 current_dir = os.getcwd() if current_dir.endswith('crypto_quant'): - output_folder = r'./output/log/' - elif current_dir.startswith(r'/root/'): - output_folder = r'/root/crypto_quant/output/log/' + output_folder = f'{current_dir}/output/log/' + elif current_dir.endswith(r'python_projects'): + output_folder = f'{current_dir}/crypto_quant/output/log/' else: - output_folder = r'./output/log/' + output_folder = f'{current_dir}/output/log/' os.makedirs(output_folder, exist_ok=True) # add self._log_filename to be adata_yyyyMMddHHmm.log self._log_filename = os.path.join(output_folder, 'crypto_monitor_{}.log'.format(time.strftime("%Y%m%d%H%M%S", time.localtime()))) diff --git a/core/statistics/price_volume_stats.py b/core/statistics/price_volume_stats.py index 57b210a..9d6d5fa 100644 --- a/core/statistics/price_volume_stats.py +++ b/core/statistics/price_volume_stats.py @@ -4,7 +4,8 @@ import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns -from datetime import datetime +from datetime import datetime, timezone, timedelta +from core.utils import get_current_date_time import re from openpyxl import Workbook from openpyxl.drawing.image import Image @@ -41,7 +42,7 @@ class PriceVolumeStats: self.initial_date = OKX_MONITOR_CONFIG.get("volume_monitor", {}).get( "initial_date", "2025-05-15 00:00:00" ) - self.end_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + self.end_date = get_current_date_time() self.window_size = 100 self.stats_output_dir = "./output/statistics/excel/" os.makedirs(self.stats_output_dir, exist_ok=True) diff --git a/core/trade/ma_break_statistics.py b/core/trade/ma_break_statistics.py index 5bdd774..12d61b6 100644 --- a/core/trade/ma_break_statistics.py +++ b/core/trade/ma_break_statistics.py @@ -4,7 +4,8 @@ import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone +from core.utils import get_current_date_time import re import json from openpyxl import Workbook @@ -81,7 +82,7 @@ class MaBreakStatistics: self.db_market_data = DBMarketData(self.db_url) if len(self.initial_date) > 10: self.initial_date = self.initial_date[:10] - self.end_date = datetime.now().strftime("%Y-%m-%d") + self.end_date = get_current_date_time() self.trade_strategy_config = self.get_trade_strategy_config() self.main_strategy = self.trade_strategy_config.get("均线系统策略", None) @@ -233,7 +234,7 @@ class MaBreakStatistics: ) latest_market_date_time = ma_break_market_data["end_date_time"].max() if latest_market_date_time is None: - latest_market_date_time = datetime.now().strftime("%Y%m%d") + latest_market_date_time = get_current_date_time() latest_market_date_time = re.sub( r"[\:\-\s]", "", str(latest_market_date_time) ) diff --git a/core/utils.py b/core/utils.py index b9bd101..cc67b05 100644 --- a/core/utils.py +++ b/core/utils.py @@ -73,4 +73,11 @@ def transform_date_time_to_timestamp(date_time: int | str): return date_time except Exception as e: logger.error(f"start参数解析失败: {e}") - return None \ No newline at end of file + return None + + +def get_current_date_time() -> str: + """ + 获取当前日期时间 + """ + return datetime.now(timezone(timedelta(hours=8))).strftime("%Y-%m-%d %H:%M:%S") \ No newline at end of file diff --git a/huge_volume_main.py b/huge_volume_main.py index ec8147a..035f67d 100644 --- a/huge_volume_main.py +++ b/huge_volume_main.py @@ -4,7 +4,7 @@ from core.db.db_market_data import DBMarketData from core.db.db_huge_volume_data import DBHugeVolumeData from core.db.db_binance_data import DBBinanceData from core.db.db_binance_huge_volume_data import DBBinanceHugeVolumeData -from core.utils import timestamp_to_datetime, transform_date_time_to_timestamp +from core.utils import timestamp_to_datetime, transform_date_time_to_timestamp, get_current_date_time from market_data_main import MarketDataMain from core.wechat import Wechat import core.logger as logging @@ -15,7 +15,7 @@ from config import ( WINDOW_SIZE, BINANCE_MONITOR_CONFIG, ) -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone import pandas as pd import os import re @@ -108,7 +108,7 @@ class HugeVolumeMain: ) if end is None: - end = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + end = get_current_date_time() logger.info( f"开始处理巨量交易数据: {symbol} {bar} 窗口大小: {window_size} 从 {start} 到 {end}" ) @@ -344,7 +344,7 @@ class HugeVolumeMain: is_update=True, ) logger.info( - f"更新巨量交易数据: {symbol} {bar} 窗口大小: {window_size} 从 {earliest_date_time} 到 {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" + f"更新巨量交易数据: {symbol} {bar} 窗口大小: {window_size} 从 {earliest_date_time} 到 {get_current_date_time()}" ) if data is not None and len(data) > 0: logger.info(f"此次更新巨量交易数据: {len(data)}条") @@ -352,7 +352,7 @@ class HugeVolumeMain: logger.info(f"此次更新巨量交易数据为空") except Exception as e: logger.error( - f"更新巨量交易数据失败: {symbol} {bar} 窗口大小: {window_size} 到 {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}: {e}" + f"更新巨量交易数据失败: {symbol} {bar} 窗口大小: {window_size} 到 {get_current_date_time()}: {e}" ) def get_seconds_by_bar(self, bar: str): @@ -413,7 +413,7 @@ class HugeVolumeMain: "initial_date", "2025-05-01 00:00:00" ) if end is None: - end = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + end = get_current_date_time() periods_text = ", ".join([str(period) for period in periods]) logger.info( f"开始计算巨量出现后,之后{periods_text}个周期,上涨或下跌的比例: {symbol} {bar} 窗口大小: {window_size} 从 {start} 到 {end}" @@ -473,7 +473,7 @@ class HugeVolumeMain: "initial_date", "2025-05-01 00:00:00" ) if end is None: - end = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + end = get_current_date_time() start_timestamp = transform_date_time_to_timestamp(start) end_timestamp = transform_date_time_to_timestamp(end) @@ -582,7 +582,7 @@ class HugeVolumeMain: "initial_date", "2025-05-01 00:00:00" ) if end is None: - end = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + end = get_current_date_time() huge_volume_data_list = [] result_data_list = [] window_size_list = WINDOW_SIZE.get("window_sizes", None) @@ -606,7 +606,7 @@ class HugeVolumeMain: if output_excel: total_huge_volume_data = total_huge_volume_data.reset_index(drop=True) total_result_data = total_result_data.reset_index(drop=True) - current_date = datetime.now().strftime("%Y%m%d%H%M%S") + current_date = get_current_date_time() file_name = f"next_periods_rise_or_fall_{current_date}.xlsx" try: with pd.ExcelWriter( @@ -687,10 +687,10 @@ def test_import_binance_data_by_csv(): def test_send_huge_volume_data_to_wechat(): huge_volume_main = HugeVolumeMain(threshold=2.0) # 获得昨天日期 - yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d") + yesterday = (datetime.now(timezone(timedelta(hours=8))) - timedelta(days=1)).strftime("%Y-%m-%d") logger.info(f"昨天日期: {yesterday}") # 获得今天日期 - today = datetime.now().strftime("%Y-%m-%d") + today = datetime.now(timezone(timedelta(hours=8))).strftime("%Y-%m-%d") logger.info(f"今天日期: {today}") huge_volume_main.send_huge_volume_data_to_wechat(start=yesterday, end=today) diff --git a/market_data_from_itick_main.py b/market_data_from_itick_main.py index 88a0756..7308372 100644 --- a/market_data_from_itick_main.py +++ b/market_data_from_itick_main.py @@ -2,8 +2,7 @@ import requests import core.logger as logging from datetime import datetime, timedelta - -from futu import KLType +from core.utils import get_current_date_time logger = logging.logger @@ -41,7 +40,7 @@ def main(): logger.info(f"成功下载 {len(processed_data)} 条数据") # 保存数据 - filename = f"{symbol}_{interval}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv" + filename = f"{symbol}_{interval}_{get_current_date_time()}.csv" market_data_from_futu.save_to_csv(filename) # 显示数据统计 diff --git a/market_data_main.py b/market_data_main.py index a90888a..2278d68 100644 --- a/market_data_main.py +++ b/market_data_main.py @@ -1,5 +1,6 @@ import core.logger as logging from datetime import datetime, timedelta, timezone +from core.utils import get_current_date_time from time import sleep import pandas as pd from core.biz.market_data import MarketData @@ -107,7 +108,7 @@ class MarketDataMain: """ 获取保存数据 """ - end_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + end_time = get_current_date_time() end_time_ts = transform_date_time_to_timestamp(end_time) if end_time_ts is None: logger.error(f"结束时间格式错误: {end_time}") @@ -225,7 +226,7 @@ class MarketDataMain: data['date_time'] = dt_series.dt.strftime('%Y-%m-%d %H:%M:%S') dt_us_series = pd.to_datetime(data['timestamp'].astype(int), unit='ms', utc=True, errors='coerce').dt.tz_convert('America/New_York') data['date_time_us'] = dt_us_series.dt.strftime('%Y-%m-%d %H:%M:%S') - data['create_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + data['create_time'] = get_current_date_time() data["date_time"] = data["date_time"].astype(str) data["date_time_us"] = data["date_time_us"].astype(str) diff --git a/market_monitor_main.py b/market_monitor_main.py index dfd80d3..dd7af5e 100644 --- a/market_monitor_main.py +++ b/market_monitor_main.py @@ -9,8 +9,9 @@ from core.utils import timestamp_to_datetime, transform_date_time_to_timestamp import core.logger as logging import os +import sys import pandas as pd -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone import json import re @@ -41,6 +42,15 @@ class MarketMonitorMain: self.db_url = f"mysql+pymysql://{mysql_user}:{mysql_password}@{mysql_host}:{mysql_port}/{mysql_database}" self.db_market_monitor = DBMarketMonitor(self.db_url) + + # 当前操作系统是windows还是linux + self.is_windows = sys.platform == "win32" + # 如果当前操作系统是windows,则is_binance为False,否则为True + # 因为LINUX服务器,目前访问不了欧易的API + if self.is_windows: + self.is_binance = False + else: + self.is_binance = True def get_latest_record(self): """ @@ -71,8 +81,8 @@ class MarketMonitorMain: 监控最新市场数据 考虑到速度,暂不与数据库交互,直接从api获取数据 """ - # 获得当前时间字符串 - now_datetime = datetime.now() + # 获得当前时间字符串,转为北京时间 + now_datetime = datetime.now(timezone(timedelta(hours=8))) now_datetime_str = now_datetime.strftime("%Y-%m-%d %H:%M:%S") end_time = transform_date_time_to_timestamp(now_datetime_str) real_time_data = self.market_data_main.market_data.get_realtime_kline_data( @@ -174,6 +184,7 @@ class MarketMonitorMain: only_output_huge_volume, only_output_rise, now_datetime_str, + self.is_binance, ) text_length = len(report.encode("utf-8")) @@ -268,6 +279,9 @@ class MarketMonitorMain: only_output_rise: bool = True, ): for symbol in self.market_data_main.symbols: + if self.is_binance and symbol == "XCH-USDT": + logger.info(f"币安交易所无: {symbol}") + continue for bar in self.market_data_main.bars: logger.info( f"开始监控: {symbol} {bar} 窗口大小: {self.window_size} 行情数据" diff --git a/orb_trade_main.py b/orb_trade_main.py index 8ac38e3..28a9111 100644 --- a/orb_trade_main.py +++ b/orb_trade_main.py @@ -1,7 +1,8 @@ from core.trade.orb_trade import ORBStrategy from config import US_STOCK_MONITOR_CONFIG, OKX_MONITOR_CONFIG, BINANCE_MONITOR_CONFIG import core.logger as logging -from datetime import datetime +from datetime import datetime, timezone, timedelta +from core.utils import get_current_date_time from openpyxl import Workbook from openpyxl.drawing.image import Image import openpyxl @@ -27,7 +28,7 @@ def main(): start_date = start_date[:10] else: start_date = "2024-01-01" - end_date = datetime.now().strftime("%Y-%m-%d") + end_date = get_current_date_time() # 原值 盈利目标倍数(默认10倍$R,即10R) profit_target_multiple = 10 @@ -120,7 +121,7 @@ def main(): statitics_dict = statistics_summary(total_trades_summary_df) output_excel_folder = r"./output/trade_sandbox/orb_strategy/excel/summary/" os.makedirs(output_excel_folder, exist_ok=True) - now_str = datetime.now().strftime("%Y%m%d%H%M%S") + now_str = get_current_date_time() excel_file_name = f"orb_strategy_summary_{now_str}.xlsx" output_file_path = os.path.join(output_excel_folder, excel_file_name) with pd.ExcelWriter(output_file_path) as writer: diff --git a/requirements.txt b/requirements.txt index b2491a2..01c840d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,4 +9,6 @@ seaborn >= 0.13.2 schedule >= 1.2.2 xlsxwriter >= 3.2.5 openpyxl >= 3.1.5 -cryptography >= 3.4.8 \ No newline at end of file +cryptography >= 3.4.8 +mplfinance +schedule \ No newline at end of file diff --git a/test_binance.py b/test_binance.py new file mode 100644 index 0000000..ac3da6e --- /dev/null +++ b/test_binance.py @@ -0,0 +1,39 @@ +import requests +import json +from datetime import datetime + +# API 端点:币安现货 K 线数据 +base_url = "https://api.binance.com" +endpoint = "/api/v3/klines" + +# 参数设置 +symbol = "ETHUSDT" # 交易对:ETH-USDT +interval = "5m" # 时间间隔:5 分钟 +limit = 100 # 获取最近 100 条 K 线(可根据需要调整,最大 1000) + +params = { + "symbol": symbol, + "interval": interval, + "limit": limit +} + +# 发送 GET 请求 +response = requests.get(base_url + endpoint, params=params) + +# 检查响应状态 +if response.status_code == 200: + data = response.json() + + # 输出最近 5 条 K 线数据作为示例(每条数据格式:[开盘时间, 开盘价, 最高价, 最低价, 收盘价, 成交量, 收盘时间, 报价成交量, 成交笔数, 主动买入成交量, 主动买入报价成交量, 忽略]) + print("最近 5 条 5 分钟 K 线数据 (ETH-USDT):") + print(json.dumps(data[-5:], indent=4, ensure_ascii=False)) + + # 可选:转换为更易读的格式 + print("\n转换为易读格式(时间为 UTC):") + for kline in data[-5:]: + open_time = datetime.fromtimestamp(kline[0] / 1000).strftime('%Y-%m-%d %H:%M:%S') + close_time = datetime.fromtimestamp(kline[6] / 1000).strftime('%Y-%m-%d %H:%M:%S') + print(f"时间: {open_time} - {close_time}, " + f"开: {kline[1]}, 高: {kline[2]}, 低: {kline[3]}, 收: {kline[4]}, 量: {kline[5]}") +else: + print(f"请求失败,状态码: {response.status_code}, 错误信息: {response.text}") \ No newline at end of file diff --git a/trade_sandbox_main.py b/trade_sandbox_main.py index 59a9f04..98ec3ba 100644 --- a/trade_sandbox_main.py +++ b/trade_sandbox_main.py @@ -5,7 +5,8 @@ import numpy as np import matplotlib.pyplot as plt import seaborn as sns from matplotlib.ticker import PercentFormatter -from datetime import datetime +from datetime import datetime, timezone, timedelta +from core.utils import get_current_date_time import re from openpyxl import Workbook from openpyxl.drawing.image import Image @@ -68,7 +69,7 @@ class MeanReversionSandboxMain: stat_data = self.statistic_data(total_data) excel_save_path = os.path.join(self.save_path, solution, "excel") os.makedirs(excel_save_path, exist_ok=True) - date_time_str = datetime.now().strftime("%Y%m%d%H%M%S") + date_time_str = get_current_date_time() excel_file_path = os.path.join( excel_save_path, f"{solution}_{date_time_str}.xlsx" ) @@ -301,7 +302,7 @@ class MeanReversionSandboxMain: if __name__ == "__main__": start_date = "2025-05-15 00:00:00" - end_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + end_date = get_current_date_time() solution_list = ["solution_3"] mean_reversion_sandbox_main = MeanReversionSandboxMain( start_date=start_date, end_date=end_date, window_size=100, only_5m=True, solution_list=solution_list