[update] RestAPI更新、基础组件更新、T.D.X下载更新
This commit is contained in:
parent
6826564622
commit
ac1c90aa42
@ -110,9 +110,21 @@ if __name__ == "__main__":
|
||||
# 更新数量
|
||||
grid['volume'] = adj_volume
|
||||
|
||||
# 更新开仓\平仓\止损价格
|
||||
open_price = grid['open_price']
|
||||
new_open_price = round(float(open_price * adj_rate), 3)
|
||||
close_price = grid['close_price']
|
||||
new_close_price = round(float(close_price * adj_rate), 3)
|
||||
stop_price = grid['stop_price']
|
||||
new_stop_price = round(float(stop_price * adj_rate), 3)
|
||||
|
||||
# 更新执行日期
|
||||
grid['snapshot'].update({'adjusted_date': dividOperateDate})
|
||||
msg = f'{strategy_name}:{vt_symbol}[{name}]发生除权调整:{cur_volume}=>{adj_volume}'
|
||||
msg = f'{strategy_name}:{vt_symbol}[{name}]发生除权调整:持仓{cur_volume}=>{adj_volume},' \
|
||||
f'开仓价:{open_price}=>{new_open_price},' \
|
||||
f'平仓价:{close_price}=>{new_close_price},' \
|
||||
f'止损价:{stop_price}=>{new_stop_price}'
|
||||
|
||||
send_wx_msg(msg)
|
||||
print(msg)
|
||||
append_data(adj_record_file, dict_data={
|
||||
@ -126,8 +138,8 @@ if __name__ == "__main__":
|
||||
'pre_back_adj': pre_data.get('backAdjustFactor'),
|
||||
'last_back_adj': last_data.get('backAdjustFactor')
|
||||
})
|
||||
changed = True
|
||||
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
print('保存更新后的Grids.json文件')
|
||||
|
@ -107,7 +107,7 @@ def refill(symbol_info):
|
||||
data_df = data_df.sort_index()
|
||||
# print(data_df.head())
|
||||
print(data_df.tail())
|
||||
data_df.to_csv(bar_file_path, index=True)
|
||||
data_df.to_csv(bar_file_path, index=True, encoding='utf8')
|
||||
d2 = datetime.now()
|
||||
microseconds = (d1 - d1).microseconds
|
||||
print(f'{progress}% 首次更新{stock_code} {stock_name}数据 {microseconds} 毫秒=> 文件{bar_file_path}')
|
||||
@ -176,8 +176,11 @@ if __name__ == '__main__':
|
||||
for symbol in symbol_dict.keys():
|
||||
info = copy(symbol_dict[symbol])
|
||||
stock_code = info['code']
|
||||
if ('stock_type' in info.keys() and info['stock_type'] in ['stock_cn',
|
||||
'cb_cn']) or stock_code in stock_list:
|
||||
|
||||
# 股票/可转债; 或 存在指定下载文件中
|
||||
if ('stock_type' in info.keys() \
|
||||
and info['stock_type'] in ['stock_cn', 'cb_cn']) \
|
||||
or stock_code in stock_list:
|
||||
info['period'] = period
|
||||
tasks.append(info)
|
||||
# if len(tasks) > 12:
|
||||
|
@ -46,6 +46,7 @@ class Request(object):
|
||||
params: dict,
|
||||
data: Union[dict, str, bytes],
|
||||
headers: dict,
|
||||
cookies: Union[requests.cookies.RequestsCookieJar, dict]=None,
|
||||
callback: CALLBACK_TYPE = None,
|
||||
on_failed: ON_FAILED_TYPE = None,
|
||||
on_error: ON_ERROR_TYPE = None,
|
||||
@ -61,7 +62,7 @@ class Request(object):
|
||||
self.params = params
|
||||
self.data = data
|
||||
self.headers = headers
|
||||
|
||||
self.cookies = cookies
|
||||
self.stream = stream
|
||||
self.on_connected = on_connected
|
||||
self.processing_line: Optional[str] = ''
|
||||
@ -258,6 +259,7 @@ class RestClient(object):
|
||||
params: dict = None,
|
||||
data: Union[dict, str, bytes] = None,
|
||||
headers: dict = None,
|
||||
cookies: Union[requests.cookies.RequestsCookieJar, dict]=None,
|
||||
on_failed: ON_FAILED_TYPE = None,
|
||||
on_error: ON_ERROR_TYPE = None,
|
||||
extra: Any = None,
|
||||
@ -281,6 +283,7 @@ class RestClient(object):
|
||||
params=params,
|
||||
data=data,
|
||||
headers=headers,
|
||||
cookies=cookies,
|
||||
callback=callback,
|
||||
on_failed=on_failed,
|
||||
on_error=on_error,
|
||||
@ -416,6 +419,7 @@ class RestClient(object):
|
||||
headers = request.headers
|
||||
params = request.params
|
||||
data = request.data
|
||||
cookies = request.cookies
|
||||
self._log("[%s] sending request %s %s, headers:%s, params:%s, data:%s",
|
||||
uid, method, url,
|
||||
headers, params, data)
|
||||
@ -425,6 +429,7 @@ class RestClient(object):
|
||||
headers=headers,
|
||||
params=params,
|
||||
data=data,
|
||||
cookies=cookies,
|
||||
proxies=self.proxies,
|
||||
stream=stream,
|
||||
)
|
||||
@ -498,6 +503,7 @@ class RestClient(object):
|
||||
params: dict = None,
|
||||
data: dict = None,
|
||||
headers: dict = None,
|
||||
cookies: Union[requests.cookies.RequestsCookieJar, dict]=None
|
||||
):
|
||||
"""
|
||||
Add a new request.
|
||||
@ -514,6 +520,7 @@ class RestClient(object):
|
||||
params,
|
||||
data,
|
||||
headers,
|
||||
cookies=cookies,
|
||||
client=self,
|
||||
)
|
||||
request = self.sign(request)
|
||||
@ -526,6 +533,7 @@ class RestClient(object):
|
||||
headers=request.headers,
|
||||
params=request.params,
|
||||
data=request.data,
|
||||
proxies=self.proxies,
|
||||
cookies=request.cookies,
|
||||
proxies=self.proxies
|
||||
)
|
||||
return response
|
||||
|
@ -367,10 +367,10 @@ class BackTestingEngine(object):
|
||||
self.volume_tick.update({vt_symbol: volume_tick})
|
||||
|
||||
def get_volume_tick(self, vt_symbol: str):
|
||||
return self.volume_tick.get(vt_symbol, 1)
|
||||
return self.volume_tick.get(vt_symbol, 100)
|
||||
|
||||
def set_contract(self, symbol: str, exchange: Exchange, product: Product, name: str, size: int,
|
||||
price_tick: float, volume_tick: float = 1, margin_rate: float = 0.1):
|
||||
price_tick: float, volume_tick: float = 100, margin_rate: float = 0.1):
|
||||
"""设置合约信息"""
|
||||
vt_symbol = '.'.join([symbol, exchange.value])
|
||||
if vt_symbol not in self.contract_dict:
|
||||
@ -580,7 +580,7 @@ class BackTestingEngine(object):
|
||||
product=Product(symbol_data.get('product', "股票")),
|
||||
size=symbol_data.get('symbol_size', 1),
|
||||
price_tick=symbol_data.get('price_tick', 0.01),
|
||||
volume_tick=symbol_data.get('min_volume', 10),
|
||||
volume_tick=symbol_data.get('min_volume', 100),
|
||||
margin_rate=margin_rate
|
||||
)
|
||||
|
||||
|
@ -1825,7 +1825,8 @@ class CtaProFutureTemplate(CtaProTemplate):
|
||||
self.write_log(u'撤单逻辑 => 重新开仓')
|
||||
# 开空委托单
|
||||
if order_info['direction'] == Direction.SHORT:
|
||||
short_price = self.cur_mi_price - self.price_tick
|
||||
cur_price = self.cta_engine.get_price(order_vt_symbol)
|
||||
short_price = cur_price - self.price_tick
|
||||
if order_grid.volume != order_volume and order_volume > 0:
|
||||
self.write_log(
|
||||
u'网格volume:{},order_volume:{}不一致,修正'.format(order_grid.volume, order_volume))
|
||||
@ -1845,7 +1846,8 @@ class CtaProFutureTemplate(CtaProTemplate):
|
||||
else:
|
||||
self.write_error(u'撤单后,重新委托开空仓失败')
|
||||
else:
|
||||
buy_price = self.cur_mi_price + self.price_tick
|
||||
cur_price = self.cta_engine.get_price(order_vt_symbol)
|
||||
buy_price = cur_price + self.price_tick
|
||||
if order_grid.volume != order_volume and order_volume > 0:
|
||||
self.write_log(
|
||||
u'网格volume:{},order_volume:{}不一致,修正'.format(order_grid.volume, order_volume))
|
||||
|
@ -16,7 +16,7 @@ from datetime import datetime
|
||||
import pandas as pd
|
||||
import traceback
|
||||
|
||||
from vnpy.component.cta_line_bar import CtaHourBar
|
||||
from vnpy.component.cta_line_bar import CtaMinuteBar, CtaHourBar, CtaDayBar, CtaLineBar, get_cta_bar_type
|
||||
from vnpy.component.cta_renko_bar import CtaRenkoBar
|
||||
from vnpy.trader.object import BarData, TickData
|
||||
from vnpy.trader.utility import get_folder_path, get_trading_date
|
||||
@ -60,9 +60,12 @@ class FundKline(object):
|
||||
self.write_log(u'使用CtaRenkoBar')
|
||||
self.kline = CtaRenkoBar(strategy=self, cb_on_bar=self.on_bar, setting=self.setting)
|
||||
else:
|
||||
self.write_log(u'使用CtaHourBar')
|
||||
self.kline = CtaHourBar(strategy=self, cb_on_bar=self.on_bar, setting=self.setting)
|
||||
# self.kline = CtaDayBar(strategy=self, onBarFunc=self.onBar, setting=self.setting)
|
||||
kline_setting = self.setting
|
||||
kline_period = kline_setting.pop('kline_period', 'H1') # 默认使用1小时K线
|
||||
kline_class, kline_bar_interval = get_cta_bar_type(kline_period)
|
||||
self.write_log(u'使用{}'.format(kline_period))
|
||||
kline_setting['bar_interval'] = kline_bar_interval # X分钟K线, X秒K线,X小时K线
|
||||
self.kline = kline_class(strategy=self, cb_on_bar=self.on_bar, setting=kline_setting)
|
||||
self.inited = False
|
||||
|
||||
self.long_pos_dict = {}
|
||||
|
@ -6240,13 +6240,14 @@ class CtaLineBar(object):
|
||||
if bi_len < 3:
|
||||
return
|
||||
|
||||
if self.cur_fenxing.is_rt:
|
||||
return
|
||||
# if self.cur_fenxing.is_rt:
|
||||
# return
|
||||
|
||||
bi_n = min(15, bi_len)
|
||||
|
||||
price = self.cur_bi.low if self.cur_bi.direction == -1 else self.cur_bi.high
|
||||
|
||||
# 计算 3,5,7,,,,13笔的形态
|
||||
for n in range(3, bi_n, 2):
|
||||
# => 信号
|
||||
if n == 3:
|
||||
@ -6294,7 +6295,7 @@ class CtaLineBar(object):
|
||||
'end': self.cur_bi.end,
|
||||
'price': price,
|
||||
'signal': qsbc_2nd})
|
||||
if cur_signal and self.export_xt_filename:
|
||||
if cur_signal is not None and self.export_xt_filename:
|
||||
self.append_data(
|
||||
file_name=self.export_xt_filename.replace('_n_', f'_2nd_'),
|
||||
dict_data=cur_signal,
|
||||
@ -6304,6 +6305,23 @@ class CtaLineBar(object):
|
||||
else:
|
||||
self.xt_2nd_signals[-1].update({'end': self.cur_bi.end, 'price': price, 'signal': qsbc_2nd})
|
||||
|
||||
def get_xt_signal(self, xt_name, x=0):
|
||||
"""
|
||||
获取n笔形态/信号的倒x笔结果
|
||||
:param n:
|
||||
:param x: 倒x笔,如倒1笔
|
||||
:return: {}
|
||||
"""
|
||||
xt_signals = getattr(self, xt_name)
|
||||
if xt_signals is None:
|
||||
return {}
|
||||
|
||||
if len(xt_signals) > x:
|
||||
return xt_signals[-1-x]
|
||||
else:
|
||||
return {}
|
||||
|
||||
|
||||
def write_log(self, content):
|
||||
"""记录CTA日志"""
|
||||
self.strategy.write_log(u'[' + self.name + u']' + content)
|
||||
|
@ -96,7 +96,7 @@ def check_bi_not_rt(kline, direction: Direction) -> bool:
|
||||
and kline.cur_fenxing.index == kline.index_list[-1] \
|
||||
and kline.line_bar[-1].datetime.strftime('%Y-%m-%d %H:%M:%S') > kline.cur_fenxing.index \
|
||||
and kline.line_bar[-1].low_price > float(kline.cur_fenxing.low) \
|
||||
and kline.line_bar[-1].high_price < kline.line_bar[-2].high_price:
|
||||
and kline.line_bar[-1].high_price > kline.line_bar[-2].high_price:
|
||||
return True
|
||||
|
||||
return False
|
||||
@ -382,7 +382,7 @@ def check_chan_xt_five_bi(kline, bi_list: List[ChanObject]):
|
||||
|
||||
# 五笔三买,要求bi_5.high是最高点, 或者bi_4.height,超过笔2、笔3两倍
|
||||
if min_low < max(bi_1.low, bi_3.low) < min(bi_1.high, bi_3.high) < bi_5.low:
|
||||
if bi_5.high == max_high:
|
||||
if bi_5.high == max_high: # and max(bi_1.high, bi_3.high) < bi_5.low
|
||||
v = ChanSignals.LI0.value # 类三买, 五笔
|
||||
elif bi_3.low == min_low and bi_1.high == max_high \
|
||||
and bi_4.height > max(bi_1.height, bi_2.height, bi_3.height) \
|
||||
@ -418,7 +418,7 @@ def check_chan_xt_five_bi(kline, bi_list: List[ChanObject]):
|
||||
|
||||
# 五笔三卖,要求bi_5.low是最低点,中枢可能是1~3
|
||||
if min(bi_1.high, bi_3.high) > max(bi_1.low, bi_3.low) > bi_5.high:
|
||||
if bi_5.low == min_low:
|
||||
if bi_5.low == min_low: # and min(bi_1.low, bi_3.low) > bi_5.high
|
||||
return ChanSignals.SI0.value
|
||||
elif bi_3.high == max_high and bi_1.low == min_low \
|
||||
and bi_4.height > max(bi_1.height, bi_2.height, bi_3.height) \
|
||||
@ -572,7 +572,7 @@ def check_chan_xt_nine_bi(kline, bi_list: List[ChanObject]):
|
||||
and min(bi_2.high, bi_4.high) > max(bi_2.low, bi_4.low) > bi_6.high \
|
||||
and min(bi_6.high, bi_8.high) > max(bi_6.low, bi_8.low) \
|
||||
and min(bi_2.low, bi_4.low) > max(bi_6.high, bi_8.high) \
|
||||
and bi_9.height < bi_5.height and bi_9.atan <= bi_5.atan:
|
||||
and (bi_9.height < bi_5.height or bi_9.atan <= bi_5.atan):
|
||||
return ChanSignals.Q1L0.value # k3='类买卖点', v1='类一买', v2='九笔aAb式')
|
||||
|
||||
# 九笔GG 类三买(1357构成中枢,最低点在3或5)
|
||||
@ -639,7 +639,7 @@ def check_chan_xt_nine_bi(kline, bi_list: List[ChanObject]):
|
||||
and bi_6.low > min(bi_2.high, bi_4.high) > max(bi_2.low, bi_4.low) \
|
||||
and min(bi_6.high, bi_8.high) > max(bi_6.low, bi_8.low) \
|
||||
and max(bi_2.high, bi_4.high) < min(bi_6.low, bi_8.low) \
|
||||
and bi_9.height < bi_5.height and bi_9.atan <= bi_5.atan:
|
||||
and (bi_9.height < bi_5.height or bi_9.atan <= bi_5.atan):
|
||||
return ChanSignals.Q1S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一卖', v2='九笔aAbBc式')
|
||||
|
||||
# 九笔类三卖
|
||||
@ -812,7 +812,7 @@ def check_chan_xt_thirteen_bi(kline, bi_list: List[ChanObject]):
|
||||
if direction == -1:
|
||||
if min_low == bi_13.low and max_high == bi_1.high:
|
||||
# ABC式类一买,A5B3C5
|
||||
if bi_5.low < min(bi_1.low, bi_3.low) and bi_9.high > max(bi_11.high, bi_13.high) \
|
||||
if bi_5.low < max(bi_1.low, bi_3.low) and bi_9.high > max(bi_11.high, bi_13.high) \
|
||||
and bi_8.high > bi_6.low and bi_1.high - bi_5.low > bi_9.high - bi_13.low:
|
||||
return ChanSignals.Q1L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一买', v2="13笔A5B3C5式")
|
||||
|
||||
@ -827,12 +827,13 @@ def check_chan_xt_thirteen_bi(kline, bi_list: List[ChanObject]):
|
||||
and min(bi_6.high, bi_8.high, bi_10.high) > max(bi_6.low, bi_8.low, bi_10.low) \
|
||||
and bi_1.high - bi_5.low > bi_11.high - bi_13.low:
|
||||
return ChanSignals.Q1L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一买', v2="13笔A5B5C3式")
|
||||
# AB式底背驰, aAbBc
|
||||
|
||||
# 上涨线段时,判断背驰类型
|
||||
elif direction == 1:
|
||||
if max_high == bi_13.high and min_low == bi_1.low:
|
||||
# ABC式顶背驰,A5B3C5
|
||||
if bi_5.high > max(bi_3.high, bi_1.high) and bi_9.low < min(bi_11.low, bi_13.low) \
|
||||
if bi_5.high > min(bi_3.high, bi_1.high) and bi_9.low < min(bi_11.low, bi_13.low) \
|
||||
and bi_8.low < bi_6.high and bi_5.high - bi_1.low > bi_13.high - bi_9.low:
|
||||
return ChanSignals.Q1S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一卖', v2="13笔A5B3C5式")
|
||||
|
||||
|
@ -16,6 +16,8 @@ import pickle
|
||||
import bz2
|
||||
import traceback
|
||||
import pandas as pd
|
||||
import random
|
||||
from time import sleep
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from logging import ERROR
|
||||
@ -349,6 +351,7 @@ class TdxStockData(object):
|
||||
if len(_bars) == 0:
|
||||
self.write_error('{} Handling {}, len1={}..., continue'.format(
|
||||
str(datetime.now()), tdx_code, len(_bars)))
|
||||
sleep(3 * random.random())
|
||||
return False, ret_bars
|
||||
|
||||
current_datetime = datetime.now()
|
||||
|
@ -92,7 +92,7 @@ class MainEngine:
|
||||
# 缺省使用了接口自己定义的gateway_name
|
||||
gateway = gateway_class(self.event_engine)
|
||||
gateway_name = gateway.gateway_name
|
||||
|
||||
self.write_log(f'添加{gateway_name}网关')
|
||||
self.gateways[gateway_name] = gateway
|
||||
|
||||
# Add gateway supported exchanges into engine
|
||||
|
@ -1563,9 +1563,12 @@ class GridKline(QtWidgets.QWidget):
|
||||
|
||||
# 配置项12: bi_file / duan_file / bi_zs_file / duan_zs_file,支持缠论的画线
|
||||
|
||||
def __init__(self, parent=None, kline_settings={}, title='', relocate=True):
|
||||
def __init__(self, parent=None, kline_settings={}, title='', relocate=True,screen_file=""):
|
||||
self.parent = parent
|
||||
super(GridKline, self).__init__(parent)
|
||||
self.width = 1920
|
||||
self.height = 1080
|
||||
|
||||
# widget的标题
|
||||
if title:
|
||||
self.setWindowTitle(title)
|
||||
@ -1590,6 +1593,9 @@ class GridKline(QtWidgets.QWidget):
|
||||
self.setLayout(self.grid_layout)
|
||||
|
||||
self.relocate = relocate
|
||||
|
||||
self.screen_file = screen_file
|
||||
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
@ -1598,13 +1604,14 @@ class GridKline(QtWidgets.QWidget):
|
||||
id = 1
|
||||
|
||||
for kline_name, kline_setting in self.kline_settings.items():
|
||||
canvas = getattr(self, f'canvas_{id}')
|
||||
canvas = getattr(self, f'canvas_{id}',None)
|
||||
if id > 8:
|
||||
print(f'最多支持8个K线同时展现', file=sys.stderr)
|
||||
continue
|
||||
|
||||
if canvas is None:
|
||||
# 创建K线图表
|
||||
canvas = KLineWidget(display_vol=False, display_sub=True)
|
||||
setattr(self, f'canvas_{id}', canvas)
|
||||
canvas.show()
|
||||
# K线标题
|
||||
canvas.KLtitle.setText(f'{kline_name}', size='18pt')
|
||||
@ -1644,11 +1651,16 @@ class GridKline(QtWidgets.QWidget):
|
||||
if len(kline_names) == 0:
|
||||
break
|
||||
row += 1
|
||||
|
||||
if len(self.screen_file) == 0:
|
||||
self.show()
|
||||
|
||||
self.load_multi_kline()
|
||||
|
||||
if len(self.screen_file) > 0:
|
||||
p = self.grab()
|
||||
p.save(self.screen_file,'png')
|
||||
self.close()
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def load_multi_kline(self):
|
||||
"""加载多周期窗口"""
|
||||
|
@ -10,8 +10,9 @@ import ctypes
|
||||
import bz2
|
||||
import pickle
|
||||
import zlib
|
||||
from time import sleep
|
||||
import pandas as pd
|
||||
|
||||
from pyqtgraph import QtGui
|
||||
from vnpy.trader.ui.kline.crosshair import Crosshair
|
||||
from vnpy.trader.ui.kline.kline import *
|
||||
|
||||
@ -29,7 +30,8 @@ class UiSnapshot(object):
|
||||
tns_file: str = "",
|
||||
dist_file: str = "",
|
||||
dist_include_list=[],
|
||||
use_grid=True):
|
||||
use_grid=True,
|
||||
export_file=""):
|
||||
"""
|
||||
显示切片
|
||||
:param snapshot_file: 切片文件路径(通过这个方法,可读取历史切片)
|
||||
@ -119,14 +121,38 @@ class UiSnapshot(object):
|
||||
k: setting
|
||||
}
|
||||
)
|
||||
# K线界面
|
||||
|
||||
try:
|
||||
if len(export_file) == 0:
|
||||
# K线界面
|
||||
if use_grid:
|
||||
w = GridKline(kline_settings=kline_settings, title=d.get('strategy', ''), relocate=True)
|
||||
w.showMaximized()
|
||||
else:
|
||||
w = MultiKlineWindow(kline_settings=kline_settings, title=d.get('strategy', ''))
|
||||
w.showMaximized()
|
||||
|
||||
else:
|
||||
w = GridKline(kline_settings=kline_settings, title=d.get('strategy',''),relocate=False,screen_file=export_file)
|
||||
print('sleep')
|
||||
sleep(1)
|
||||
print('close')
|
||||
w.close()
|
||||
except Exception as ex:
|
||||
print(u'exception:{},trace:{}'.format(str(ex), traceback.format_exc()))
|
||||
|
||||
def export(self,
|
||||
snapshot_file: str,
|
||||
d: dict = None,
|
||||
trade_file: str = "",
|
||||
tns_file: str = "",
|
||||
dist_file: str = "",
|
||||
dist_include_list=[],
|
||||
export_file:str=""
|
||||
):
|
||||
|
||||
self.show(snapshot_file=snapshot_file,
|
||||
d=d,
|
||||
trade_file=trade_file,
|
||||
dist_file=dist_file,
|
||||
dist_include_list=dist_include_list,
|
||||
export_file=export_file)
|
||||
|
@ -350,7 +350,7 @@ def get_csv_last_dt(file_name, dt_index=0, dt_format='%Y-%m-%d %H:%M:%S', line_l
|
||||
if not os.path.exists(file_name):
|
||||
return False
|
||||
|
||||
with open(file_name, 'r') as f:
|
||||
with open(file_name, 'r', encoding='utf8') as f:
|
||||
f_size = os.path.getsize(file_name)
|
||||
if f_size < line_length:
|
||||
line_length = f_size
|
||||
|
Loading…
Reference in New Issue
Block a user