This commit is contained in:
27942
2026-02-25 02:09:23 +08:00
parent e83d15f127
commit df9d4a069b
17 changed files with 2400 additions and 16 deletions

View File

@@ -0,0 +1,904 @@
import time
import json
from datetime import datetime
from pathlib import Path
from tqdm import tqdm
from loguru import logger
from bit_tools import openBrowser
from DrissionPage import ChromiumPage
from DrissionPage import ChromiumOptions
from bitmart.api_contract import APIContract
PRECOMPUTED_TRADE_PARAMS = {
# 你已经算好参数时,把 enabled 改成 True并在下面填入你的值。
# 直接运行本文件即可生效,不需要任何命令行参数。
"enabled": False,
"params": {}
}
class BitmartFuturesTransaction:
def __init__(self, bit_id):
self.page: ChromiumPage | None = None
self.api_key = "6104088c65a68d7e53df5d9395b67d78e555293a"
self.secret_key = "a8b14312330d8e6b9b09acfd972b34e32022fdfa9f2b06f0a0a31723b873fd01"
self.memo = "me"
self.contract_symbol = "ETHUSDT"
self.contractAPI = APIContract(self.api_key, self.secret_key, self.memo, timeout=(5, 15))
self.start = 0 # 持仓状态: -1 空, 0 无, 1 多
self.pbar = tqdm(total=30, desc="等待K线", ncols=80) # 可选:用于长时间等待时展示进度
self.last_kline_time = None # 上一次处理的K线时间戳用于判断是否是新K线
# 反手频率控制
self.reverse_cooldown_seconds = 1.5 * 60 # 反手冷却时间(秒)
self.last_reverse_time = None # 上次反手时间
self.last_reverse_kline_id = None # 已反手过的 K 线 id该 K 线内不再操作仓位
# 开仓频率控制
self.open_cooldown_seconds = 60 # 开仓冷却时间(秒),两次开仓至少间隔此时长
self.last_open_time = None # 上次开仓时间
self.last_open_kline_id = None # 上次开仓所在 K 线 id同一根 K 线只允许开仓一次
self.leverage = "40" # 高杠杆(全仓模式下可开更大仓位)
self.open_type = "cross" # 全仓模式
self.risk_percent = 0 # 未使用;若启用则可为每次开仓占可用余额的百分比
self.open_avg_price = None # 开仓价格
self.current_amount = None # 持仓量
self.bit_id = bit_id
self.default_order_size = 25 # 开仓/反手张数,统一在此修改
# 策略相关变量
self.prev_kline = None # 上一根K线
self.current_kline = None # 当前K线
self.prev_entity = None # 上一根K线实体大小
self.current_open = None # 当前K线开盘价
# 策略优化参数
self.min_prev_entity_pct = 0.1 # 上一根K线实体涨幅%),仅当实体涨幅 > 此值才用作“上一根”
# 自动止盈基于当前K线振幅四等分多仓用 open~high空仓用 open~low
self.take_profit_close_quartile = 3 # 达到极值后,回到 3/4 位置平仓
self.take_profit_reentry_quartile = 2 # 止盈后,继续回到 2/4 位置同向再开仓
self.take_profit_triggered_kline_id = None # 多仓本K线内是否出现过 open~high 的极值触发
self.take_profit_reentry_threshold = None # 多仓止盈平仓后,价格 <= 此值则开多(同向)
self.take_profit_triggered_kline_id_short = None # 空仓本K线内是否出现过 open~low 的极值触发
self.take_profit_reentry_threshold_short = None # 空仓止盈平仓后,价格 >= 此值则开空(同向)
self.last_take_profit_kline_id = None # 本K线已止盈一次不区分多空则不再止盈
self.optimized_params_file = Path(__file__).resolve().parent / "atr_best_params.json"
self.strategy_log_dir = Path(__file__).resolve().parent # 策略开仓日志目录
self.apply_precomputed_params()
self.load_optimized_params()
def get_klines(self):
"""获取最近2根K线当前K线和上一根K线"""
try:
end_time = int(time.time())
# 获取足够多的条目确保有最新的K线
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=15, # 15分钟
start_time=end_time - 3600 * 9, # 取最近9小时与原5分钟*3小时接近的样本量
end_time=end_time
)[0]["data"]
# 每根: [timestamp, open, high, low, close, volume]
formatted = []
for k in response:
formatted.append({
'id': int(k["timestamp"]),
'open': float(k["open_price"]),
'high': float(k["high_price"]),
'low': float(k["low_price"]),
'close': float(k["close_price"])
})
formatted.sort(key=lambda x: x['id'])
# 返回最近多根K线列表供主循环按「实体涨幅>0.1%」向前选取上一根
if len(formatted) >= 2:
return formatted
return None
except Exception as e:
logger.error(f"获取K线异常: {e}")
self.ding(text="获取K线异常", error=True)
return None
def get_current_price(self):
"""获取当前最新价格"""
try:
end_time = int(time.time())
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=1, # 1分钟
start_time=end_time - 3600 * 1, # 取最近1小时
end_time=end_time
)[0]
if response['code'] == 1000:
return float(response['data'][-1]["close_price"])
return None
except Exception as e:
logger.error(f"获取价格异常: {e}")
return None
def get_available_balance(self):
"""获取合约账户可用USDT余额"""
try:
response = self.contractAPI.get_assets_detail()[0]
if response['code'] == 1000:
data = response['data']
if isinstance(data, dict):
return float(data.get('available_balance', 0))
elif isinstance(data, list):
for asset in data:
if asset.get('currency') == 'USDT':
return float(asset.get('available_balance', 0))
return None
except Exception as e:
logger.error(f"余额查询异常: {e}")
return None
def get_position_status(self):
"""获取当前持仓方向"""
try:
response = self.contractAPI.get_position(contract_symbol=self.contract_symbol)[0]
if response['code'] == 1000:
positions = response['data']
if not positions:
self.start = 0
self.open_avg_price = None
self.current_amount = None
self.unrealized_pnl = None
return True
pos = positions[0]
self.start = 1 if pos['position_type'] == 1 else -1
self.open_avg_price = float(pos['open_avg_price'])
self.current_amount = float(pos['current_amount'])
self.position_cross = pos["position_cross"]
# 直接从API获取未实现盈亏Bitmart返回的是 unrealized_value 字段)
self.unrealized_pnl = float(pos.get('unrealized_value', 0))
logger.debug(f"持仓详情: 方向={self.start}, 开仓均价={self.open_avg_price}, "
f"持仓量={self.current_amount}, 未实现盈亏={self.unrealized_pnl:.2f}")
return True
else:
return False
except Exception as e:
logger.error(f"持仓查询异常: {e}")
return False
def get_unrealized_pnl_usd(self):
"""
获取当前持仓未实现盈亏美元直接使用API返回值
"""
if self.start == 0 or self.unrealized_pnl is None:
return None
return self.unrealized_pnl
def set_leverage(self):
"""程序启动时设置全仓 + 高杠杆"""
try:
response = self.contractAPI.post_submit_leverage(
contract_symbol=self.contract_symbol,
leverage=self.leverage,
open_type=self.open_type
)[0]
if response['code'] == 1000:
logger.success(f"全仓模式 + {self.leverage}x 杠杆设置成功")
return True
else:
logger.error(f"杠杆设置失败: {response}")
return False
except Exception as e:
logger.error(f"设置杠杆异常: {e}")
return False
def openBrowser(self):
"""打开 TGE 对应浏览器实例"""
try:
bit_port = openBrowser(id=self.bit_id)
co = ChromiumOptions()
co.set_local_port(port=bit_port)
self.page = ChromiumPage(addr_or_opts=co)
return True
except:
return False
def click_safe(self, xpath, sleep=0.5):
"""安全点击"""
try:
ele = self.page.ele(xpath)
if not ele:
return False
# ele.scroll.to_see(center=True)
# time.sleep(sleep)
ele.click(by_js=True)
return True
except:
return False
def 平仓(self):
"""平仓操作"""
self.click_safe('x://span[normalize-space(text()) ="市价"]')
def 开单(self, marketPriceLongOrder=0, limitPriceShortOrder=0, size=None, price=None):
"""
marketPriceLongOrder 市价做多或者做空1是做多-1是做空
limitPriceShortOrder 限价做多或者做空
"""
if marketPriceLongOrder == -1:
# self.click_safe('x://button[normalize-space(text()) ="市价"]')
# self.page.ele('x://*[@id="size_0"]').input(vals=size, clear=True)
self.click_safe('x://span[normalize-space(text()) ="卖出/做空"]')
elif marketPriceLongOrder == 1:
# self.click_safe('x://button[normalize-space(text()) ="市价"]')
# self.page.ele('x://*[@id="size_0"]').input(vals=size, clear=True)
self.click_safe('x://span[normalize-space(text()) ="买入/做多"]')
if limitPriceShortOrder == -1:
self.click_safe('x://button[normalize-space(text()) ="限价"]')
self.page.ele('x://*[@id="price_0"]').input(vals=price, clear=True)
time.sleep(1)
self.page.ele('x://*[@id="size_0"]').input(1)
self.click_safe('x://span[normalize-space(text()) ="卖出/做空"]')
elif limitPriceShortOrder == 1:
self.click_safe('x://button[normalize-space(text()) ="限价"]')
self.page.ele('x://*[@id="price_0"]').input(vals=price, clear=True)
time.sleep(1)
self.page.ele('x://*[@id="size_0"]').input(1)
self.click_safe('x://span[normalize-space(text()) ="买入/做多"]')
def ding(self, text, error=False):
"""日志通知"""
if error:
logger.error(text)
else:
logger.info(text)
def _log_take_profit_action(self, operation: str, reason: str):
"""止盈相关操作日志:时间、操作、原因"""
time_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
logger.info(f"[止盈日志] 时间={time_str} | 操作={operation} | 原因={reason}")
def _write_open_log(self, operation: str, reason: str, current_kline: dict, prev_kline: dict | None):
"""写入策略开仓日志文件时间、参考的两根K线、操作、开仓原因"""
try:
date_str = datetime.now().strftime("%Y%m%d")
log_file = self.strategy_log_dir / f"strategy_log_{date_str}.txt"
time_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
cur = current_kline
cur_line = f"id={cur['id']} open={cur['open']:.2f} high={cur['high']:.2f} low={cur['low']:.2f} close={cur['close']:.2f}"
if prev_kline:
prev = prev_kline
prev_line = f"id={prev['id']} open={prev['open']:.2f} high={prev['high']:.2f} low={prev['low']:.2f} close={prev['close']:.2f}"
else:
prev_line = "(无)"
block = (
f"\n{'='*60}\n"
f"时间: {time_str}\n"
f"操作: {operation}\n"
f"参考K线:\n 当前K线: {cur_line}\n 上一根K线: {prev_line}\n"
f"开仓原因: {reason}\n"
f"{'='*60}\n"
)
with open(log_file, "a", encoding="utf-8") as f:
f.write(block)
logger.info(f"已写入开仓日志: {log_file.name}")
except Exception as e:
logger.warning(f"写入开仓日志失败: {e}")
def load_optimized_params(self):
"""从本地优化结果文件加载参数(可选)。"""
try:
if PRECOMPUTED_TRADE_PARAMS.get("enabled"):
logger.info("已启用 PRECOMPUTED_TRADE_PARAMS跳过 atr_best_params.json 加载")
return
if not self.optimized_params_file.exists():
return
data = json.loads(self.optimized_params_file.read_text(encoding="utf-8"))
if data.get("apply_live") is not True:
logger.info(f"检测到优化参数文件但 apply_live != true跳过加载: {self.optimized_params_file}")
return
params = data.get("params_for_trade_py", data)
allow_keys = {"min_prev_entity_pct"}
applied = []
for key, val in params.items():
if key in allow_keys and hasattr(self, key):
setattr(self, key, val)
applied.append(key)
if applied:
logger.info(f"已加载优化参数文件: {self.optimized_params_file},字段数: {len(applied)}")
except Exception as e:
logger.warning(f"加载优化参数文件失败,将继续使用默认参数: {e}")
def apply_precomputed_params(self):
"""
直接应用本文件内预计算参数(不依赖命令)。
当 PRECOMPUTED_TRADE_PARAMS.enabled=True 时生效。
"""
try:
conf = PRECOMPUTED_TRADE_PARAMS or {}
if conf.get("enabled") is not True:
return
params = conf.get("params") or {}
if not isinstance(params, dict):
logger.warning("PRECOMPUTED_TRADE_PARAMS.params 不是字典,忽略")
return
allow_keys = {"min_prev_entity_pct"}
applied = []
for key, val in params.items():
if key in allow_keys and hasattr(self, key):
setattr(self, key, val)
applied.append(key)
logger.info(f"已应用文件内预计算参数,字段数: {len(applied)}")
except Exception as e:
logger.warning(f"应用文件内预计算参数失败,将继续使用默认参数: {e}")
def calculate_entity(self, kline):
"""计算K线实体大小绝对值"""
return abs(kline['close'] - kline['open'])
def get_entity_edge(self, kline):
"""获取K线实体边收盘价或开盘价取决于是阳线还是阴线"""
# 阳线(收盘>开盘):实体上边=收盘价,实体下边=开盘价
# 阴线(收盘<开盘):实体上边=开盘价,实体下边=收盘价
return {
'upper': max(kline['open'], kline['close']), # 实体上边
'lower': min(kline['open'], kline['close']) # 实体下边
}
def calc_long_take_profit_levels(self, current_kline):
"""
多仓止盈阈值(自动四等分):
基于当前K线 open~high 计算:
- extreme: high4/4 极值)
- close: open + 3/4 * (high-open)
- reentry: open + 2/4 * (high-open)
"""
k_open = float(current_kline['open'])
k_high = float(current_kline['high'])
if k_high <= k_open:
return None
move = k_high - k_open
close_threshold = k_open + move * (self.take_profit_close_quartile / 4)
reentry_threshold = k_open + move * (self.take_profit_reentry_quartile / 4)
return {
"open": k_open,
"extreme": k_high,
"close_threshold": close_threshold,
"reentry_threshold": reentry_threshold
}
def calc_short_take_profit_levels(self, current_kline):
"""
空仓止盈阈值(自动四等分):
基于当前K线 open~low 计算:
- extreme: low4/4 极值)
- close: open - 3/4 * (open-low)
- reentry: open - 2/4 * (open-low)
"""
k_open = float(current_kline['open'])
k_low = float(current_kline['low'])
if k_low >= k_open:
return None
move = k_open - k_low
close_threshold = k_open - move * (self.take_profit_close_quartile / 4)
reentry_threshold = k_open - move * (self.take_profit_reentry_quartile / 4)
return {
"open": k_open,
"extreme": k_low,
"close_threshold": close_threshold,
"reentry_threshold": reentry_threshold
}
def check_signal(self, current_price, prev_kline, current_kline):
"""
检查交易信号
返回: ('long', trigger_price) / ('short', trigger_price) / None
"""
# 计算上一根K线实体主循环已保证所选 prev 实体涨幅 > 0.1%
prev_entity = self.calculate_entity(prev_kline)
# 获取上一根K线的实体上下边
prev_entity_edge = self.get_entity_edge(prev_kline)
prev_entity_upper = prev_entity_edge['upper'] # 实体上边
prev_entity_lower = prev_entity_edge['lower'] # 实体下边
# 优化:以下两种情况以当前这根的开盘价作为计算基准
# 1) 上一根阳线 且 当前开盘价 > 上一根收盘价(跳空高开)
# 2) 上一根阴线 且 当前开盘价 < 上一根收盘价(跳空低开)
prev_is_bullish_for_calc = prev_kline['close'] > prev_kline['open']
prev_is_bearish_for_calc = prev_kline['close'] < prev_kline['open']
current_open_above_prev_close = current_kline['open'] > prev_kline['close']
current_open_below_prev_close = current_kline['open'] < prev_kline['close']
use_current_open_as_base = (prev_is_bullish_for_calc and current_open_above_prev_close) or (prev_is_bearish_for_calc and current_open_below_prev_close)
if use_current_open_as_base:
# 以当前K线开盘价为基准计算跳空时用当前开盘价参与计算
calc_lower = current_kline['open']
calc_upper = current_kline['open'] # 同一基准,上下三分之一对称
long_trigger = calc_lower + prev_entity / 3
short_trigger = calc_upper - prev_entity / 3
long_breakout = calc_upper + prev_entity / 3
short_breakout = calc_lower - prev_entity / 3
else:
# 原有计算方式
long_trigger = prev_entity_lower + prev_entity / 3 # 做多触发价 = 实体下边 + 实体/3下三分之一处
short_trigger = prev_entity_upper - prev_entity / 3 # 做空触发价 = 实体上边 - 实体/3上三分之一处
long_breakout = prev_entity_upper + prev_entity / 3 # 做多突破价 = 实体上边 + 实体/3
short_breakout = prev_entity_lower - prev_entity / 3 # 做空突破价 = 实体下边 - 实体/3
# 上一根阴线 + 当前阳线做多形态不按上一根K线上三分之一做空
prev_is_bearish = prev_kline['close'] < prev_kline['open']
current_is_bullish = current_kline['close'] > current_kline['open']
skip_short_by_upper_third = prev_is_bearish and current_is_bullish
# 上一根阳线 + 当前阴线做空形态不按上一根K线下三分之一做多
prev_is_bullish = prev_kline['close'] > prev_kline['open']
current_is_bearish = current_kline['close'] < current_kline['open']
skip_long_by_lower_third = prev_is_bullish and current_is_bearish
if use_current_open_as_base:
if prev_is_bullish_for_calc and current_open_above_prev_close:
logger.info(f"上一根阳线且当前开盘价({current_kline['open']:.2f})>上一根收盘价({prev_kline['close']:.2f}),以当前开盘价为基准计算")
else:
logger.info(f"上一根阴线且当前开盘价({current_kline['open']:.2f})<上一根收盘价({prev_kline['close']:.2f}),以当前开盘价为基准计算")
logger.info(f"当前价格: {current_price:.2f}, 上一根实体: {prev_entity:.4f}")
logger.info(f"上一根实体上边: {prev_entity_upper:.2f}, 下边: {prev_entity_lower:.2f}")
logger.info(f"做多触发价(下1/3): {long_trigger:.2f}, 做空触发价(上1/3): {short_trigger:.2f}")
logger.info(f"突破做多价(上1/3外): {long_breakout:.2f}, 突破做空价(下1/3外): {short_breakout:.2f}")
if skip_short_by_upper_third:
logger.info("上一根阴线+当前阳线(做多形态),不按上三分之一做空")
if skip_long_by_lower_third:
logger.info("上一根阳线+当前阴线(做空形态),不按下三分之一做多")
# 无持仓时检查开仓信号
if self.start == 0:
if current_price >= long_breakout and not skip_long_by_lower_third:
logger.info(
f"触发做多信号!价格 {current_price:.2f} >= 突破价(上1/3外) {long_breakout:.2f}"
)
return ('long', long_breakout)
elif current_price <= short_breakout and not skip_short_by_upper_third:
logger.info(
f"触发做空信号!价格 {current_price:.2f} <= 突破价(下1/3外) {short_breakout:.2f}"
)
return ('short', short_breakout)
# 持仓时检查反手信号
elif self.start == 1: # 持多仓
# 反手条件: 价格跌到上一根K线的上三分之一处做空触发价上一根阴线+当前阳线做多时跳过
if current_price <= short_trigger and not skip_short_by_upper_third:
logger.info(f"持多反手做空!价格 {current_price:.2f} <= 触发价(上1/3) {short_trigger:.2f}")
return ('reverse_short', short_trigger)
elif self.start == -1: # 持空仓
# 反手条件: 价格涨到上一根K线的下三分之一处做多触发价上一根阳线+当前阴线做空时跳过
if current_price >= long_trigger and not skip_long_by_lower_third:
logger.info(f"持空反手做多!价格 {current_price:.2f} >= 触发价(下1/3) {long_trigger:.2f}")
return ('reverse_long', long_trigger)
return None
def can_open(self, current_kline_id):
"""开仓前过滤:同一根 K 线只开一次 + 开仓冷却时间。仅用于 long/short 新开仓。"""
now = time.time()
if self.last_open_kline_id is not None and self.last_open_kline_id == current_kline_id:
logger.info(f"开仓频率控制:本 K 线({current_kline_id})已开过仓,跳过")
return False
if self.last_open_time is not None and now - self.last_open_time < self.open_cooldown_seconds:
remain = self.open_cooldown_seconds - (now - self.last_open_time)
logger.info(f"开仓冷却中,剩余 {remain:.0f}")
return False
return True
def can_reverse(self, current_price, trigger_price):
"""反手前过滤:冷却时间"""
now = time.time()
if self.last_reverse_time and now - self.last_reverse_time < self.reverse_cooldown_seconds:
remain = self.reverse_cooldown_seconds - (now - self.last_reverse_time)
logger.info(f"反手冷却中,剩余 {remain:.0f}")
return False
return True
def verify_no_position(self, max_retries=5, retry_interval=3):
"""
验证当前无持仓
返回: True 表示无持仓可以开仓False 表示有持仓不能开仓
"""
for i in range(max_retries):
if self.get_position_status():
if self.start == 0:
logger.info(f"确认无持仓,可以开仓")
return True
else:
logger.warning(
f"仍有持仓 (方向: {self.start}),等待 {retry_interval} 秒后重试 ({i + 1}/{max_retries})")
time.sleep(retry_interval)
else:
logger.warning(f"查询持仓状态失败,等待 {retry_interval} 秒后重试 ({i + 1}/{max_retries})")
time.sleep(retry_interval)
logger.error(f"经过 {max_retries} 次重试仍有持仓或查询失败,放弃开仓")
return False
def verify_position_direction(self, expected_direction):
"""
验证当前持仓方向是否与预期一致
expected_direction: 1 多仓, -1 空仓
返回: True 表示持仓方向正确False 表示不正确
"""
if self.get_position_status():
if self.start == expected_direction:
logger.info(f"持仓方向验证成功: {self.start}")
return True
else:
logger.warning(f"持仓方向不符: 期望 {expected_direction}, 实际 {self.start}")
return False
else:
logger.error("查询持仓状态失败")
return False
def execute_trade(self, signal, size=None):
"""执行交易。size 不传或为 None 时使用 default_order_size。"""
signal_type, trigger_price = signal
size = self.default_order_size if size is None else size
if signal_type == 'long':
# 开多前先确认无持仓
logger.info(f"准备开多,触发价: {trigger_price:.2f}")
if not self.get_position_status():
logger.error("开仓前查询持仓状态失败,放弃开仓")
return False
if self.start != 0:
logger.warning(f"开多前发现已有持仓 (方向: {self.start}),放弃开仓避免双向持仓")
return False
logger.info(f"确认无持仓,执行开多")
self.开单(marketPriceLongOrder=1, size=size)
time.sleep(3) # 等待订单执行
# 验证开仓是否成功
if self.verify_position_direction(1):
self.last_open_time = time.time()
self.last_open_kline_id = getattr(self, "_current_kline_id_for_open", None)
logger.success("开多成功")
return True
else:
logger.error("开多后持仓验证失败")
return False
elif signal_type == 'short':
# 开空前先确认无持仓
logger.info(f"准备开空,触发价: {trigger_price:.2f}")
if not self.get_position_status():
logger.error("开仓前查询持仓状态失败,放弃开仓")
return False
if self.start != 0:
logger.warning(f"开空前发现已有持仓 (方向: {self.start}),放弃开仓避免双向持仓")
return False
logger.info(f"确认无持仓,执行开空")
self.开单(marketPriceLongOrder=-1, size=size)
time.sleep(3) # 等待订单执行
# 验证开仓是否成功
if self.verify_position_direction(-1):
self.last_open_time = time.time()
self.last_open_kline_id = getattr(self, "_current_kline_id_for_open", None)
logger.success("开空成功")
return True
else:
logger.error("开空后持仓验证失败")
return False
elif signal_type == 'reverse_long':
# 平空 + 开多(反手做多):先平仓,确认无仓后再开多,避免双向持仓
logger.info(f"执行反手做多,触发价: {trigger_price:.2f}")
self.平仓()
time.sleep(1) # 给交易所处理平仓的时间
# 轮询确认已无持仓再开多(最多等约 10 秒)
for _ in range(10):
if self.get_position_status() and self.start == 0:
break
time.sleep(1)
if self.start != 0:
logger.warning("反手做多:平仓后仍有持仓,放弃本次开多")
return False
logger.info("已确认无持仓,执行开多")
self.开单(marketPriceLongOrder=1, size=size)
time.sleep(3)
if self.verify_position_direction(1):
logger.success("反手做多成功")
self.last_reverse_time = time.time()
time.sleep(20)
return True
else:
logger.error("反手做多后持仓验证失败")
return False
elif signal_type == 'reverse_short':
# 平多 + 开空(反手做空):先平仓,确认无仓后再开空
logger.info(f"执行反手做空,触发价: {trigger_price:.2f}")
self.平仓()
time.sleep(1)
for _ in range(10):
if self.get_position_status() and self.start == 0:
break
time.sleep(1)
if self.start != 0:
logger.warning("反手做空:平仓后仍有持仓,放弃本次开空")
return False
logger.info("已确认无持仓,执行开空")
self.开单(marketPriceLongOrder=-1, size=size)
time.sleep(3)
if self.verify_position_direction(-1):
logger.success("反手做空成功")
self.last_reverse_time = time.time()
time.sleep(20)
return True
else:
logger.error("反手做空后持仓验证失败")
return False
return False
def action(self):
"""主循环"""
logger.info("开始运行三分之一策略交易15分钟K线...")
# 启动时设置全仓高杠杆
if not self.set_leverage():
logger.error("杠杆设置失败,程序继续运行但可能下单失败")
return
page_start = True
while True:
if page_start:
# 打开浏览器
for i in range(5):
if self.openBrowser():
logger.info("浏览器打开成功")
break
else:
self.ding("打开浏览器失败!", error=True)
return
# 进入交易页面
self.page.get("https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT")
self.click_safe('x://button[normalize-space(text()) ="市价"]')
self.page.ele('x://*[@id="size_0"]').input(vals=25, clear=True)
page_start = False
try:
# 1. 获取K线数据当前K线=最后一根;上一根=从后往前第一根实体涨幅>0.1%的K线
formatted = self.get_klines()
if not formatted or len(formatted) < 2:
logger.warning("获取K线失败等待重试...")
time.sleep(5)
continue
current_kline = formatted[-1]
prev_kline = None
for i in range(len(formatted) - 2, -1, -1):
k = formatted[i]
entity = abs(k['close'] - k['open'])
entity_pct = entity / k['open'] * 100 if k['open'] else 0
if entity_pct > self.min_prev_entity_pct:
prev_kline = k
break
if prev_kline is None:
logger.info(f"没有实体涨幅>{self.min_prev_entity_pct:.3f}%的上一根K线跳过信号检测")
time.sleep(0.1)
continue
# 记录进入新的K线
current_kline_time = current_kline['id']
if self.last_kline_time != current_kline_time:
self.last_kline_time = current_kline_time
logger.info(f"进入新K线: {current_kline_time}")
# 新K线内重新判断多/空止盈触发
if self.start == 1:
self.take_profit_triggered_kline_id = None
if self.start == -1:
self.take_profit_triggered_kline_id_short = None
# 2. 获取当前价格
current_price = self.get_current_price()
if not current_price:
logger.warning("获取价格失败,等待重试...")
time.sleep(2)
continue
# 3. 每次循环都通过SDK获取真实持仓状态避免状态不同步导致双向持仓
if not self.get_position_status():
logger.warning("获取持仓状态失败,等待重试...")
time.sleep(2)
continue
logger.debug(f"当前持仓状态: {self.start} (0=无, 1=多, -1=空)")
signal = None
# 3.5 多仓止盈自动四等分open~high 达到极值后,回到 3/4 平仓
if self.start == 1:
# 同一根K线多仓只允许止盈一次避免“止盈->再开->再止盈”循环
if self.last_take_profit_kline_id == current_kline_time:
signal = self.check_signal(current_price, prev_kline, current_kline)
else:
long_levels = self.calc_long_take_profit_levels(current_kline)
if long_levels is not None:
retrace_close_threshold = long_levels["close_threshold"]
# 使用当前K线 high 判定是否已触发到 4/4 极值,避免依赖分钟收盘价漏判
if long_levels["extreme"] > long_levels["open"]:
self.take_profit_triggered_kline_id = current_kline_time
if (
self.take_profit_triggered_kline_id == current_kline_time
and current_price <= retrace_close_threshold
):
reason = (
f"当前K线开盘价={long_levels['open']:.2f},最高价={long_levels['extreme']:.2f}(4/4)"
f"现价{current_price:.2f}已回调至≤{retrace_close_threshold:.2f}(3/4),按规则止盈平多"
)
self._log_take_profit_action("止盈平多仓", reason)
self.平仓()
self.take_profit_reentry_threshold = long_levels["reentry_threshold"]
self.take_profit_triggered_kline_id = None
self.last_take_profit_kline_id = current_kline_time
page_start = True
time.sleep(1)
else:
signal = self.check_signal(current_price, prev_kline, current_kline)
else:
signal = self.check_signal(current_price, prev_kline, current_kline)
# 3.6 止盈平多后:价格继续回调到 2/4 则同向开多
elif self.start == 0 and self.take_profit_reentry_threshold is not None:
if current_price <= self.take_profit_reentry_threshold:
reason = (
f"止盈平仓后价格继续回调至≤{self.take_profit_reentry_threshold:.2f}(2/4),按规则同向开多"
)
self._log_take_profit_action("止盈后同向开多", reason)
self.开单(marketPriceLongOrder=1, size=self.default_order_size)
time.sleep(3)
if self.verify_position_direction(1):
self.last_open_time = time.time()
self.last_open_kline_id = current_kline_time
self._write_open_log("止盈后同向开多", reason, current_kline, prev_kline)
logger.success("止盈后再开多成功")
page_start = True
else:
logger.error("止盈后再开多验证失败")
self.take_profit_reentry_threshold = None
else:
signal = self.check_signal(current_price, prev_kline, current_kline)
# 3.7 空仓止盈自动四等分open~low 达到极值后,回到 3/4 平仓
elif self.start == -1:
# 同一根K线空仓只允许止盈一次避免“止盈->再开->再止盈”循环
if self.last_take_profit_kline_id == current_kline_time:
signal = self.check_signal(current_price, prev_kline, current_kline)
else:
short_levels = self.calc_short_take_profit_levels(current_kline)
if short_levels is not None:
retrace_close_threshold_short = short_levels["close_threshold"]
# 使用当前K线 low 判定是否已触发到 4/4 极值,避免依赖分钟收盘价漏判
if short_levels["extreme"] < short_levels["open"]:
self.take_profit_triggered_kline_id_short = current_kline_time
if (
self.take_profit_triggered_kline_id_short == current_kline_time
and current_price >= retrace_close_threshold_short
):
reason = (
f"当前K线开盘价={short_levels['open']:.2f},最低价={short_levels['extreme']:.2f}(4/4)"
f"现价{current_price:.2f}已反弹至≥{retrace_close_threshold_short:.2f}(3/4),按规则止盈平空"
)
self._log_take_profit_action("止盈平空仓", reason)
self.平仓()
self.take_profit_reentry_threshold_short = short_levels["reentry_threshold"]
self.take_profit_triggered_kline_id_short = None
self.last_take_profit_kline_id = current_kline_time
page_start = True
time.sleep(1)
else:
signal = self.check_signal(current_price, prev_kline, current_kline)
else:
signal = self.check_signal(current_price, prev_kline, current_kline)
# 3.8 止盈平空后:价格继续反弹到 2/4 则同向开空
elif self.start == 0 and self.take_profit_reentry_threshold_short is not None:
if current_price >= self.take_profit_reentry_threshold_short:
reason = (
f"止盈平空后价格继续反弹至≥{self.take_profit_reentry_threshold_short:.2f}(2/4),按规则同向开空"
)
self._log_take_profit_action("止盈后同向开空", reason)
self.开单(marketPriceLongOrder=-1, size=self.default_order_size)
time.sleep(3)
if self.verify_position_direction(-1):
self.last_open_time = time.time()
self.last_open_kline_id = current_kline_time
self._write_open_log("止盈后同向开空", reason, current_kline, prev_kline)
logger.success("止盈后再开空成功")
page_start = True
else:
logger.error("止盈后再开空验证失败")
self.take_profit_reentry_threshold_short = None
else:
signal = self.check_signal(current_price, prev_kline, current_kline)
else:
# 4. 检查信号
signal = self.check_signal(current_price, prev_kline, current_kline)
# 6. 反手过滤:冷却时间
if signal and signal[0].startswith('reverse_'):
if not self.can_reverse(current_price, signal[1]):
signal = None
# 6.5 开仓频率过滤:同一根 K 线只开一次 + 开仓冷却
if signal and signal[0] in ('long', 'short'):
if not self.can_open(current_kline_time):
signal = None
else:
self._current_kline_id_for_open = current_kline_time # 供 execute_trade 成功后记录
# 6.6 当前 K 线已反手过则本 K 线内不再操作仓位
if signal and self.last_reverse_kline_id == current_kline_time:
logger.info(f"本 K 线({current_kline_time})已反手过,本 K 线内不再操作仓位")
signal = None
# 7. 有信号则执行交易
if signal:
trade_success = self.execute_trade(signal)
if trade_success:
if signal[0] in ('reverse_long', 'reverse_short'):
self.last_reverse_kline_id = current_kline_time # 本 K 线已反手,本 K 线内不再操作
# 写入开仓日志参考的两根K线 + 开仓原因
sig_type, trigger_price = signal
op_name = {"long": "开多", "short": "开空", "reverse_long": "反手做多", "reverse_short": "反手做空"}.get(sig_type, sig_type)
if sig_type == "long":
open_reason = f"三分之一策略:当前价{current_price:.2f}>=突破做多价{trigger_price:.2f}(实体上边+1/3)"
elif sig_type == "short":
open_reason = f"三分之一策略:当前价{current_price:.2f}<=突破做空价{trigger_price:.2f}(实体下边-1/3)"
elif sig_type == "reverse_long":
open_reason = f"持空反手做多:当前价{current_price:.2f}>=做多触发价{trigger_price:.2f}(下1/3)"
else:
open_reason = f"持多反手做空:当前价{current_price:.2f}<=做空触发价{trigger_price:.2f}(上1/3)"
self._write_open_log(op_name, open_reason, current_kline, prev_kline)
logger.success(f"交易执行完成: {signal[0]}, 当前持仓状态: {self.start}")
page_start = True
else:
logger.warning(f"交易执行失败或被阻止: {signal[0]}")
# 短暂等待后继续循环同一根K线遇到信号就操作
time.sleep(0.1)
if page_start:
self.page.close()
time.sleep(5)
except KeyboardInterrupt:
logger.info("用户中断,程序退出")
break
except Exception as e:
logger.error(f"主循环异常: {e}")
time.sleep(5)
if __name__ == '__main__':
BitmartFuturesTransaction(bit_id="62f9107d0c674925972084e282df55b3").action()

546
bb_trade.py Normal file
View File

@@ -0,0 +1,546 @@
"""
布林带均值回归策略 — 实盘交易
BB(10, 2.5) | 5分钟K线 | ETH | 50x杠杆 | 每单权益1%
逻辑:
- 价格触及上布林带 → 平多(如有) + 开空
- 价格触及下布林带 → 平空(如有) + 开多
- 始终持仓(多空翻转)
使用 BitMart Futures API 进行开平仓
"""
import time
import uuid
import numpy as np
from datetime import datetime
from pathlib import Path
from loguru import logger
from bitmart.api_contract import APIContract
# ---------------------------------------------------------------------------
# 配置
# ---------------------------------------------------------------------------
class BBTradeConfig:
# API 凭证
API_KEY = "6104088c65a68d7e53df5d9395b67d78e555293a"
SECRET_KEY = "a8b14312330d8e6b9b09acfd972b34e32022fdfa9f2b06f0a0a31723b873fd01"
MEMO = "me"
# 合约
CONTRACT_SYMBOL = "ETHUSDT"
# 布林带参数
BB_PERIOD = 10 # 10根5分钟K线 = 50分钟回看
BB_STD = 2.5 # 标准差倍数
# 仓位管理
LEVERAGE = 50 # 杠杆倍数
OPEN_TYPE = "cross" # 全仓模式
MARGIN_PCT = 0.01 # 每单用权益的1%作为保证金
# 风控
MAX_DAILY_LOSS = 50.0 # 日最大亏损(U),达到后停止交易
COOLDOWN_SECONDS = 30 # 两次交易之间最小间隔(秒)
# 运行
POLL_INTERVAL = 5 # 主循环轮询间隔(秒)
KLINE_STEP = 5 # K线周期(分钟)
KLINE_HOURS = 2 # 获取最近多少小时K线(需覆盖BB_PERIOD)
# ---------------------------------------------------------------------------
# 布林带计算
# ---------------------------------------------------------------------------
def calc_bollinger(closes: list, period: int, n_std: float):
"""计算布林带,返回 (mid, upper, lower) 或 None数据不足时"""
if len(closes) < period:
return None
arr = np.array(closes[-period:], dtype=float)
mid = arr.mean()
std = arr.std(ddof=0)
upper = mid + n_std * std
lower = mid - n_std * std
return mid, upper, lower
# ---------------------------------------------------------------------------
# 交易主类
# ---------------------------------------------------------------------------
class BBTrader:
def __init__(self, cfg: BBTradeConfig = None):
self.cfg = cfg or BBTradeConfig()
self.api = APIContract(
self.cfg.API_KEY, self.cfg.SECRET_KEY, self.cfg.MEMO,
timeout=(5, 15)
)
# 持仓状态: -1=空, 0=无, 1=多
self.position = 0
self.open_avg_price = None
self.current_amount = None
# 风控
self.daily_pnl = 0.0
self.daily_stopped = False
self.current_date = None
self.last_trade_time = 0.0
# 日志
self.log_dir = Path(__file__).resolve().parent
logger.add(
self.log_dir / "bb_trade_{time:YYYY-MM-DD}.log",
rotation="1 day", retention="30 days",
format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}"
)
# ------------------------------------------------------------------
# API 封装
# ------------------------------------------------------------------
def get_klines(self) -> list | None:
"""获取最近N小时的5分钟K线返回 [{id, open, high, low, close}, ...]"""
try:
end_time = int(time.time())
start_time = end_time - 3600 * self.cfg.KLINE_HOURS
resp = self.api.get_kline(
contract_symbol=self.cfg.CONTRACT_SYMBOL,
step=self.cfg.KLINE_STEP,
start_time=start_time,
end_time=end_time
)[0]
if resp.get("code") != 1000:
logger.error(f"获取K线失败: {resp}")
return None
data = resp["data"]
klines = []
for k in data:
klines.append({
"id": int(k["timestamp"]),
"open": float(k["open_price"]),
"high": float(k["high_price"]),
"low": float(k["low_price"]),
"close": float(k["close_price"]),
})
klines.sort(key=lambda x: x["id"])
return klines
except Exception as e:
logger.error(f"获取K线异常: {e}")
return None
def get_current_price(self) -> float | None:
"""获取当前最新价格最近1分钟K线收盘价"""
try:
end_time = int(time.time())
resp = self.api.get_kline(
contract_symbol=self.cfg.CONTRACT_SYMBOL,
step=1,
start_time=end_time - 300,
end_time=end_time
)[0]
if resp.get("code") == 1000 and resp["data"]:
return float(resp["data"][-1]["close_price"])
return None
except Exception as e:
logger.error(f"获取价格异常: {e}")
return None
def get_balance(self) -> float | None:
"""获取合约账户可用余额"""
try:
resp = self.api.get_assets_detail()[0]
if resp.get("code") == 1000:
data = resp["data"]
if isinstance(data, dict):
return float(data.get("available_balance", 0))
elif isinstance(data, list):
for asset in data:
if asset.get("currency") == "USDT":
return float(asset.get("available_balance", 0))
return None
except Exception as e:
logger.error(f"查询余额异常: {e}")
return None
def get_position_status(self) -> bool:
"""查询当前持仓,更新 self.position / open_avg_price / current_amount"""
try:
resp = self.api.get_position(contract_symbol=self.cfg.CONTRACT_SYMBOL)[0]
if resp.get("code") != 1000:
logger.error(f"查询持仓失败: {resp}")
return False
positions = resp["data"]
if not positions:
self.position = 0
self.open_avg_price = None
self.current_amount = None
return True
pos = positions[0]
self.position = 1 if pos["position_type"] == 1 else -1
self.open_avg_price = float(pos["open_avg_price"])
self.current_amount = float(pos["current_amount"])
unrealized = float(pos.get("unrealized_value", 0))
logger.debug(f"持仓: dir={self.position} price={self.open_avg_price} "
f"amt={self.current_amount} upnl={unrealized:.2f}")
return True
except Exception as e:
logger.error(f"查询持仓异常: {e}")
return False
def set_leverage(self) -> bool:
"""设置杠杆和全仓模式"""
try:
resp = self.api.post_submit_leverage(
contract_symbol=self.cfg.CONTRACT_SYMBOL,
leverage=str(self.cfg.LEVERAGE),
open_type=self.cfg.OPEN_TYPE
)[0]
if resp.get("code") == 1000:
logger.success(f"杠杆设置成功: {self.cfg.LEVERAGE}x {self.cfg.OPEN_TYPE}")
return True
else:
logger.error(f"杠杆设置失败: {resp}")
return False
except Exception as e:
logger.error(f"设置杠杆异常: {e}")
return False
def _gen_client_order_id(self) -> str:
return f"BB_{uuid.uuid4().hex[:12]}"
def submit_order(self, side: int, size: int) -> bool:
"""
提交市价单
side: 1=买入开多, 2=买入平空, 3=卖出平多, 4=卖出开空
size: 张数
"""
side_names = {1: "买入开多", 2: "买入平空", 3: "卖出平多", 4: "卖出开空"}
logger.info(f"下单: {side_names.get(side, side)} {size}")
try:
resp = self.api.post_submit_order(
contract_symbol=self.cfg.CONTRACT_SYMBOL,
client_order_id=self._gen_client_order_id(),
side=side,
mode=1, # GTC
type="market",
leverage=str(self.cfg.LEVERAGE),
open_type=self.cfg.OPEN_TYPE,
size=size,
)[0]
if resp.get("code") == 1000:
logger.success(f"下单成功: {side_names.get(side)} {size}张 resp={resp}")
return True
else:
logger.error(f"下单失败: {resp}")
return False
except Exception as e:
logger.error(f"下单异常: {e}")
return False
# ------------------------------------------------------------------
# 仓位操作
# ------------------------------------------------------------------
def calc_order_size(self, price: float) -> int:
"""
根据当前权益的1%计算开仓张数
BitMart ETH合约: 1张 = 0.01 ETH
保证金 = equity * margin_pct
名义价值 = margin * leverage
数量(ETH) = 名义价值 / price
张数 = 数量 / 0.01
"""
balance = self.get_balance()
if balance is None or balance <= 0:
logger.warning(f"余额不足或查询失败: {balance}")
return 0
margin = balance * self.cfg.MARGIN_PCT
notional = margin * self.cfg.LEVERAGE
qty_eth = notional / price
size = max(1, int(qty_eth / 0.01)) # 1张=0.01ETH
logger.info(f"仓位计算: 余额={balance:.2f} 保证金={margin:.2f} "
f"名义={notional:.2f} 数量={qty_eth:.4f}ETH = {size}")
return size
def close_current_position(self) -> bool:
"""平掉当前持仓"""
if not self.get_position_status():
return False
if self.position == 0:
logger.info("无持仓,无需平仓")
return True
if self.position == 1:
# 平多: side=3
size = int(self.current_amount)
return self.submit_order(side=3, size=size)
else:
# 平空: side=2
size = int(self.current_amount)
return self.submit_order(side=2, size=size)
def open_long(self, price: float) -> bool:
"""开多"""
size = self.calc_order_size(price)
if size <= 0:
return False
return self.submit_order(side=1, size=size)
def open_short(self, price: float) -> bool:
"""开空"""
size = self.calc_order_size(price)
if size <= 0:
return False
return self.submit_order(side=4, size=size)
def flip_to_long(self, price: float) -> bool:
"""平空 → 开多"""
logger.info("=== 翻转为多 ===")
if self.position == -1:
if not self.close_current_position():
logger.error("平空失败,放弃开多")
return False
time.sleep(2)
# 确认已无仓
for _ in range(5):
if self.get_position_status() and self.position == 0:
break
time.sleep(1)
if self.position != 0:
logger.warning(f"平仓后仍有持仓({self.position}),放弃开多")
return False
return self.open_long(price)
def flip_to_short(self, price: float) -> bool:
"""平多 → 开空"""
logger.info("=== 翻转为空 ===")
if self.position == 1:
if not self.close_current_position():
logger.error("平多失败,放弃开空")
return False
time.sleep(2)
for _ in range(5):
if self.get_position_status() and self.position == 0:
break
time.sleep(1)
if self.position != 0:
logger.warning(f"平仓后仍有持仓({self.position}),放弃开空")
return False
return self.open_short(price)
# ------------------------------------------------------------------
# 风控
# ------------------------------------------------------------------
def check_daily_reset(self):
"""每日重置(UTC+8 00:00 = UTC 16:00)"""
now = datetime.utcnow()
# 用UTC日期做简单日切
today = now.date()
if self.current_date != today:
if self.current_date is not None:
logger.info(f"日切: {self.current_date}{today}, 日PnL={self.daily_pnl:.2f}")
self.current_date = today
self.daily_pnl = 0.0
self.daily_stopped = False
def can_trade(self) -> bool:
"""检查是否可交易"""
if self.daily_stopped:
return False
now = time.time()
if now - self.last_trade_time < self.cfg.COOLDOWN_SECONDS:
remain = self.cfg.COOLDOWN_SECONDS - (now - self.last_trade_time)
logger.debug(f"交易冷却中,剩余 {remain:.0f}s")
return False
return True
# ------------------------------------------------------------------
# 日志
# ------------------------------------------------------------------
def write_trade_log(self, action: str, price: float, bb_upper: float,
bb_mid: float, bb_lower: float, reason: str):
"""写入交易日志文件"""
try:
date_str = datetime.now().strftime("%Y%m%d")
log_file = self.log_dir / f"bb_trade_log_{date_str}.txt"
time_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
block = (
f"\n{'='*60}\n"
f"时间: {time_str}\n"
f"操作: {action}\n"
f"价格: {price:.2f}\n"
f"BB上轨: {bb_upper:.2f} | 中轨: {bb_mid:.2f} | 下轨: {bb_lower:.2f}\n"
f"原因: {reason}\n"
f"{'='*60}\n"
)
with open(log_file, "a", encoding="utf-8") as f:
f.write(block)
except Exception as e:
logger.warning(f"写入日志失败: {e}")
# ------------------------------------------------------------------
# 主循环
# ------------------------------------------------------------------
def run(self):
"""策略主循环"""
logger.info("=" * 60)
logger.info(f" BB策略启动: BB({self.cfg.BB_PERIOD},{self.cfg.BB_STD})")
logger.info(f" 合约: {self.cfg.CONTRACT_SYMBOL} | {self.cfg.LEVERAGE}x {self.cfg.OPEN_TYPE}")
logger.info(f" 每单: 权益×{self.cfg.MARGIN_PCT:.0%}")
logger.info("=" * 60)
# 设置杠杆
if not self.set_leverage():
logger.error("杠杆设置失败,退出")
return
# 初始持仓同步
if not self.get_position_status():
logger.error("初始持仓查询失败,退出")
return
logger.info(f"初始持仓状态: {self.position}")
last_kline_id = None # 避免同一根K线重复触发
while True:
try:
self.check_daily_reset()
if self.daily_stopped:
logger.info(f"日亏损已达限制({self.daily_pnl:.2f}),等待日切")
time.sleep(60)
continue
# 1. 获取K线
klines = self.get_klines()
if not klines or len(klines) < self.cfg.BB_PERIOD:
logger.warning(f"K线数据不足({len(klines) if klines else 0}根),等待...")
time.sleep(self.cfg.POLL_INTERVAL)
continue
# 当前K线 = 最后一根未收盘信号用已收盘的K线
# 使用倒数第二根及之前的收盘价算BB已收盘的K线
closed_klines = klines[:-1] # 已收盘的K线
current_kline = klines[-1] # 当前未收盘K线
if len(closed_klines) < self.cfg.BB_PERIOD:
time.sleep(self.cfg.POLL_INTERVAL)
continue
# 2. 计算布林带
closes = [k["close"] for k in closed_klines]
bb = calc_bollinger(closes, self.cfg.BB_PERIOD, self.cfg.BB_STD)
if bb is None:
time.sleep(self.cfg.POLL_INTERVAL)
continue
bb_mid, bb_upper, bb_lower = bb
# 3. 获取当前价格
current_price = self.get_current_price()
if current_price is None:
time.sleep(self.cfg.POLL_INTERVAL)
continue
# 用当前K线的 high/low 判断是否触及布林带
cur_high = current_kline["high"]
cur_low = current_kline["low"]
touched_upper = cur_high >= bb_upper
touched_lower = cur_low <= bb_lower
logger.info(
f"价格={current_price:.2f} | "
f"BB: {bb_lower:.2f} / {bb_mid:.2f} / {bb_upper:.2f} | "
f"H={cur_high:.2f} L={cur_low:.2f} | "
f"触上={touched_upper} 触下={touched_lower} | "
f"仓位={self.position}"
)
# 4. 同步持仓状态
if not self.get_position_status():
time.sleep(self.cfg.POLL_INTERVAL)
continue
# 5. 信号判断 + 执行
# 同一根K线只触发一次
kline_id = current_kline["id"]
if kline_id == last_kline_id:
# 已在这根K线触发过不重复操作
time.sleep(self.cfg.POLL_INTERVAL)
continue
# 同时触及上下轨(极端波动)→ 跳过
if touched_upper and touched_lower:
logger.warning("同时触及上下轨,跳过")
time.sleep(self.cfg.POLL_INTERVAL)
continue
action = None
reason = ""
if touched_upper:
# 触及上轨 → 开空 / 翻转为空
if not self.can_trade():
time.sleep(self.cfg.POLL_INTERVAL)
continue
reason = (f"价格最高{cur_high:.2f}触及上轨{bb_upper:.2f}"
f"BB({self.cfg.BB_PERIOD},{self.cfg.BB_STD})")
if self.position == 1:
action = "翻转: 平多→开空"
success = self.flip_to_short(current_price)
elif self.position == 0:
action = "开空"
success = self.open_short(current_price)
else:
# 已经是空仓,不操作
logger.info("已持空仓,触上轨无需操作")
success = False
if success:
last_kline_id = kline_id
self.last_trade_time = time.time()
self.write_trade_log(action, current_price,
bb_upper, bb_mid, bb_lower, reason)
logger.success(f"{action} 执行成功")
elif touched_lower:
# 触及下轨 → 开多 / 翻转为多
if not self.can_trade():
time.sleep(self.cfg.POLL_INTERVAL)
continue
reason = (f"价格最低{cur_low:.2f}触及下轨{bb_lower:.2f}"
f"BB({self.cfg.BB_PERIOD},{self.cfg.BB_STD})")
if self.position == -1:
action = "翻转: 平空→开多"
success = self.flip_to_long(current_price)
elif self.position == 0:
action = "开多"
success = self.open_long(current_price)
else:
logger.info("已持多仓,触下轨无需操作")
success = False
if success:
last_kline_id = kline_id
self.last_trade_time = time.time()
self.write_trade_log(action, current_price,
bb_upper, bb_mid, bb_lower, reason)
logger.success(f"{action} 执行成功")
time.sleep(self.cfg.POLL_INTERVAL)
except KeyboardInterrupt:
logger.info("用户中断,程序退出")
break
except Exception as e:
logger.error(f"主循环异常: {e}")
time.sleep(10)
# ---------------------------------------------------------------------------
# 入口
# ---------------------------------------------------------------------------
if __name__ == "__main__":
trader = BBTrader()
trader.run()

16
main.py
View File

@@ -1,16 +0,0 @@
# 这是一个示例 Python 脚本。
# 按 ⌃R 执行或将其替换为您的代码。
# 按 双击 ⇧ 在所有地方搜索类、文件、工具窗口、操作和设置。
def print_hi(name):
# 在下面的代码行中使用断点来调试脚本。
print(f'Hi, {name}') # 按 ⌘F8 切换断点。
# 按装订区域中的绿色按钮以运行脚本。
if __name__ == '__main__':
print_hi('PyCharm')
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

View File

@@ -0,0 +1,277 @@
n_grids,mode,half_pct,grid_sl,eq,ret,trades,gross,nfee,worst_day,max_dd,wr,score,max_open,profit_lock,max_daily_loss
25,long,0.08,0.0,1397.9111280963439,39.791112809634384,1829,1118.61138190761,89.34110427803469,-54.66635046647207,-101.88736561661199,0.9781301257517769,18.296839388862164,8,0.0,50.0
25,long,0.08,0.0,1392.6959362266246,39.269593622662455,1822,1113.1328682608444,89.07778250098772,-54.66635046647207,-101.88736561661199,0.9780461031833151,17.775320201890235,8,40.0,50.0
25,long,0.08,0.08,1377.4361374244675,37.74361374244675,1894,1020.5273176511827,92.77597302857623,-54.66635046647207,-102.50464117878687,0.9693769799366421,16.218476543565785,8,0.0,50.0
25,long,0.08,0.08,1372.2209455547481,37.22209455547481,1887,1015.0488040044162,92.51265125152923,-54.66635046647207,-102.50464117878687,0.969263381028087,15.696957356593849,8,40.0,50.0
25,long,0.08,0.0,1358.8279680292997,35.88279680292997,1760,1064.0701032765814,86.79599035314052,-54.66635046647207,-104.92067967367007,0.9772727272727273,14.236857679304844,8,20.0,50.0
25,long,0.08,0.08,1339.133685213397,33.913368521339706,1826,966.8043696257179,90.26848185327287,-54.66635046647207,-105.53795523584495,0.968236582694414,12.236565619605837,8,20.0,50.0
25,long,0.08,0.05,1305.7377273966035,30.573772739660352,2243,660.9272563596152,106.21458290512612,-54.82484156455007,-134.23780091713024,0.9259919750334373,7.414430224438818,10,40.0,50.0
25,long,0.08,0.05,1305.7377273966035,30.573772739660352,2243,660.9272563596152,106.21458290512612,-54.82484156455007,-134.23780091713024,0.9259919750334373,7.414430224438818,10,0.0,50.0
25,long,0.08,0.05,1273.2290820455269,27.322908204552686,2200,626.800992068894,104.59696396548253,-54.82484156455007,-134.23780091713024,0.9245454545454546,4.1635656893311515,10,20.0,50.0
25,long,0.08,0.05,1274.1268173351598,27.412681733515978,2194,625.3080156191049,103.98444015678419,-55.57015591838194,-133.67404726819632,0.9247948951686418,4.057932594591579,8,40.0,50.0
25,long,0.08,0.05,1274.1268173351598,27.412681733515978,2194,625.3080156191049,103.98444015678419,-55.57015591838194,-133.67404726819632,0.9247948951686418,4.057932594591579,8,0.0,50.0
25,long,0.08,0.05,1269.6333024989083,26.963330249890827,2237,630.6752392403805,106.17254510255816,-54.82484156455007,-135.87368396513898,0.9226642825212338,3.722193582268856,0,0.0,50.0
25,long,0.08,0.05,1269.6333024989083,26.963330249890827,2237,630.6752392403805,106.17254510255816,-54.82484156455007,-135.87368396513898,0.9226642825212338,3.722193582268856,0,0.0,50.0
25,long,0.08,0.05,1269.6333024989083,26.963330249890827,2237,630.6752392403805,106.17254510255816,-54.82484156455007,-135.87368396513898,0.9226642825212338,3.722193582268856,0,40.0,50.0
25,long,0.08,0.08,1304.459491306357,30.4459491306357,2087,855.6829832347544,100.87587182425239,-62.51677693859392,-173.81100512689272,0.9458552946813608,3.0003657927128877,10,0.0,50.0
25,long,0.08,0.0,1304.2820463031949,30.428204630319488,2075,878.5740502089094,100.46650937600748,-62.51677693859392,-173.98845013005507,0.946987951807229,2.9737490422385573,10,0.0,50.0
25,long,0.08,0.0,1303.3736239387122,30.337362393871217,2179,842.8262746516338,104.98721868527448,-65.84157418233985,-167.3725604145027,0.9343735658558971,2.216262118444126,0,0.0,50.0
25,long,0.08,0.0,1303.3736239387122,30.337362393871217,2179,842.8262746516338,104.98721868527448,-65.84157418233985,-167.3725604145027,0.9343735658558971,2.216262118444126,0,0.0,50.0
25,long,0.08,0.08,1292.3418470283234,29.23418470283234,2071,842.9634310238881,100.27396389142075,-62.51677693859392,-173.81100512689272,0.9454369869628199,1.7886013649095283,10,40.0,50.0
25,long,0.08,0.0,1292.1644020251613,29.21644020251613,2059,865.8544979980437,99.8646014431759,-62.51677693859392,-173.98845013005507,0.9465760077707625,1.7619846144351978,10,40.0,50.0
25,long,0.08,0.05,1247.8009310396624,24.780093103966237,2159,597.6654829437048,102.66779377688283,-55.57015591838194,-138.20581671564264,0.9235757295044001,1.1987554926695223,8,20.0,50.0
25,long,0.08,0.08,1296.157481099035,29.615748109903507,2182,812.2098595260189,104.9076262230056,-65.84157418233985,-174.5887032541798,0.9330889092575618,1.1338406924925604,0,0.0,50.0
25,long,0.08,0.08,1296.157481099035,29.615748109903507,2182,812.2098595260189,104.9076262230056,-65.84157418233985,-174.5887032541798,0.9330889092575618,1.1338406924925604,0,0.0,50.0
25,long,0.08,0.0,1289.7808097173345,28.978080971733448,2161,828.5563199370484,104.3100781920673,-65.84157418233985,-167.3725604145027,0.933826931975937,0.8569806963063566,0,40.0,50.0
25,long,0.08,0.05,1236.34927096897,23.63492709689699,2193,595.7359668195779,104.51730421169512,-54.82484156455007,-135.87368396513898,0.9211126310989513,0.39379042927502006,0,20.0,50.0
25,long,0.08,0.08,1282.5646668776574,28.256466687765737,2164,797.9399048114334,104.23048572979843,-65.84157418233985,-174.5887032541798,0.9325323475046211,-0.225440729645209,0,40.0,50.0
25,long,0.08,0.08,1259.3235564374731,25.932355643747314,2012,795.9619663232609,97.92940397913668,-62.51677693859392,-175.36061401718916,0.9438369781312127,-1.5907081386903208,10,20.0,50.0
25,long,0.08,0.0,1259.146111434311,25.914611143431102,2000,818.8530332974159,97.52004153089177,-62.51677693859392,-175.53805902035128,0.945,-1.6173248891646388,10,20.0,50.0
25,long,0.08,0.05,1147.8412009571211,14.784120095712115,1785,420.34470412045823,84.48944027534574,-35.21316528488592,-120.10936470512252,0.9165266106442577,-1.7852977250097855,5,0.0,30.0
25,long,0.08,0.05,1147.8412009571211,14.784120095712115,1785,420.34470412045823,84.48944027534574,-35.21316528488592,-120.10936470512252,0.9165266106442577,-1.7852977250097855,5,40.0,30.0
25,long,0.08,0.0,1261.5124700601637,26.151247006016366,2101,786.1802135581369,101.84092566781933,-65.84157418233985,-168.14269369398585,0.9319371727748691,-2.0083599333848827,0,20.0,50.0
25,long,0.08,0.08,1254.296327220487,25.4296327220487,2104,755.563798432521,101.76133320555047,-65.84157418233985,-175.35883653366284,0.9306083650190115,-3.090781359336397,0,20.0,50.0
25,long,0.08,0.05,1135.205793534383,13.520579353438302,1768,407.0698054629229,83.84994904054716,-35.21316528488592,-123.03902246406142,0.9157239819004525,-3.1953213552305435,5,20.0,30.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,0,0.0,30.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,5,40.0,50.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,0,0.0,50.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,0,20.0,30.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,0,20.0,50.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,0,40.0,50.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,0,40.0,30.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,5,0.0,30.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,5,0.0,50.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,10,40.0,30.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,8,20.0,50.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,8,40.0,30.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,8,40.0,50.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,10,0.0,30.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,10,0.0,50.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,10,20.0,30.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,10,20.0,50.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,10,40.0,50.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,5,20.0,30.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,5,20.0,50.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,5,40.0,30.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,8,0.0,50.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,8,0.0,30.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,0,0.0,50.0
12,long,0.12,0.05,1180.5141440437385,18.05141440437385,308,282.92810755714413,19.2010653555889,-63.63293586820578,-80.54084655171164,0.8409090909090909,-5.065508683673463,8,20.0,30.0
25,long,0.08,0.0,1137.3810945856771,13.738109458567715,1474,590.1090690766704,71.4449647368382,-34.93805315434156,-168.20950929824642,0.9525101763907734,-5.1537819526470745,5,40.0,30.0
25,long,0.08,0.0,1137.3810945856771,13.738109458567715,1474,590.1090690766704,71.4449647368382,-34.93805315434156,-168.20950929824642,0.9525101763907734,-5.1537819526470745,5,0.0,30.0
25,long,0.08,0.08,1136.1945657236706,13.619456572367062,1493,550.5861371661551,72.43633240984111,-34.93805315434156,-168.77876259807783,0.9497655726724715,-5.300897503839298,5,0.0,30.0
25,long,0.08,0.08,1136.1945657236706,13.619456572367062,1493,550.5861371661551,72.43633240984111,-34.93805315434156,-168.77876259807783,0.9497655726724715,-5.300897503839298,5,40.0,30.0
25,long,0.08,0.0,1165.97069931178,16.597069931177998,2143,575.931136840335,101.70221229800816,-46.11878114338265,-192.7322510212599,0.9066728884741018,-6.875176962899792,0,0.0,30.0
25,long,0.08,0.08,1165.97069931178,16.597069931177998,2143,575.931136840335,101.70221229800816,-46.11878114338265,-192.7322510212599,0.9066728884741018,-6.875176962899792,0,0.0,30.0
20,long,0.12,0.03,1135.6843456332908,13.568434563329083,847,231.87397292139397,42.89311882444578,-50.24276668427581,-107.62095367657184,0.7922077922077922,-6.885443125782251,5,40.0,30.0
20,long,0.12,0.03,1135.6843456332908,13.568434563329083,847,231.87397292139397,42.89311882444578,-50.24276668427581,-107.62095367657184,0.7922077922077922,-6.885443125782251,5,0.0,30.0
20,long,0.12,0.03,1135.6843456332908,13.568434563329083,847,231.87397292139397,42.89311882444578,-50.24276668427581,-107.62095367657184,0.7922077922077922,-6.885443125782251,5,20.0,50.0
20,long,0.12,0.03,1135.6843456332908,13.568434563329083,847,231.87397292139397,42.89311882444578,-50.24276668427581,-107.62095367657184,0.7922077922077922,-6.885443125782251,5,40.0,50.0
20,long,0.12,0.03,1135.6843456332908,13.568434563329083,847,231.87397292139397,42.89311882444578,-50.24276668427581,-107.62095367657184,0.7922077922077922,-6.885443125782251,5,20.0,30.0
20,long,0.12,0.03,1135.6843456332908,13.568434563329083,847,231.87397292139397,42.89311882444578,-50.24276668427581,-107.62095367657184,0.7922077922077922,-6.885443125782251,5,0.0,50.0
25,long,0.08,0.0,1122.4863591809087,12.248635918090873,1444,566.5065840356414,70.31642436408208,-34.93805315434156,-175.07793896588328,0.9515235457063712,-6.986676976505759,5,20.0,30.0
12,long,0.12,0.05,1175.608365031793,17.560836503179303,311,280.58636652303625,19.37571409443378,-67.89589136744712,-85.93785129322646,0.8392282958199357,-7.104823471716155,8,20.0,80.0
12,long,0.12,0.05,1175.608365031793,17.560836503179303,311,280.58636652303625,19.37571409443378,-67.89589136744712,-85.93785129322646,0.8392282958199357,-7.104823471716155,0,0.0,80.0
12,long,0.12,0.05,1175.608365031793,17.560836503179303,311,280.58636652303625,19.37571409443378,-67.89589136744712,-85.93785129322646,0.8392282958199357,-7.104823471716155,10,0.0,80.0
12,long,0.12,0.05,1175.608365031793,17.560836503179303,311,280.58636652303625,19.37571409443378,-67.89589136744712,-85.93785129322646,0.8392282958199357,-7.104823471716155,0,20.0,80.0
12,long,0.12,0.05,1175.608365031793,17.560836503179303,311,280.58636652303625,19.37571409443378,-67.89589136744712,-85.93785129322646,0.8392282958199357,-7.104823471716155,5,20.0,80.0
12,long,0.12,0.05,1175.608365031793,17.560836503179303,311,280.58636652303625,19.37571409443378,-67.89589136744712,-85.93785129322646,0.8392282958199357,-7.104823471716155,5,0.0,80.0
12,long,0.12,0.05,1175.608365031793,17.560836503179303,311,280.58636652303625,19.37571409443378,-67.89589136744712,-85.93785129322646,0.8392282958199357,-7.104823471716155,8,40.0,80.0
12,long,0.12,0.05,1175.608365031793,17.560836503179303,311,280.58636652303625,19.37571409443378,-67.89589136744712,-85.93785129322646,0.8392282958199357,-7.104823471716155,8,0.0,80.0
12,long,0.12,0.05,1175.608365031793,17.560836503179303,311,280.58636652303625,19.37571409443378,-67.89589136744712,-85.93785129322646,0.8392282958199357,-7.104823471716155,5,40.0,80.0
12,long,0.12,0.05,1175.608365031793,17.560836503179303,311,280.58636652303625,19.37571409443378,-67.89589136744712,-85.93785129322646,0.8392282958199357,-7.104823471716155,10,20.0,80.0
12,long,0.12,0.05,1175.608365031793,17.560836503179303,311,280.58636652303625,19.37571409443378,-67.89589136744712,-85.93785129322646,0.8392282958199357,-7.104823471716155,0,40.0,80.0
12,long,0.12,0.05,1175.608365031793,17.560836503179303,311,280.58636652303625,19.37571409443378,-67.89589136744712,-85.93785129322646,0.8392282958199357,-7.104823471716155,10,40.0,80.0
25,long,0.08,0.08,1121.2998303189036,12.129983031890356,1463,526.9836521251272,71.30779203708497,-34.93805315434156,-175.64719226571356,0.9487354750512645,-7.133792527697789,5,20.0,30.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,0,40.0,30.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,0,0.0,30.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,0,20.0,50.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,0,20.0,30.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,0,40.0,50.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,0,0.0,50.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,10,40.0,30.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,10,40.0,50.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,8,40.0,50.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,8,0.0,50.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,8,0.0,30.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,8,20.0,50.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,8,40.0,30.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,10,20.0,50.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,10,0.0,30.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,8,20.0,30.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,10,0.0,50.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,0,0.0,50.0
20,long,0.12,0.03,1127.938046241879,12.793804624187896,849,224.2015226624435,42.96696795690694,-50.24276668427581,-107.62095367657184,0.790341578327444,-7.660073064923438,10,20.0,30.0
25,long,0.08,0.0,1157.7954939202243,15.779549392022432,2132,567.3421430997186,101.28842394894701,-46.11878114338265,-192.73225102126014,0.9061913696060038,-7.6926975020553705,0,40.0,30.0
25,long,0.08,0.08,1157.7954939202243,15.779549392022432,2132,567.3421430997186,101.28842394894701,-46.11878114338265,-192.73225102126014,0.9061913696060038,-7.6926975020553705,0,40.0,30.0
12,long,0.1,0.05,1160.639981828195,16.0639981828195,415,287.8808246742429,24.34881068136027,-65.96155392833498,-87.71954981539272,0.8506024096385543,-8.11044548645063,0,0.0,50.0
25,long,0.08,0.0,1152.2873508564207,15.228735085642075,2116,557.8141899897886,100.12306620572392,-46.11878114338265,-196.98067925385715,0.9068998109640832,-8.455933220065576,10,0.0,30.0
25,long,0.08,0.08,1152.2873508564207,15.228735085642075,2116,557.8141899897886,100.12306620572392,-46.11878114338265,-196.98067925385715,0.9068998109640832,-8.455933220065576,10,0.0,30.0
25,long,0.08,0.05,1130.5880659042618,13.058806590426183,2165,429.6712922463619,101.57412180073922,-42.96178493326261,-183.68928172463336,0.8965357967667437,-9.014192975784267,10,0.0,30.0
25,long,0.08,0.05,1130.5880659042618,13.058806590426183,2165,429.6712922463619,101.57412180073922,-42.96178493326261,-183.68928172463336,0.8965357967667437,-9.014192975784267,10,40.0,30.0
25,long,0.08,0.0,1145.5873154082087,14.558731540820872,2107,550.7755987528917,99.78451041703838,-46.11878114338265,-196.9806792538576,0.9065021357380162,-9.125936764886802,10,40.0,30.0
25,long,0.08,0.08,1145.5873154082087,14.558731540820872,2107,550.7755987528917,99.78451041703838,-46.11878114338265,-196.9806792538576,0.9065021357380162,-9.125936764886802,10,40.0,30.0
25,long,0.08,0.05,1127.3665122706623,12.736651227066227,2165,429.6712922463619,101.63662180073922,-42.96178493326261,-186.91083535823395,0.8965357967667437,-9.497426020824252,0,40.0,30.0
25,long,0.08,0.05,1127.3665122706623,12.736651227066227,2165,429.6712922463619,101.63662180073922,-42.96178493326261,-186.91083535823395,0.8965357967667437,-9.497426020824252,0,0.0,30.0
25,long,0.08,0.0,1141.560014818118,14.15600148181179,2095,537.8633318701434,99.68370601897158,-46.11878114338265,-198.02270069179235,0.9045346062052506,-9.580767895792622,0,20.0,30.0
25,long,0.08,0.08,1141.560014818118,14.15600148181179,2095,537.8633318701434,99.68370601897158,-46.11878114338265,-198.02270069179235,0.9045346062052506,-9.580767895792622,0,20.0,30.0
15,long,0.12,0.05,1146.4138461034074,14.641384610340742,444,281.9958657009046,25.54491016368575,-65.10586571841566,-113.39236837709984,0.8513513513513513,-10.559993524038948,0,0.0,50.0
12,long,0.12,0.03,1110.6656937601829,11.066569376018288,361,142.41245281010382,19.9916028853587,-59.77484153931823,-78.2840404351266,0.6980609418282548,-10.780085107533509,0,0.0,50.0
25,long,0.08,0.08,1130.147250491773,13.01472504917731,2071,522.2176262505083,98.30521702858394,-46.11878114338265,-203.0793978984076,0.9048768710767745,-10.974879188757864,10,20.0,30.0
25,long,0.08,0.0,1130.147250491773,13.01472504917731,2071,522.2176262505083,98.30521702858394,-46.11878114338265,-203.0793978984076,0.9048768710767745,-10.974879188757864,10,20.0,30.0
12,long,0.12,0.0,1224.732709882688,22.47327098826879,264,549.896055719594,19.312854894621676,-94.17262348471081,-109.39570457022182,0.9810606060606061,-11.248301285655543,0,0.0,50.0
25,long,0.12,0.05,1283.2152523741586,28.32152523741586,1218,557.1262213962846,62.60538994244905,-110.98849465466697,-141.9289131411324,0.9121510673234812,-12.071468816040852,0,0.0,50.0
25,long,0.08,0.05,1105.7826258452312,10.578262584523122,2132,403.62444516026403,100.33271477367626,-42.96178493326261,-197.15031497435166,0.8949343339587242,-12.167788644173243,10,20.0,30.0
25,long,0.08,0.08,1117.966475303976,11.796647530397603,2014,516.252592545815,95.09100037625154,-44.815807347324835,-211.43426210996347,0.9131082423038729,-12.219807779298021,8,0.0,30.0
25,long,0.08,0.0,1117.966475303976,11.796647530397603,2014,516.252592545815,95.09100037625154,-44.815807347324835,-211.43426210996347,0.9131082423038729,-12.219807779298021,8,0.0,30.0
25,long,0.08,0.05,1108.8895958521423,10.888959585214229,2120,405.51821071028405,99.73320631136474,-44.81012850141826,-200.08066373027987,0.8981132075471698,-12.558112151725243,8,0.0,30.0
25,long,0.08,0.05,1108.8895958521423,10.888959585214229,2120,405.51821071028405,99.73320631136474,-44.81012850141826,-200.08066373027987,0.8981132075471698,-12.558112151725243,8,40.0,30.0
25,long,0.08,0.05,1101.785686032769,10.178568603276904,2131,402.8114370301827,100.35759282245672,-42.96178493326261,-201.14725478681396,0.8948850305021117,-12.767329616042575,0,20.0,30.0
25,long,0.08,0.0,1112.7512834342563,11.275128343425626,2007,510.7740788990486,94.82767859920457,-44.815807347324835,-214.5082036791364,0.9128051818634778,-12.895024044728643,8,40.0,30.0
25,long,0.08,0.08,1112.7512834342563,11.275128343425626,2007,510.7740788990486,94.82767859920457,-44.815807347324835,-214.5082036791364,0.9128051818634778,-12.895024044728643,8,40.0,30.0
15,long,0.1,0.03,1094.6458586065482,9.464585860654825,683,158.66641909829264,34.10293603391873,-61.25513021004292,-82.42727579859945,0.7628111273792094,-13.033316992288022,0,0.0,50.0
12,long,0.1,0.0,1218.1921573711056,21.81921573711056,370,558.8663558516799,24.378060357085793,-97.53392094072365,-113.18691429679939,0.9648648648648649,-13.1003062599465,0,0.0,50.0
15,long,0.1,0.05,1168.8056578277817,16.88056578277817,608,332.66918416530905,33.09163814654082,-84.03484815008869,-96.03995553948675,0.8766447368421053,-13.131886439222775,0,0.0,50.0
12,long,0.1,0.08,1215.462729528697,21.546272952869707,377,489.653836130157,24.213987894964383,-97.53392094072365,-112.85866997895482,0.946949602122016,-13.356836828295126,0,0.0,50.0
25,long,0.08,0.08,1108.728703758097,10.872870375809702,1986,494.4803779573687,94.15080181096374,-44.815807347324835,-215.94985471803068,0.9118831822759316,-13.369364564289283,8,20.0,30.0
25,long,0.08,0.0,1108.728703758097,10.872870375809702,1986,494.4803779573687,94.15080181096374,-44.815807347324835,-215.94985471803068,0.9118831822759316,-13.369364564289283,8,20.0,30.0
12,long,0.12,0.08,1202.135538914119,20.2135538914119,277,417.44371934726576,19.051796460002638,-94.17262348471081,-109.39570457022182,0.9350180505415162,-13.508018382512432,0,0.0,50.0
20,long,0.12,0.05,1200.4075158078238,20.040751580782377,772,407.6951606504391,42.131827934710174,-88.78100275208044,-138.8849499303052,0.8886010362694301,-13.537796741357013,0,0.0,50.0
15,long,0.12,0.08,1206.931478920573,20.6931478920573,403,499.84954109113613,25.74372989411244,-95.83391499090408,-112.73654229682552,0.9478908188585607,-13.693853720055197,0,0.0,50.0
12,long,0.1,0.03,1076.1396752509584,7.613967525095836,478,120.51267212115341,25.074418902266103,-56.93595340542038,-84.69167915779826,0.7196652719665272,-13.70140245442019,0,0.0,50.0
20,long,0.12,0.03,1121.2162789700935,12.121627897009352,852,217.59126385183671,43.078476418085344,-66.15135242200427,-122.08902033976858,0.789906103286385,-13.828228846580355,5,20.0,80.0
20,long,0.12,0.03,1121.2162789700935,12.121627897009352,852,217.59126385183671,43.078476418085344,-66.15135242200427,-122.08902033976858,0.789906103286385,-13.828228846580355,5,0.0,80.0
20,long,0.12,0.03,1121.2162789700935,12.121627897009352,852,217.59126385183671,43.078476418085344,-66.15135242200427,-122.08902033976858,0.789906103286385,-13.828228846580355,5,40.0,80.0
15,long,0.12,0.0,1214.7169049952067,21.471690499520673,396,586.2432808688322,25.804940849395216,-95.83391499090408,-133.0859518383436,0.9646464646464646,-13.932781589667728,0,0.0,50.0
25,long,0.12,0.03,1130.2847694808067,13.028476948080675,1319,262.16363740691367,63.660170440323625,-70.4809411677835,-126.9113436164962,0.8225928733889311,-14.461372583079186,0,0.0,50.0
20,long,0.12,0.03,1113.4699795786817,11.346997957868165,854,209.91881359288624,43.15232555054651,-66.15135242200427,-122.08902033976858,0.788056206088993,-14.602858785721542,8,20.0,80.0
20,long,0.12,0.03,1113.4699795786817,11.346997957868165,854,209.91881359288624,43.15232555054651,-66.15135242200427,-122.08902033976858,0.788056206088993,-14.602858785721542,8,0.0,80.0
20,long,0.12,0.03,1113.4699795786817,11.346997957868165,854,209.91881359288624,43.15232555054651,-66.15135242200427,-122.08902033976858,0.788056206088993,-14.602858785721542,10,0.0,80.0
20,long,0.12,0.03,1113.4699795786817,11.346997957868165,854,209.91881359288624,43.15232555054651,-66.15135242200427,-122.08902033976858,0.788056206088993,-14.602858785721542,0,20.0,80.0
20,long,0.12,0.03,1113.4699795786817,11.346997957868165,854,209.91881359288624,43.15232555054651,-66.15135242200427,-122.08902033976858,0.788056206088993,-14.602858785721542,0,0.0,80.0
20,long,0.12,0.03,1113.4699795786817,11.346997957868165,854,209.91881359288624,43.15232555054651,-66.15135242200427,-122.08902033976858,0.788056206088993,-14.602858785721542,10,40.0,80.0
20,long,0.12,0.03,1113.4699795786817,11.346997957868165,854,209.91881359288624,43.15232555054651,-66.15135242200427,-122.08902033976858,0.788056206088993,-14.602858785721542,8,40.0,80.0
20,long,0.12,0.03,1113.4699795786817,11.346997957868165,854,209.91881359288624,43.15232555054651,-66.15135242200427,-122.08902033976858,0.788056206088993,-14.602858785721542,0,40.0,80.0
20,long,0.12,0.03,1113.4699795786817,11.346997957868165,854,209.91881359288624,43.15232555054651,-66.15135242200427,-122.08902033976858,0.788056206088993,-14.602858785721542,10,20.0,80.0
25,long,0.08,0.05,1089.496781569205,8.949678156920504,2094,385.1473407968583,98.7551506808777,-44.81012850141815,-213.54169697999976,0.8968481375358166,-15.170445242504929,8,20.0,30.0
15,long,0.1,0.08,1243.0202705911236,24.302027059112355,567,572.5946309565628,33.29402202030417,-114.68147922291314,-118.16886726038092,0.9506172839506173,-16.01086007078063,0,0.0,50.0
12,neutral,0.12,0.05,1037.9895852623313,3.7989585262331276,556,226.17952089224386,34.03563049266339,-56.46939726378719,-58.7057166817433,0.7823741007194245,-16.077146486990195,0,0.0,50.0
15,long,0.1,0.0,1231.6688825911422,23.166888259114216,562,624.0818356728452,33.2374811459689,-114.68147922291314,-118.16886726038092,0.9590747330960854,-17.14599887077877,0,0.0,50.0
15,long,0.12,0.03,1064.3778106743348,6.437781067433479,507,117.68982521873309,26.456260866499733,-60.38601930790628,-113.29885817579066,0.7238658777120316,-17.342967633727937,0,0.0,50.0
15,neutral,0.1,0.03,993.9890197090041,-0.6010980290995918,1192,136.12983051289334,59.865484701015816,-44.5593963794538,-67.62637117847862,0.7390939597315436,-17.350235501859665,0,0.0,50.0
12,long,0.08,0.03,1058.3809240671826,5.8380924067182605,650,116.62721487361696,32.129238689975715,-61.97745949961916,-98.7286258146944,0.7584615384615384,-17.691576733902206,0,0.0,50.0
15,long,0.08,0.03,1065.030855040643,6.503085504064302,967,152.4218403959458,45.73911677613086,-62.65861339021251,-113.75718075857355,0.795243019648397,-17.98235755092813,0,0.0,50.0
12,neutral,0.12,0.03,998.8232078658049,-0.11767921341951251,652,75.79458766142683,35.54253268540669,-52.61130293489987,-55.604272508392796,0.651840490797546,-18.68128371930911,0,0.0,50.0
20,long,0.1,0.03,1112.3511799795551,11.235117997955513,1160,225.20618140656305,56.28680677582321,-80.9271140265929,-117.33321152758344,0.8146551724137931,-18.90967678640153,0,0.0,50.0
25,long,0.1,0.03,1137.8204040487715,13.782040404877147,1738,298.6606490222889,81.70297366660668,-87.57493412407553,-128.86633923936358,0.8469505178365938,-18.933756794313688,0,0.0,50.0
12,long,0.08,0.05,1122.5811342325073,12.258113423250734,585,277.1917030386695,31.280576441343342,-85.28680718476664,-121.57700457535657,0.864957264957265,-19.406778960947086,0,0.0,50.0
25,long,0.12,0.08,1371.744259157642,37.17442591576421,1160,871.6224107175224,62.565532809174414,-161.30721102473558,-171.214038359484,0.9594827586206897,-19.778439309630663,0,0.0,50.0
25,long,0.1,0.05,1262.711774762407,26.2711774762407,1636,579.9023988493022,80.68691090263451,-130.16444853221992,-151.29168430641596,0.9199266503667481,-20.34274129874607,0,0.0,50.0
20,neutral,0.1,0.05,1041.6653566596644,4.166535665966444,1824,470.56950844861683,94.94622264486853,-64.9166578552639,-108.61916219869659,0.8788377192982456,-20.739419800547555,0,0.0,50.0
15,neutral,0.1,0.05,1023.4740346121534,2.3474034612153445,1069,327.45375194862976,58.23512402896476,-63.931022033571594,-100.97187700510881,0.842843779232928,-21.880496999111575,0,0.0,50.0
20,long,0.12,0.08,1260.4752961208446,26.047529612084464,723,667.0280626385457,42.16092334302708,-135.50865972723386,-150.8608790368212,0.9571230982019364,-22.148112257926755,0,0.0,50.0
20,neutral,0.1,0.03,956.1987905231379,-4.380120947686214,1999,178.43581268591768,97.88269633548947,-42.335442452572465,-104.20000006556529,0.7893946973486743,-22.290753686736217,0,0.0,50.0
20,long,0.12,0.0,1251.5216767776158,25.152167677761575,718,727.4776651327481,42.273681367564386,-135.50865972723386,-154.88750732866333,0.9637883008356546,-23.24480560684175,0,0.0,50.0
15,long,0.08,0.05,1143.6244005813899,14.362440058138986,886,345.81889856321624,44.79509595151441,-104.18340085279203,-128.58926435853732,0.8893905191873589,-23.322043415625487,0,0.0,50.0
25,long,0.08,0.0,1162.638999863216,16.263899986321597,1313,919.3682609557522,65.60442349285192,-105.56034411395922,-159.58649466306406,0.9961919268849961,-23.38352798101937,5,40.0,80.0
25,long,0.08,0.0,1162.638999863216,16.263899986321597,1313,919.3682609557522,65.60442349285192,-105.56034411395922,-159.58649466306406,0.9961919268849961,-23.38352798101937,5,40.0,50.0
25,long,0.08,0.0,1162.638999863216,16.263899986321597,1313,919.3682609557522,65.60442349285192,-105.56034411395922,-159.58649466306406,0.9961919268849961,-23.38352798101937,5,0.0,50.0
25,long,0.08,0.0,1162.638999863216,16.263899986321597,1313,919.3682609557522,65.60442349285192,-105.56034411395922,-159.58649466306406,0.9961919268849961,-23.38352798101937,5,0.0,80.0
15,neutral,0.12,0.03,945.6312327561075,-5.436876724389253,914,64.06999239417084,48.03964097029774,-38.33682334954847,-144.63841270170803,0.6947483588621444,-24.169844364339195,0,0.0,50.0
25,long,0.12,0.0,1374.08970296183,37.408970296183,1150,955.8881185470308,62.82790901214145,-175.1490649951843,-185.06073940235842,0.9678260869565217,-24.38878617249021,0,0.0,50.0
15,neutral,0.08,0.03,916.2774810214778,-8.37225189785222,1636,92.48960072730145,78.83031964227641,-29.068823055436724,-149.19914767533828,0.7707823960880196,-24.552856198250147,0,0.0,50.0
25,long,0.08,0.08,1150.5467855406948,15.054678554069483,1413,677.8783233720811,70.45508910566215,-106.69741850405876,-161.62723530921096,0.9752300070771408,-25.035908762608692,5,0.0,80.0
25,long,0.08,0.08,1150.5467855406948,15.054678554069483,1413,677.8783233720811,70.45508910566215,-106.69741850405876,-161.62723530921096,0.9752300070771408,-25.035908762608692,5,40.0,80.0
25,long,0.08,0.08,1150.5467855406948,15.054678554069483,1413,677.8783233720811,70.45508910566215,-106.69741850405876,-161.62723530921096,0.9752300070771408,-25.035908762608692,5,40.0,50.0
25,long,0.08,0.08,1150.5467855406948,15.054678554069483,1413,677.8783233720811,70.45508910566215,-106.69741850405876,-161.62723530921096,0.9752300070771408,-25.035908762608692,5,0.0,50.0
20,long,0.1,0.05,1186.6696459394852,18.666964593948524,1064,432.0676359261743,54.9231060535204,-120.30407942169711,-153.4168352434191,0.900375939849624,-25.09510099473156,0,0.0,50.0
25,neutral,0.12,0.05,1012.0465648674691,1.20465648674691,2054,488.07004801319835,107.44242585435785,-72.28568569651452,-95.78787952852781,0.8816942551119766,-25.270443198633835,0,0.0,50.0
12,long,0.08,0.0,1210.6524467238366,21.065244672383663,527,627.2986835412452,31.51050188915172,-131.2305899868711,-141.04418369609425,0.9715370018975332,-25.356141508482384,0,0.0,50.0
25,long,0.08,0.0,1143.0144737579244,14.30144737579244,1275,889.5293442627606,64.28800233046684,-105.56034411395922,-168.9886655282604,0.996078431372549,-25.816089134808347,5,20.0,50.0
25,long,0.08,0.0,1143.0144737579244,14.30144737579244,1275,889.5293442627606,64.28800233046684,-105.56034411395922,-168.9886655282604,0.996078431372549,-25.816089134808347,5,20.0,80.0
12,neutral,0.08,0.05,978.4938613340059,-2.150613866599406,1037,254.85703759537702,55.63214630748209,-63.898405808383586,-101.80238064086086,0.8341369334619093,-26.41025464115753,0,0.0,50.0
12,long,0.08,0.08,1195.4002596892822,19.540025968928216,538,526.1334261643764,31.304136516382002,-131.2305899868711,-141.04418369609425,0.9516728624535316,-26.88136021193783,0,0.0,50.0
25,long,0.08,0.08,1130.9222594354017,13.092225943540166,1375,648.0394066790885,69.13866794327703,-106.69741850405887,-171.02940617440856,0.9745454545454545,-27.468469916397925,5,20.0,50.0
25,long,0.08,0.08,1130.9222594354017,13.092225943540166,1375,648.0394066790885,69.13866794327703,-106.69741850405887,-171.02940617440856,0.9745454545454545,-27.468469916397925,5,20.0,80.0
20,long,0.1,0.0,1307.0048036488877,30.70048036488877,1008,785.3832957491421,55.20914801241078,-166.9392973327656,-173.9969693214946,0.9533730158730159,-28.08115730101564,0,0.0,50.0
12,neutral,0.1,0.05,948.24922165223,-5.175077834777005,750,171.7366268104928,43.22284706683776,-62.63829821262266,-110.01846066629491,0.796,-29.467490331878547,0,0.0,50.0
12,neutral,0.12,0.08,1008.9190139207014,0.8919013920701445,492,438.1749220568439,34.19374707352298,-87.00908488029222,-89.24540429824833,0.8861788617886179,-29.67309428692994,0,0.0,50.0
20,neutral,0.12,0.05,964.5506878824742,-3.5449312117525777,1366,336.32174432541854,74.64673397079011,-68.4316393371688,-126.46280859431408,0.8521229868228404,-30.39756344261892,0,0.0,50.0
12,neutral,0.08,0.03,915.8994957302318,-8.410050426976818,1156,40.918312957083714,57.188082139095386,-50.40523183454059,-141.06559746668916,0.726643598615917,-30.584899850673448,0,0.0,50.0
15,neutral,0.1,0.08,1026.7049567353506,2.6704956735350605,984,658.9147969900778,58.93390459925652,-94.57765310639593,-112.4327831029899,0.9227642276422764,-31.324439413533213,0,0.0,50.0
15,long,0.08,0.08,1229.0364111861206,22.903641118612065,838,624.5993026406226,45.355033808331484,-154.1585934057598,-160.7601507757945,0.9474940334128878,-31.381944441905603,0,0.0,50.0
15,neutral,0.12,0.05,955.8990723136604,-4.410092768633956,805,215.94264205295738,46.60735243116032,-64.67672564451289,-152.12460481925052,0.8074534161490683,-31.419340702950343,0,0.0,50.0
20,long,0.1,0.08,1268.588132553505,26.85881325535049,1015,693.826328971641,55.10276224506073,-166.9392973327656,-173.9969693214947,0.9467980295566503,-31.922824410553922,0,0.0,50.0
25,long,0.08,0.0,1268.0414109758044,26.80414109758044,1775,1232.4699757286367,87.45391338479479,-164.3795939103586,-189.1770745020549,0.9954929577464788,-31.968590800629887,8,0.0,80.0
15,neutral,0.12,0.08,972.4274717848173,-2.757252821518273,722,537.0352221027357,47.17328332457399,-74.0082277391358,-140.1880329926729,0.9058171745152355,-31.96912279289266,0,0.0,50.0
20,long,0.08,0.03,1029.5129914577938,2.951299145779376,1594,168.21235588421675,74.41258491762432,-86.32167848217352,-183.87671254553186,0.8343789209535759,-32.139040026149274,0,0.0,50.0
25,long,0.08,0.0,1262.826219106085,26.28262191060851,1768,1226.9914620818697,87.19059160774773,-164.3795939103586,-189.177074502055,0.995475113122172,-32.490109987601826,8,40.0,80.0
25,long,0.08,0.05,1096.2653230093817,9.626532300938175,1817,387.1731107607151,86.51594748229121,-111.92692120922152,-176.61022966954397,0.9257017061089708,-32.78205554530548,5,0.0,50.0
25,long,0.08,0.05,1096.2653230093817,9.626532300938175,1817,387.1731107607151,86.51594748229121,-111.92692120922152,-176.61022966954397,0.9257017061089708,-32.78205554530548,5,40.0,50.0
12,neutral,0.1,0.03,892.2612677882854,-10.77387322117146,862,-5.7148548369195185,45.07079750191549,-53.61269768970783,-126.5004025339041,0.6740139211136891,-33.182702654779014,0,0.0,50.0
25,long,0.08,0.05,1092.1819524536968,9.21819524536968,1817,383.0891276075564,86.51533488481823,-111.92692120922152,-176.61022966954397,0.9257017061089708,-33.19039260087398,5,0.0,80.0
25,long,0.08,0.05,1092.1819524536968,9.21819524536968,1817,383.0891276075564,86.51533488481823,-111.92692120922152,-176.61022966954397,0.9257017061089708,-33.19039260087398,5,40.0,80.0
15,neutral,0.08,0.05,905.1757000990156,-9.482429990098444,1496,269.5513433703725,76.95965566395986,-55.92848521443341,-147.88151729119272,0.858957219251337,-33.6550514189881,0,0.0,50.0
25,long,0.08,0.05,1083.629915586647,8.362991558664703,1800,373.89821210317984,85.8764562474926,-111.92692120922152,-179.57504991988685,0.925,-34.19383730009609,5,20.0,50.0
25,long,0.08,0.05,1079.5465450309614,7.9546545030961395,1800,369.81422895002106,85.87584365001965,-111.92692120922152,-180.3029057185688,0.925,-34.638567145598756,5,20.0,80.0
25,long,0.08,0.08,1239.5468088164787,23.954680881647867,1881,927.819736467546,92.58407163905943,-165.51666830045815,-193.5361077653356,0.9766081871345029,-35.37712499675636,8,0.0,80.0
25,long,0.08,0.08,1234.331616946761,23.433161694676095,1874,922.3412228207794,92.32074986201238,-165.51666830045815,-193.53610776533537,0.9765208110992529,-35.89864418372812,8,40.0,80.0
25,neutral,0.1,0.03,906.3628160481298,-9.363718395187016,2888,207.19204221547852,138.1737804893506,-64.94214030179364,-145.47984940481342,0.8244459833795014,-36.12035295596578,0,0.0,50.0
15,long,0.08,0.0,1227.3961128748017,22.73961128748017,829,697.9347268062245,45.5905195229829,-167.99310421760356,-174.59950608867211,0.9577804583835947,-36.3882952822345,0,0.0,50.0
12,neutral,0.12,0.0,969.3566043989616,-3.064339560103838,453,745.0479952647905,35.217155627846786,-87.00908488029222,-149.45137337681047,0.9624724061810155,-36.639633693032025,0,0.0,50.0
25,long,0.08,0.0,1228.9582509087586,22.89582509087586,1706,1177.9286970976077,84.90879945990056,-164.37959391035884,-204.808440494122,0.9953106682297772,-36.658475106937885,8,20.0,80.0
12,neutral,0.08,0.08,1017.5268988730409,1.7526898873040864,939,642.0429221626582,55.486604857858254,-109.84218861048737,-110.42637689916171,0.9243876464323749,-36.72128554080021,0,0.0,50.0
25,long,0.1,0.08,1316.9263500053653,31.69263500053653,1567,863.4338174117532,80.21478847713934,-195.1137402743459,-202.50425458038717,0.9489470325462668,-36.966699810786594,0,0.0,50.0
20,neutral,0.12,0.03,874.4226048516447,-12.557739514835532,1518,62.59357657113197,76.88600010573118,-57.30136960786092,-163.13382195213535,0.7483530961791831,-37.90484149480058,0,0.0,50.0
12,neutral,0.1,0.08,959.0611392166089,-4.093886078339108,667,490.30403423333235,43.2330110457878,-94.21066522501121,-117.41301240124483,0.9010494752623688,-38.22773626590472,0,0.0,50.0
25,neutral,0.12,0.03,885.7225423471225,-11.42774576528775,2234,139.27716934255434,109.78796064866359,-65.18830656293073,-163.99841781207726,0.7931960608773501,-39.18415862477083,0,0.0,50.0
20,neutral,0.1,0.08,1019.9155307951296,1.99155307951296,1714,889.0116003101779,95.50972109837602,-111.55187576633205,-169.96014848227196,0.9387397899649942,-39.97201707450024,0,0.0,50.0
25,long,0.08,0.08,1201.244356605409,20.124435660540893,1813,874.0967884420804,90.07658046375604,-165.5166683004585,-209.48201046918098,0.97573083287369,-40.0046653530557,8,20.0,80.0
20,long,0.08,0.05,1124.5819461650653,12.458194616506535,1492,411.2270180323591,73.11772134759346,-142.86133759521113,-222.21167486844843,0.9088471849865952,-41.51079040547922,0,0.0,50.0
15,neutral,0.08,0.08,962.2733614713102,-3.7726638528689818,1390,731.6268276728515,77.71704193631616,-97.82223007855794,-173.32372563648516,0.9338129496402877,-41.78551915826062,0,0.0,50.0
25,long,0.1,0.0,1313.1987801079035,31.319878010790354,1562,900.3658461399156,80.34530684975778,-208.96662361050812,-216.36198885118438,0.9519846350832266,-42.1882085149213,0,0.0,50.0
20,neutral,0.08,0.03,829.4339026671721,-17.05660973328279,2636,98.19159368509234,124.5297032156403,-50.45636658278261,-215.42374875258838,0.8171471927162367,-42.96470714574699,0,0.0,50.0
15,neutral,0.1,0.0,958.7020508349266,-4.1297949165073415,952,877.943488361327,59.83872248961458,-94.57765310639593,-220.2343940423009,0.9537815126050421,-43.51481055054116,0,0.0,50.0
15,neutral,0.12,0.0,915.1260245021808,-8.487397549781917,681,852.6782963054246,48.21569346198492,-80.02389538542047,-229.63375181486947,0.960352422907489,-43.976253756151536,0,0.0,50.0
25,neutral,0.1,0.05,957.9505861549574,-4.204941384504264,2693,508.3431872295519,135.33386878994648,-107.53165470993815,-162.52408992777555,0.8971407352395099,-44.59064229387449,0,0.0,50.0
25,long,0.08,0.0,1261.2510255067548,26.12510255067548,1962,1241.518453175452,97.51089000134886,-199.61125096898286,-228.045925259608,0.9898063200815495,-45.16056900299978,10,0.0,80.0
25,long,0.08,0.08,1263.004536227681,26.3004536227681,2047,994.3289831906201,100.93357667030716,-200.74832535908251,-234.30900361061288,0.9755740107474352,-45.6394941654873,10,0.0,80.0
25,long,0.08,0.03,977.8030252525732,-2.2196974747426794,2360,171.53530836186184,107.69807878640938,-108.99847089762079,-218.1390860908691,0.8593220338983051,-45.82619304857237,0,0.0,50.0
25,long,0.08,0.0,1247.6337518181654,24.763375181816535,1944,1227.2240353241866,96.83374583867123,-199.6112509689831,-229.54555467016212,0.9897119341563786,-46.59727784238649,10,40.0,80.0
20,long,0.08,0.0,1253.9827072613166,25.39827072613166,1425,842.2815443716456,73.60409985214305,-205.2864268826097,-215.18491317778285,0.9536842105263158,-46.94690299754039,0,0.0,50.0
25,long,0.08,0.08,1249.3872625390923,24.938726253909227,2029,980.0345653393548,100.25643250762954,-200.74832535908274,-235.80863302116722,0.9753573188762937,-47.07620300487395,10,40.0,80.0
25,long,0.08,0.05,1156.3011102933785,15.630111029337854,2244,527.1697975637469,106.47584069366704,-170.6942396219963,-239.92570159008744,0.9295900178253119,-47.57444593676541,10,40.0,80.0
25,long,0.08,0.05,1156.3011102933785,15.630111029337854,2244,527.1697975637469,106.47584069366704,-170.6942396219963,-239.92570159008744,0.9295900178253119,-47.57444593676541,10,0.0,80.0
12,neutral,0.1,0.0,908.7043890282025,-9.12956109717975,631,763.220257812243,44.28853244365189,-94.21066522501121,-203.76964277656498,0.9492868462757528,-47.58124280351136,0,0.0,50.0
12,neutral,0.08,0.0,942.564965429586,-5.743503457041402,905,887.4298730720966,56.35697626431882,-109.84218861048794,-177.77224939405562,0.958011049723757,-47.584772509890556,0,0.0,50.0
20,long,0.08,0.08,1238.5115422947035,23.851154229470353,1432,770.8758322716842,73.50250478563372,-205.2864268826097,-215.18491317778285,0.9490223463687151,-48.494019494201694,0,0.0,50.0
25,neutral,0.12,0.08,951.1715940359319,-4.882840596406811,1934,893.587242548015,107.84552558600296,-122.6044020665829,-157.87084081117223,0.93846949327818,-49.55770325694029,0,0.0,50.0
25,long,0.08,0.05,1140.2052710481846,14.020527104818461,2192,507.0421467208481,104.22221702668796,-171.42644373863436,-243.43094321578212,0.9292883211678832,-49.57895317756095,8,0.0,80.0
25,long,0.08,0.05,1140.2052710481846,14.020527104818461,2192,507.0421467208481,104.22221702668796,-171.42644373863436,-243.43094321578212,0.9292883211678832,-49.57895317756095,8,40.0,80.0
25,long,0.08,0.05,1130.7394017322986,13.073940173229857,2247,507.79962905841853,106.77293516839114,-170.6942396219963,-246.24068604468005,0.9283489096573209,-50.44636601560303,0,0.0,80.0
25,long,0.08,0.05,1130.7394017322986,13.073940173229857,2247,507.79962905841853,106.77293516839114,-170.6942396219963,-246.24068604468005,0.9283489096573209,-50.44636601560303,0,40.0,80.0
20,neutral,0.12,0.08,922.7526156562791,-7.724738434372091,1268,674.6355346682385,74.98528389955857,-115.15929631232211,-168.85788441401166,0.9211356466876972,-50.715421548769314,0,0.0,50.0
25,long,0.08,0.05,1123.792464942301,12.379246494230097,2201,493.0435332730257,104.85822175402342,-170.6942396219963,-244.45747103753422,0.9282144479781917,-51.0518989442455,10,20.0,80.0
25,long,0.08,0.08,1213.0890273538441,21.308902735384414,1952,918.5667128387636,97.1097026371753,-200.74832535908274,-245.18204336073813,0.9743852459016393,-51.17469704037731,10,20.0,80.0
25,long,0.08,0.0,1204.8948358787318,20.489483587873178,1869,1167.522764050186,93.69978095540102,-199.61125096898297,-245.57495399993752,0.9892990904226859,-51.67263940281858,10,20.0,80.0
20,neutral,0.08,0.05,843.9156120270152,-15.608438797298481,2457,345.8560483495332,121.90691029950048,-81.38855124452266,-240.35299600281314,0.8917378917378918,-52.04265397079594,0,0.0,50.0
25,long,0.08,0.05,1113.8793847526845,11.387938475268447,2157,479.3996140454485,102.90557064678663,-171.42644373863436,-247.9627126632289,0.9281409364858599,-52.4381302794833,8,20.0,80.0
25,long,0.08,0.05,1101.8441240869888,10.184412408698881,2198,477.0622408048723,104.93082456015318,-170.6942396219963,-248.1048958985108,0.9272065514103731,-53.42910427282554,0,20.0,80.0
20,neutral,0.08,0.08,933.7151944535493,-6.628480554645068,2335,909.5540468508254,122.11614293315958,-127.75056090327416,-222.0555457341295,0.9408993576017131,-56.05642611233379,0,0.0,50.0
15,neutral,0.08,0.0,893.2798589855879,-10.67201410144121,1351,999.0722921013755,78.81239461941462,-111.65674089040158,-259.08071225882327,0.9607698001480385,-57.12307198150284,0,0.0,50.0
20,neutral,0.12,0.0,893.2481570336073,-10.67518429663927,1226,965.1856697126141,76.02582293352991,-115.15929631232211,-246.80425997403324,0.9502446982055465,-57.563186189037566,0,0.0,50.0
20,neutral,0.1,0.0,892.2381775176088,-10.776182248239115,1680,1015.4979053676461,96.11117696167355,-111.55187576633205,-275.58768912213407,0.9517857142857142,-58.02112943424543,0,0.0,50.0
20,neutral,0.08,0.0,907.7165314110839,-9.228346858891609,2310,1073.1891314194672,123.22985895655859,-127.75056090327416,-224.72118979536845,0.9493506493506494,-58.78957461964228,0,0.0,50.0
25,long,0.08,0.08,1246.3778914445222,24.63778914445222,2174,966.0754452181279,107.87418295211393,-249.51298036242326,-268.0871479032645,0.9668813247470102,-63.62046235943798,0,0.0,80.0
25,neutral,0.12,0.0,876.9849725322533,-12.301502746774668,1883,1173.335843416292,108.5738726747974,-136.44625603703173,-233.93550504181076,0.9569835369091875,-64.93215480997472,0,0.0,50.0
25,long,0.08,0.08,1231.2854478125905,23.128544781259052,2154,950.2306248631428,107.1218062290607,-249.5129803624235,-269.5867773138185,0.9665738161559888,-65.20468819315892,0,40.0,80.0
25,long,0.08,0.0,1250.129294503415,25.012929450341495,2159,1095.3846784387028,108.18324616531072,-263.3769106549943,-280.311776303294,0.9735988883742474,-68.01573256132149,0,0.0,80.0
25,long,0.08,0.0,1235.0368508714841,23.503685087148416,2139,1079.5398580837168,107.43086944225746,-263.37691065499405,-281.81140571384753,0.9733520336605891,-69.59995839504218,0,40.0,80.0
25,long,0.08,0.08,1186.755101595493,18.675510159549297,2078,889.6085148619517,103.98741680426937,-249.51298036242326,-285.6161766435938,0.9653512993262753,-70.45919278135737,0,20.0,80.0
25,neutral,0.1,0.08,896.2498454068138,-10.375015459318615,2557,951.9026603241215,135.6213145995644,-172.48094645206368,-211.1600905658389,0.9421196714900274,-72.67730392322966,0,0.0,50.0
25,neutral,0.08,0.03,667.6452507448552,-33.23547492551448,3848,25.05767319412064,178.75037479320912,-83.26174105150335,-354.0556578479617,0.8435550935550935,-75.91678013336357,0,0.0,50.0
25,long,0.08,0.0,1178.6678874078664,17.86678874078664,2047,1005.4810992466884,103.56946452014068,-263.37691065499405,-297.84080504362305,0.9721543722520762,-76.03832470789273,0,20.0,80.0
25,neutral,0.08,0.05,754.8750095955463,-24.51249904044537,3639,400.9700275229705,176.1617337979003,-127.58504206956457,-301.28041541625385,0.9084913437757626,-77.85203243212743,0,0.0,50.0
25,neutral,0.08,0.0,956.1631788661102,-4.383682113388977,3465,1342.2749906710937,175.64727713885594,-204.1786834260496,-249.2685574601693,0.9512265512265512,-78.10071501421231,0,0.0,50.0
25,neutral,0.08,0.08,899.6206335365904,-10.037936646340961,3490,1093.1066894313235,175.5638321579994,-190.3147531334788,-234.46730157901732,0.9449856733524356,-78.85572766533546,0,0.0,50.0
25,neutral,0.1,0.0,856.4548169989196,-14.354518300108044,2508,1267.1084544600399,136.81912532955567,-186.333829788226,-238.37432065779933,0.9589314194577353,-82.1733832694658,0,0.0,50.0
1 n_grids mode half_pct grid_sl eq ret trades gross nfee worst_day max_dd wr score max_open profit_lock max_daily_loss
2 25 long 0.08 0.0 1397.9111280963439 39.791112809634384 1829 1118.61138190761 89.34110427803469 -54.66635046647207 -101.88736561661199 0.9781301257517769 18.296839388862164 8 0.0 50.0
3 25 long 0.08 0.0 1392.6959362266246 39.269593622662455 1822 1113.1328682608444 89.07778250098772 -54.66635046647207 -101.88736561661199 0.9780461031833151 17.775320201890235 8 40.0 50.0
4 25 long 0.08 0.08 1377.4361374244675 37.74361374244675 1894 1020.5273176511827 92.77597302857623 -54.66635046647207 -102.50464117878687 0.9693769799366421 16.218476543565785 8 0.0 50.0
5 25 long 0.08 0.08 1372.2209455547481 37.22209455547481 1887 1015.0488040044162 92.51265125152923 -54.66635046647207 -102.50464117878687 0.969263381028087 15.696957356593849 8 40.0 50.0
6 25 long 0.08 0.0 1358.8279680292997 35.88279680292997 1760 1064.0701032765814 86.79599035314052 -54.66635046647207 -104.92067967367007 0.9772727272727273 14.236857679304844 8 20.0 50.0
7 25 long 0.08 0.08 1339.133685213397 33.913368521339706 1826 966.8043696257179 90.26848185327287 -54.66635046647207 -105.53795523584495 0.968236582694414 12.236565619605837 8 20.0 50.0
8 25 long 0.08 0.05 1305.7377273966035 30.573772739660352 2243 660.9272563596152 106.21458290512612 -54.82484156455007 -134.23780091713024 0.9259919750334373 7.414430224438818 10 40.0 50.0
9 25 long 0.08 0.05 1305.7377273966035 30.573772739660352 2243 660.9272563596152 106.21458290512612 -54.82484156455007 -134.23780091713024 0.9259919750334373 7.414430224438818 10 0.0 50.0
10 25 long 0.08 0.05 1273.2290820455269 27.322908204552686 2200 626.800992068894 104.59696396548253 -54.82484156455007 -134.23780091713024 0.9245454545454546 4.1635656893311515 10 20.0 50.0
11 25 long 0.08 0.05 1274.1268173351598 27.412681733515978 2194 625.3080156191049 103.98444015678419 -55.57015591838194 -133.67404726819632 0.9247948951686418 4.057932594591579 8 40.0 50.0
12 25 long 0.08 0.05 1274.1268173351598 27.412681733515978 2194 625.3080156191049 103.98444015678419 -55.57015591838194 -133.67404726819632 0.9247948951686418 4.057932594591579 8 0.0 50.0
13 25 long 0.08 0.05 1269.6333024989083 26.963330249890827 2237 630.6752392403805 106.17254510255816 -54.82484156455007 -135.87368396513898 0.9226642825212338 3.722193582268856 0 0.0 50.0
14 25 long 0.08 0.05 1269.6333024989083 26.963330249890827 2237 630.6752392403805 106.17254510255816 -54.82484156455007 -135.87368396513898 0.9226642825212338 3.722193582268856 0 0.0 50.0
15 25 long 0.08 0.05 1269.6333024989083 26.963330249890827 2237 630.6752392403805 106.17254510255816 -54.82484156455007 -135.87368396513898 0.9226642825212338 3.722193582268856 0 40.0 50.0
16 25 long 0.08 0.08 1304.459491306357 30.4459491306357 2087 855.6829832347544 100.87587182425239 -62.51677693859392 -173.81100512689272 0.9458552946813608 3.0003657927128877 10 0.0 50.0
17 25 long 0.08 0.0 1304.2820463031949 30.428204630319488 2075 878.5740502089094 100.46650937600748 -62.51677693859392 -173.98845013005507 0.946987951807229 2.9737490422385573 10 0.0 50.0
18 25 long 0.08 0.0 1303.3736239387122 30.337362393871217 2179 842.8262746516338 104.98721868527448 -65.84157418233985 -167.3725604145027 0.9343735658558971 2.216262118444126 0 0.0 50.0
19 25 long 0.08 0.0 1303.3736239387122 30.337362393871217 2179 842.8262746516338 104.98721868527448 -65.84157418233985 -167.3725604145027 0.9343735658558971 2.216262118444126 0 0.0 50.0
20 25 long 0.08 0.08 1292.3418470283234 29.23418470283234 2071 842.9634310238881 100.27396389142075 -62.51677693859392 -173.81100512689272 0.9454369869628199 1.7886013649095283 10 40.0 50.0
21 25 long 0.08 0.0 1292.1644020251613 29.21644020251613 2059 865.8544979980437 99.8646014431759 -62.51677693859392 -173.98845013005507 0.9465760077707625 1.7619846144351978 10 40.0 50.0
22 25 long 0.08 0.05 1247.8009310396624 24.780093103966237 2159 597.6654829437048 102.66779377688283 -55.57015591838194 -138.20581671564264 0.9235757295044001 1.1987554926695223 8 20.0 50.0
23 25 long 0.08 0.08 1296.157481099035 29.615748109903507 2182 812.2098595260189 104.9076262230056 -65.84157418233985 -174.5887032541798 0.9330889092575618 1.1338406924925604 0 0.0 50.0
24 25 long 0.08 0.08 1296.157481099035 29.615748109903507 2182 812.2098595260189 104.9076262230056 -65.84157418233985 -174.5887032541798 0.9330889092575618 1.1338406924925604 0 0.0 50.0
25 25 long 0.08 0.0 1289.7808097173345 28.978080971733448 2161 828.5563199370484 104.3100781920673 -65.84157418233985 -167.3725604145027 0.933826931975937 0.8569806963063566 0 40.0 50.0
26 25 long 0.08 0.05 1236.34927096897 23.63492709689699 2193 595.7359668195779 104.51730421169512 -54.82484156455007 -135.87368396513898 0.9211126310989513 0.39379042927502006 0 20.0 50.0
27 25 long 0.08 0.08 1282.5646668776574 28.256466687765737 2164 797.9399048114334 104.23048572979843 -65.84157418233985 -174.5887032541798 0.9325323475046211 -0.225440729645209 0 40.0 50.0
28 25 long 0.08 0.08 1259.3235564374731 25.932355643747314 2012 795.9619663232609 97.92940397913668 -62.51677693859392 -175.36061401718916 0.9438369781312127 -1.5907081386903208 10 20.0 50.0
29 25 long 0.08 0.0 1259.146111434311 25.914611143431102 2000 818.8530332974159 97.52004153089177 -62.51677693859392 -175.53805902035128 0.945 -1.6173248891646388 10 20.0 50.0
30 25 long 0.08 0.05 1147.8412009571211 14.784120095712115 1785 420.34470412045823 84.48944027534574 -35.21316528488592 -120.10936470512252 0.9165266106442577 -1.7852977250097855 5 0.0 30.0
31 25 long 0.08 0.05 1147.8412009571211 14.784120095712115 1785 420.34470412045823 84.48944027534574 -35.21316528488592 -120.10936470512252 0.9165266106442577 -1.7852977250097855 5 40.0 30.0
32 25 long 0.08 0.0 1261.5124700601637 26.151247006016366 2101 786.1802135581369 101.84092566781933 -65.84157418233985 -168.14269369398585 0.9319371727748691 -2.0083599333848827 0 20.0 50.0
33 25 long 0.08 0.08 1254.296327220487 25.4296327220487 2104 755.563798432521 101.76133320555047 -65.84157418233985 -175.35883653366284 0.9306083650190115 -3.090781359336397 0 20.0 50.0
34 25 long 0.08 0.05 1135.205793534383 13.520579353438302 1768 407.0698054629229 83.84994904054716 -35.21316528488592 -123.03902246406142 0.9157239819004525 -3.1953213552305435 5 20.0 30.0
35 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 0 0.0 30.0
36 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 5 40.0 50.0
37 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 0 0.0 50.0
38 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 0 20.0 30.0
39 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 0 20.0 50.0
40 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 0 40.0 50.0
41 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 0 40.0 30.0
42 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 5 0.0 30.0
43 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 5 0.0 50.0
44 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 10 40.0 30.0
45 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 8 20.0 50.0
46 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 8 40.0 30.0
47 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 8 40.0 50.0
48 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 10 0.0 30.0
49 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 10 0.0 50.0
50 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 10 20.0 30.0
51 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 10 20.0 50.0
52 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 10 40.0 50.0
53 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 5 20.0 30.0
54 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 5 20.0 50.0
55 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 5 40.0 30.0
56 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 8 0.0 50.0
57 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 8 0.0 30.0
58 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 0 0.0 50.0
59 12 long 0.12 0.05 1180.5141440437385 18.05141440437385 308 282.92810755714413 19.2010653555889 -63.63293586820578 -80.54084655171164 0.8409090909090909 -5.065508683673463 8 20.0 30.0
60 25 long 0.08 0.0 1137.3810945856771 13.738109458567715 1474 590.1090690766704 71.4449647368382 -34.93805315434156 -168.20950929824642 0.9525101763907734 -5.1537819526470745 5 40.0 30.0
61 25 long 0.08 0.0 1137.3810945856771 13.738109458567715 1474 590.1090690766704 71.4449647368382 -34.93805315434156 -168.20950929824642 0.9525101763907734 -5.1537819526470745 5 0.0 30.0
62 25 long 0.08 0.08 1136.1945657236706 13.619456572367062 1493 550.5861371661551 72.43633240984111 -34.93805315434156 -168.77876259807783 0.9497655726724715 -5.300897503839298 5 0.0 30.0
63 25 long 0.08 0.08 1136.1945657236706 13.619456572367062 1493 550.5861371661551 72.43633240984111 -34.93805315434156 -168.77876259807783 0.9497655726724715 -5.300897503839298 5 40.0 30.0
64 25 long 0.08 0.0 1165.97069931178 16.597069931177998 2143 575.931136840335 101.70221229800816 -46.11878114338265 -192.7322510212599 0.9066728884741018 -6.875176962899792 0 0.0 30.0
65 25 long 0.08 0.08 1165.97069931178 16.597069931177998 2143 575.931136840335 101.70221229800816 -46.11878114338265 -192.7322510212599 0.9066728884741018 -6.875176962899792 0 0.0 30.0
66 20 long 0.12 0.03 1135.6843456332908 13.568434563329083 847 231.87397292139397 42.89311882444578 -50.24276668427581 -107.62095367657184 0.7922077922077922 -6.885443125782251 5 40.0 30.0
67 20 long 0.12 0.03 1135.6843456332908 13.568434563329083 847 231.87397292139397 42.89311882444578 -50.24276668427581 -107.62095367657184 0.7922077922077922 -6.885443125782251 5 0.0 30.0
68 20 long 0.12 0.03 1135.6843456332908 13.568434563329083 847 231.87397292139397 42.89311882444578 -50.24276668427581 -107.62095367657184 0.7922077922077922 -6.885443125782251 5 20.0 50.0
69 20 long 0.12 0.03 1135.6843456332908 13.568434563329083 847 231.87397292139397 42.89311882444578 -50.24276668427581 -107.62095367657184 0.7922077922077922 -6.885443125782251 5 40.0 50.0
70 20 long 0.12 0.03 1135.6843456332908 13.568434563329083 847 231.87397292139397 42.89311882444578 -50.24276668427581 -107.62095367657184 0.7922077922077922 -6.885443125782251 5 20.0 30.0
71 20 long 0.12 0.03 1135.6843456332908 13.568434563329083 847 231.87397292139397 42.89311882444578 -50.24276668427581 -107.62095367657184 0.7922077922077922 -6.885443125782251 5 0.0 50.0
72 25 long 0.08 0.0 1122.4863591809087 12.248635918090873 1444 566.5065840356414 70.31642436408208 -34.93805315434156 -175.07793896588328 0.9515235457063712 -6.986676976505759 5 20.0 30.0
73 12 long 0.12 0.05 1175.608365031793 17.560836503179303 311 280.58636652303625 19.37571409443378 -67.89589136744712 -85.93785129322646 0.8392282958199357 -7.104823471716155 8 20.0 80.0
74 12 long 0.12 0.05 1175.608365031793 17.560836503179303 311 280.58636652303625 19.37571409443378 -67.89589136744712 -85.93785129322646 0.8392282958199357 -7.104823471716155 0 0.0 80.0
75 12 long 0.12 0.05 1175.608365031793 17.560836503179303 311 280.58636652303625 19.37571409443378 -67.89589136744712 -85.93785129322646 0.8392282958199357 -7.104823471716155 10 0.0 80.0
76 12 long 0.12 0.05 1175.608365031793 17.560836503179303 311 280.58636652303625 19.37571409443378 -67.89589136744712 -85.93785129322646 0.8392282958199357 -7.104823471716155 0 20.0 80.0
77 12 long 0.12 0.05 1175.608365031793 17.560836503179303 311 280.58636652303625 19.37571409443378 -67.89589136744712 -85.93785129322646 0.8392282958199357 -7.104823471716155 5 20.0 80.0
78 12 long 0.12 0.05 1175.608365031793 17.560836503179303 311 280.58636652303625 19.37571409443378 -67.89589136744712 -85.93785129322646 0.8392282958199357 -7.104823471716155 5 0.0 80.0
79 12 long 0.12 0.05 1175.608365031793 17.560836503179303 311 280.58636652303625 19.37571409443378 -67.89589136744712 -85.93785129322646 0.8392282958199357 -7.104823471716155 8 40.0 80.0
80 12 long 0.12 0.05 1175.608365031793 17.560836503179303 311 280.58636652303625 19.37571409443378 -67.89589136744712 -85.93785129322646 0.8392282958199357 -7.104823471716155 8 0.0 80.0
81 12 long 0.12 0.05 1175.608365031793 17.560836503179303 311 280.58636652303625 19.37571409443378 -67.89589136744712 -85.93785129322646 0.8392282958199357 -7.104823471716155 5 40.0 80.0
82 12 long 0.12 0.05 1175.608365031793 17.560836503179303 311 280.58636652303625 19.37571409443378 -67.89589136744712 -85.93785129322646 0.8392282958199357 -7.104823471716155 10 20.0 80.0
83 12 long 0.12 0.05 1175.608365031793 17.560836503179303 311 280.58636652303625 19.37571409443378 -67.89589136744712 -85.93785129322646 0.8392282958199357 -7.104823471716155 0 40.0 80.0
84 12 long 0.12 0.05 1175.608365031793 17.560836503179303 311 280.58636652303625 19.37571409443378 -67.89589136744712 -85.93785129322646 0.8392282958199357 -7.104823471716155 10 40.0 80.0
85 25 long 0.08 0.08 1121.2998303189036 12.129983031890356 1463 526.9836521251272 71.30779203708497 -34.93805315434156 -175.64719226571356 0.9487354750512645 -7.133792527697789 5 20.0 30.0
86 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 0 40.0 30.0
87 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 0 0.0 30.0
88 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 0 20.0 50.0
89 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 0 20.0 30.0
90 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 0 40.0 50.0
91 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 0 0.0 50.0
92 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 10 40.0 30.0
93 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 10 40.0 50.0
94 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 8 40.0 50.0
95 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 8 0.0 50.0
96 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 8 0.0 30.0
97 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 8 20.0 50.0
98 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 8 40.0 30.0
99 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 10 20.0 50.0
100 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 10 0.0 30.0
101 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 8 20.0 30.0
102 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 10 0.0 50.0
103 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 0 0.0 50.0
104 20 long 0.12 0.03 1127.938046241879 12.793804624187896 849 224.2015226624435 42.96696795690694 -50.24276668427581 -107.62095367657184 0.790341578327444 -7.660073064923438 10 20.0 30.0
105 25 long 0.08 0.0 1157.7954939202243 15.779549392022432 2132 567.3421430997186 101.28842394894701 -46.11878114338265 -192.73225102126014 0.9061913696060038 -7.6926975020553705 0 40.0 30.0
106 25 long 0.08 0.08 1157.7954939202243 15.779549392022432 2132 567.3421430997186 101.28842394894701 -46.11878114338265 -192.73225102126014 0.9061913696060038 -7.6926975020553705 0 40.0 30.0
107 12 long 0.1 0.05 1160.639981828195 16.0639981828195 415 287.8808246742429 24.34881068136027 -65.96155392833498 -87.71954981539272 0.8506024096385543 -8.11044548645063 0 0.0 50.0
108 25 long 0.08 0.0 1152.2873508564207 15.228735085642075 2116 557.8141899897886 100.12306620572392 -46.11878114338265 -196.98067925385715 0.9068998109640832 -8.455933220065576 10 0.0 30.0
109 25 long 0.08 0.08 1152.2873508564207 15.228735085642075 2116 557.8141899897886 100.12306620572392 -46.11878114338265 -196.98067925385715 0.9068998109640832 -8.455933220065576 10 0.0 30.0
110 25 long 0.08 0.05 1130.5880659042618 13.058806590426183 2165 429.6712922463619 101.57412180073922 -42.96178493326261 -183.68928172463336 0.8965357967667437 -9.014192975784267 10 0.0 30.0
111 25 long 0.08 0.05 1130.5880659042618 13.058806590426183 2165 429.6712922463619 101.57412180073922 -42.96178493326261 -183.68928172463336 0.8965357967667437 -9.014192975784267 10 40.0 30.0
112 25 long 0.08 0.0 1145.5873154082087 14.558731540820872 2107 550.7755987528917 99.78451041703838 -46.11878114338265 -196.9806792538576 0.9065021357380162 -9.125936764886802 10 40.0 30.0
113 25 long 0.08 0.08 1145.5873154082087 14.558731540820872 2107 550.7755987528917 99.78451041703838 -46.11878114338265 -196.9806792538576 0.9065021357380162 -9.125936764886802 10 40.0 30.0
114 25 long 0.08 0.05 1127.3665122706623 12.736651227066227 2165 429.6712922463619 101.63662180073922 -42.96178493326261 -186.91083535823395 0.8965357967667437 -9.497426020824252 0 40.0 30.0
115 25 long 0.08 0.05 1127.3665122706623 12.736651227066227 2165 429.6712922463619 101.63662180073922 -42.96178493326261 -186.91083535823395 0.8965357967667437 -9.497426020824252 0 0.0 30.0
116 25 long 0.08 0.0 1141.560014818118 14.15600148181179 2095 537.8633318701434 99.68370601897158 -46.11878114338265 -198.02270069179235 0.9045346062052506 -9.580767895792622 0 20.0 30.0
117 25 long 0.08 0.08 1141.560014818118 14.15600148181179 2095 537.8633318701434 99.68370601897158 -46.11878114338265 -198.02270069179235 0.9045346062052506 -9.580767895792622 0 20.0 30.0
118 15 long 0.12 0.05 1146.4138461034074 14.641384610340742 444 281.9958657009046 25.54491016368575 -65.10586571841566 -113.39236837709984 0.8513513513513513 -10.559993524038948 0 0.0 50.0
119 12 long 0.12 0.03 1110.6656937601829 11.066569376018288 361 142.41245281010382 19.9916028853587 -59.77484153931823 -78.2840404351266 0.6980609418282548 -10.780085107533509 0 0.0 50.0
120 25 long 0.08 0.08 1130.147250491773 13.01472504917731 2071 522.2176262505083 98.30521702858394 -46.11878114338265 -203.0793978984076 0.9048768710767745 -10.974879188757864 10 20.0 30.0
121 25 long 0.08 0.0 1130.147250491773 13.01472504917731 2071 522.2176262505083 98.30521702858394 -46.11878114338265 -203.0793978984076 0.9048768710767745 -10.974879188757864 10 20.0 30.0
122 12 long 0.12 0.0 1224.732709882688 22.47327098826879 264 549.896055719594 19.312854894621676 -94.17262348471081 -109.39570457022182 0.9810606060606061 -11.248301285655543 0 0.0 50.0
123 25 long 0.12 0.05 1283.2152523741586 28.32152523741586 1218 557.1262213962846 62.60538994244905 -110.98849465466697 -141.9289131411324 0.9121510673234812 -12.071468816040852 0 0.0 50.0
124 25 long 0.08 0.05 1105.7826258452312 10.578262584523122 2132 403.62444516026403 100.33271477367626 -42.96178493326261 -197.15031497435166 0.8949343339587242 -12.167788644173243 10 20.0 30.0
125 25 long 0.08 0.08 1117.966475303976 11.796647530397603 2014 516.252592545815 95.09100037625154 -44.815807347324835 -211.43426210996347 0.9131082423038729 -12.219807779298021 8 0.0 30.0
126 25 long 0.08 0.0 1117.966475303976 11.796647530397603 2014 516.252592545815 95.09100037625154 -44.815807347324835 -211.43426210996347 0.9131082423038729 -12.219807779298021 8 0.0 30.0
127 25 long 0.08 0.05 1108.8895958521423 10.888959585214229 2120 405.51821071028405 99.73320631136474 -44.81012850141826 -200.08066373027987 0.8981132075471698 -12.558112151725243 8 0.0 30.0
128 25 long 0.08 0.05 1108.8895958521423 10.888959585214229 2120 405.51821071028405 99.73320631136474 -44.81012850141826 -200.08066373027987 0.8981132075471698 -12.558112151725243 8 40.0 30.0
129 25 long 0.08 0.05 1101.785686032769 10.178568603276904 2131 402.8114370301827 100.35759282245672 -42.96178493326261 -201.14725478681396 0.8948850305021117 -12.767329616042575 0 20.0 30.0
130 25 long 0.08 0.0 1112.7512834342563 11.275128343425626 2007 510.7740788990486 94.82767859920457 -44.815807347324835 -214.5082036791364 0.9128051818634778 -12.895024044728643 8 40.0 30.0
131 25 long 0.08 0.08 1112.7512834342563 11.275128343425626 2007 510.7740788990486 94.82767859920457 -44.815807347324835 -214.5082036791364 0.9128051818634778 -12.895024044728643 8 40.0 30.0
132 15 long 0.1 0.03 1094.6458586065482 9.464585860654825 683 158.66641909829264 34.10293603391873 -61.25513021004292 -82.42727579859945 0.7628111273792094 -13.033316992288022 0 0.0 50.0
133 12 long 0.1 0.0 1218.1921573711056 21.81921573711056 370 558.8663558516799 24.378060357085793 -97.53392094072365 -113.18691429679939 0.9648648648648649 -13.1003062599465 0 0.0 50.0
134 15 long 0.1 0.05 1168.8056578277817 16.88056578277817 608 332.66918416530905 33.09163814654082 -84.03484815008869 -96.03995553948675 0.8766447368421053 -13.131886439222775 0 0.0 50.0
135 12 long 0.1 0.08 1215.462729528697 21.546272952869707 377 489.653836130157 24.213987894964383 -97.53392094072365 -112.85866997895482 0.946949602122016 -13.356836828295126 0 0.0 50.0
136 25 long 0.08 0.08 1108.728703758097 10.872870375809702 1986 494.4803779573687 94.15080181096374 -44.815807347324835 -215.94985471803068 0.9118831822759316 -13.369364564289283 8 20.0 30.0
137 25 long 0.08 0.0 1108.728703758097 10.872870375809702 1986 494.4803779573687 94.15080181096374 -44.815807347324835 -215.94985471803068 0.9118831822759316 -13.369364564289283 8 20.0 30.0
138 12 long 0.12 0.08 1202.135538914119 20.2135538914119 277 417.44371934726576 19.051796460002638 -94.17262348471081 -109.39570457022182 0.9350180505415162 -13.508018382512432 0 0.0 50.0
139 20 long 0.12 0.05 1200.4075158078238 20.040751580782377 772 407.6951606504391 42.131827934710174 -88.78100275208044 -138.8849499303052 0.8886010362694301 -13.537796741357013 0 0.0 50.0
140 15 long 0.12 0.08 1206.931478920573 20.6931478920573 403 499.84954109113613 25.74372989411244 -95.83391499090408 -112.73654229682552 0.9478908188585607 -13.693853720055197 0 0.0 50.0
141 12 long 0.1 0.03 1076.1396752509584 7.613967525095836 478 120.51267212115341 25.074418902266103 -56.93595340542038 -84.69167915779826 0.7196652719665272 -13.70140245442019 0 0.0 50.0
142 20 long 0.12 0.03 1121.2162789700935 12.121627897009352 852 217.59126385183671 43.078476418085344 -66.15135242200427 -122.08902033976858 0.789906103286385 -13.828228846580355 5 20.0 80.0
143 20 long 0.12 0.03 1121.2162789700935 12.121627897009352 852 217.59126385183671 43.078476418085344 -66.15135242200427 -122.08902033976858 0.789906103286385 -13.828228846580355 5 0.0 80.0
144 20 long 0.12 0.03 1121.2162789700935 12.121627897009352 852 217.59126385183671 43.078476418085344 -66.15135242200427 -122.08902033976858 0.789906103286385 -13.828228846580355 5 40.0 80.0
145 15 long 0.12 0.0 1214.7169049952067 21.471690499520673 396 586.2432808688322 25.804940849395216 -95.83391499090408 -133.0859518383436 0.9646464646464646 -13.932781589667728 0 0.0 50.0
146 25 long 0.12 0.03 1130.2847694808067 13.028476948080675 1319 262.16363740691367 63.660170440323625 -70.4809411677835 -126.9113436164962 0.8225928733889311 -14.461372583079186 0 0.0 50.0
147 20 long 0.12 0.03 1113.4699795786817 11.346997957868165 854 209.91881359288624 43.15232555054651 -66.15135242200427 -122.08902033976858 0.788056206088993 -14.602858785721542 8 20.0 80.0
148 20 long 0.12 0.03 1113.4699795786817 11.346997957868165 854 209.91881359288624 43.15232555054651 -66.15135242200427 -122.08902033976858 0.788056206088993 -14.602858785721542 8 0.0 80.0
149 20 long 0.12 0.03 1113.4699795786817 11.346997957868165 854 209.91881359288624 43.15232555054651 -66.15135242200427 -122.08902033976858 0.788056206088993 -14.602858785721542 10 0.0 80.0
150 20 long 0.12 0.03 1113.4699795786817 11.346997957868165 854 209.91881359288624 43.15232555054651 -66.15135242200427 -122.08902033976858 0.788056206088993 -14.602858785721542 0 20.0 80.0
151 20 long 0.12 0.03 1113.4699795786817 11.346997957868165 854 209.91881359288624 43.15232555054651 -66.15135242200427 -122.08902033976858 0.788056206088993 -14.602858785721542 0 0.0 80.0
152 20 long 0.12 0.03 1113.4699795786817 11.346997957868165 854 209.91881359288624 43.15232555054651 -66.15135242200427 -122.08902033976858 0.788056206088993 -14.602858785721542 10 40.0 80.0
153 20 long 0.12 0.03 1113.4699795786817 11.346997957868165 854 209.91881359288624 43.15232555054651 -66.15135242200427 -122.08902033976858 0.788056206088993 -14.602858785721542 8 40.0 80.0
154 20 long 0.12 0.03 1113.4699795786817 11.346997957868165 854 209.91881359288624 43.15232555054651 -66.15135242200427 -122.08902033976858 0.788056206088993 -14.602858785721542 0 40.0 80.0
155 20 long 0.12 0.03 1113.4699795786817 11.346997957868165 854 209.91881359288624 43.15232555054651 -66.15135242200427 -122.08902033976858 0.788056206088993 -14.602858785721542 10 20.0 80.0
156 25 long 0.08 0.05 1089.496781569205 8.949678156920504 2094 385.1473407968583 98.7551506808777 -44.81012850141815 -213.54169697999976 0.8968481375358166 -15.170445242504929 8 20.0 30.0
157 15 long 0.1 0.08 1243.0202705911236 24.302027059112355 567 572.5946309565628 33.29402202030417 -114.68147922291314 -118.16886726038092 0.9506172839506173 -16.01086007078063 0 0.0 50.0
158 12 neutral 0.12 0.05 1037.9895852623313 3.7989585262331276 556 226.17952089224386 34.03563049266339 -56.46939726378719 -58.7057166817433 0.7823741007194245 -16.077146486990195 0 0.0 50.0
159 15 long 0.1 0.0 1231.6688825911422 23.166888259114216 562 624.0818356728452 33.2374811459689 -114.68147922291314 -118.16886726038092 0.9590747330960854 -17.14599887077877 0 0.0 50.0
160 15 long 0.12 0.03 1064.3778106743348 6.437781067433479 507 117.68982521873309 26.456260866499733 -60.38601930790628 -113.29885817579066 0.7238658777120316 -17.342967633727937 0 0.0 50.0
161 15 neutral 0.1 0.03 993.9890197090041 -0.6010980290995918 1192 136.12983051289334 59.865484701015816 -44.5593963794538 -67.62637117847862 0.7390939597315436 -17.350235501859665 0 0.0 50.0
162 12 long 0.08 0.03 1058.3809240671826 5.8380924067182605 650 116.62721487361696 32.129238689975715 -61.97745949961916 -98.7286258146944 0.7584615384615384 -17.691576733902206 0 0.0 50.0
163 15 long 0.08 0.03 1065.030855040643 6.503085504064302 967 152.4218403959458 45.73911677613086 -62.65861339021251 -113.75718075857355 0.795243019648397 -17.98235755092813 0 0.0 50.0
164 12 neutral 0.12 0.03 998.8232078658049 -0.11767921341951251 652 75.79458766142683 35.54253268540669 -52.61130293489987 -55.604272508392796 0.651840490797546 -18.68128371930911 0 0.0 50.0
165 20 long 0.1 0.03 1112.3511799795551 11.235117997955513 1160 225.20618140656305 56.28680677582321 -80.9271140265929 -117.33321152758344 0.8146551724137931 -18.90967678640153 0 0.0 50.0
166 25 long 0.1 0.03 1137.8204040487715 13.782040404877147 1738 298.6606490222889 81.70297366660668 -87.57493412407553 -128.86633923936358 0.8469505178365938 -18.933756794313688 0 0.0 50.0
167 12 long 0.08 0.05 1122.5811342325073 12.258113423250734 585 277.1917030386695 31.280576441343342 -85.28680718476664 -121.57700457535657 0.864957264957265 -19.406778960947086 0 0.0 50.0
168 25 long 0.12 0.08 1371.744259157642 37.17442591576421 1160 871.6224107175224 62.565532809174414 -161.30721102473558 -171.214038359484 0.9594827586206897 -19.778439309630663 0 0.0 50.0
169 25 long 0.1 0.05 1262.711774762407 26.2711774762407 1636 579.9023988493022 80.68691090263451 -130.16444853221992 -151.29168430641596 0.9199266503667481 -20.34274129874607 0 0.0 50.0
170 20 neutral 0.1 0.05 1041.6653566596644 4.166535665966444 1824 470.56950844861683 94.94622264486853 -64.9166578552639 -108.61916219869659 0.8788377192982456 -20.739419800547555 0 0.0 50.0
171 15 neutral 0.1 0.05 1023.4740346121534 2.3474034612153445 1069 327.45375194862976 58.23512402896476 -63.931022033571594 -100.97187700510881 0.842843779232928 -21.880496999111575 0 0.0 50.0
172 20 long 0.12 0.08 1260.4752961208446 26.047529612084464 723 667.0280626385457 42.16092334302708 -135.50865972723386 -150.8608790368212 0.9571230982019364 -22.148112257926755 0 0.0 50.0
173 20 neutral 0.1 0.03 956.1987905231379 -4.380120947686214 1999 178.43581268591768 97.88269633548947 -42.335442452572465 -104.20000006556529 0.7893946973486743 -22.290753686736217 0 0.0 50.0
174 20 long 0.12 0.0 1251.5216767776158 25.152167677761575 718 727.4776651327481 42.273681367564386 -135.50865972723386 -154.88750732866333 0.9637883008356546 -23.24480560684175 0 0.0 50.0
175 15 long 0.08 0.05 1143.6244005813899 14.362440058138986 886 345.81889856321624 44.79509595151441 -104.18340085279203 -128.58926435853732 0.8893905191873589 -23.322043415625487 0 0.0 50.0
176 25 long 0.08 0.0 1162.638999863216 16.263899986321597 1313 919.3682609557522 65.60442349285192 -105.56034411395922 -159.58649466306406 0.9961919268849961 -23.38352798101937 5 40.0 80.0
177 25 long 0.08 0.0 1162.638999863216 16.263899986321597 1313 919.3682609557522 65.60442349285192 -105.56034411395922 -159.58649466306406 0.9961919268849961 -23.38352798101937 5 40.0 50.0
178 25 long 0.08 0.0 1162.638999863216 16.263899986321597 1313 919.3682609557522 65.60442349285192 -105.56034411395922 -159.58649466306406 0.9961919268849961 -23.38352798101937 5 0.0 50.0
179 25 long 0.08 0.0 1162.638999863216 16.263899986321597 1313 919.3682609557522 65.60442349285192 -105.56034411395922 -159.58649466306406 0.9961919268849961 -23.38352798101937 5 0.0 80.0
180 15 neutral 0.12 0.03 945.6312327561075 -5.436876724389253 914 64.06999239417084 48.03964097029774 -38.33682334954847 -144.63841270170803 0.6947483588621444 -24.169844364339195 0 0.0 50.0
181 25 long 0.12 0.0 1374.08970296183 37.408970296183 1150 955.8881185470308 62.82790901214145 -175.1490649951843 -185.06073940235842 0.9678260869565217 -24.38878617249021 0 0.0 50.0
182 15 neutral 0.08 0.03 916.2774810214778 -8.37225189785222 1636 92.48960072730145 78.83031964227641 -29.068823055436724 -149.19914767533828 0.7707823960880196 -24.552856198250147 0 0.0 50.0
183 25 long 0.08 0.08 1150.5467855406948 15.054678554069483 1413 677.8783233720811 70.45508910566215 -106.69741850405876 -161.62723530921096 0.9752300070771408 -25.035908762608692 5 0.0 80.0
184 25 long 0.08 0.08 1150.5467855406948 15.054678554069483 1413 677.8783233720811 70.45508910566215 -106.69741850405876 -161.62723530921096 0.9752300070771408 -25.035908762608692 5 40.0 80.0
185 25 long 0.08 0.08 1150.5467855406948 15.054678554069483 1413 677.8783233720811 70.45508910566215 -106.69741850405876 -161.62723530921096 0.9752300070771408 -25.035908762608692 5 40.0 50.0
186 25 long 0.08 0.08 1150.5467855406948 15.054678554069483 1413 677.8783233720811 70.45508910566215 -106.69741850405876 -161.62723530921096 0.9752300070771408 -25.035908762608692 5 0.0 50.0
187 20 long 0.1 0.05 1186.6696459394852 18.666964593948524 1064 432.0676359261743 54.9231060535204 -120.30407942169711 -153.4168352434191 0.900375939849624 -25.09510099473156 0 0.0 50.0
188 25 neutral 0.12 0.05 1012.0465648674691 1.20465648674691 2054 488.07004801319835 107.44242585435785 -72.28568569651452 -95.78787952852781 0.8816942551119766 -25.270443198633835 0 0.0 50.0
189 12 long 0.08 0.0 1210.6524467238366 21.065244672383663 527 627.2986835412452 31.51050188915172 -131.2305899868711 -141.04418369609425 0.9715370018975332 -25.356141508482384 0 0.0 50.0
190 25 long 0.08 0.0 1143.0144737579244 14.30144737579244 1275 889.5293442627606 64.28800233046684 -105.56034411395922 -168.9886655282604 0.996078431372549 -25.816089134808347 5 20.0 50.0
191 25 long 0.08 0.0 1143.0144737579244 14.30144737579244 1275 889.5293442627606 64.28800233046684 -105.56034411395922 -168.9886655282604 0.996078431372549 -25.816089134808347 5 20.0 80.0
192 12 neutral 0.08 0.05 978.4938613340059 -2.150613866599406 1037 254.85703759537702 55.63214630748209 -63.898405808383586 -101.80238064086086 0.8341369334619093 -26.41025464115753 0 0.0 50.0
193 12 long 0.08 0.08 1195.4002596892822 19.540025968928216 538 526.1334261643764 31.304136516382002 -131.2305899868711 -141.04418369609425 0.9516728624535316 -26.88136021193783 0 0.0 50.0
194 25 long 0.08 0.08 1130.9222594354017 13.092225943540166 1375 648.0394066790885 69.13866794327703 -106.69741850405887 -171.02940617440856 0.9745454545454545 -27.468469916397925 5 20.0 50.0
195 25 long 0.08 0.08 1130.9222594354017 13.092225943540166 1375 648.0394066790885 69.13866794327703 -106.69741850405887 -171.02940617440856 0.9745454545454545 -27.468469916397925 5 20.0 80.0
196 20 long 0.1 0.0 1307.0048036488877 30.70048036488877 1008 785.3832957491421 55.20914801241078 -166.9392973327656 -173.9969693214946 0.9533730158730159 -28.08115730101564 0 0.0 50.0
197 12 neutral 0.1 0.05 948.24922165223 -5.175077834777005 750 171.7366268104928 43.22284706683776 -62.63829821262266 -110.01846066629491 0.796 -29.467490331878547 0 0.0 50.0
198 12 neutral 0.12 0.08 1008.9190139207014 0.8919013920701445 492 438.1749220568439 34.19374707352298 -87.00908488029222 -89.24540429824833 0.8861788617886179 -29.67309428692994 0 0.0 50.0
199 20 neutral 0.12 0.05 964.5506878824742 -3.5449312117525777 1366 336.32174432541854 74.64673397079011 -68.4316393371688 -126.46280859431408 0.8521229868228404 -30.39756344261892 0 0.0 50.0
200 12 neutral 0.08 0.03 915.8994957302318 -8.410050426976818 1156 40.918312957083714 57.188082139095386 -50.40523183454059 -141.06559746668916 0.726643598615917 -30.584899850673448 0 0.0 50.0
201 15 neutral 0.1 0.08 1026.7049567353506 2.6704956735350605 984 658.9147969900778 58.93390459925652 -94.57765310639593 -112.4327831029899 0.9227642276422764 -31.324439413533213 0 0.0 50.0
202 15 long 0.08 0.08 1229.0364111861206 22.903641118612065 838 624.5993026406226 45.355033808331484 -154.1585934057598 -160.7601507757945 0.9474940334128878 -31.381944441905603 0 0.0 50.0
203 15 neutral 0.12 0.05 955.8990723136604 -4.410092768633956 805 215.94264205295738 46.60735243116032 -64.67672564451289 -152.12460481925052 0.8074534161490683 -31.419340702950343 0 0.0 50.0
204 20 long 0.1 0.08 1268.588132553505 26.85881325535049 1015 693.826328971641 55.10276224506073 -166.9392973327656 -173.9969693214947 0.9467980295566503 -31.922824410553922 0 0.0 50.0
205 25 long 0.08 0.0 1268.0414109758044 26.80414109758044 1775 1232.4699757286367 87.45391338479479 -164.3795939103586 -189.1770745020549 0.9954929577464788 -31.968590800629887 8 0.0 80.0
206 15 neutral 0.12 0.08 972.4274717848173 -2.757252821518273 722 537.0352221027357 47.17328332457399 -74.0082277391358 -140.1880329926729 0.9058171745152355 -31.96912279289266 0 0.0 50.0
207 20 long 0.08 0.03 1029.5129914577938 2.951299145779376 1594 168.21235588421675 74.41258491762432 -86.32167848217352 -183.87671254553186 0.8343789209535759 -32.139040026149274 0 0.0 50.0
208 25 long 0.08 0.0 1262.826219106085 26.28262191060851 1768 1226.9914620818697 87.19059160774773 -164.3795939103586 -189.177074502055 0.995475113122172 -32.490109987601826 8 40.0 80.0
209 25 long 0.08 0.05 1096.2653230093817 9.626532300938175 1817 387.1731107607151 86.51594748229121 -111.92692120922152 -176.61022966954397 0.9257017061089708 -32.78205554530548 5 0.0 50.0
210 25 long 0.08 0.05 1096.2653230093817 9.626532300938175 1817 387.1731107607151 86.51594748229121 -111.92692120922152 -176.61022966954397 0.9257017061089708 -32.78205554530548 5 40.0 50.0
211 12 neutral 0.1 0.03 892.2612677882854 -10.77387322117146 862 -5.7148548369195185 45.07079750191549 -53.61269768970783 -126.5004025339041 0.6740139211136891 -33.182702654779014 0 0.0 50.0
212 25 long 0.08 0.05 1092.1819524536968 9.21819524536968 1817 383.0891276075564 86.51533488481823 -111.92692120922152 -176.61022966954397 0.9257017061089708 -33.19039260087398 5 0.0 80.0
213 25 long 0.08 0.05 1092.1819524536968 9.21819524536968 1817 383.0891276075564 86.51533488481823 -111.92692120922152 -176.61022966954397 0.9257017061089708 -33.19039260087398 5 40.0 80.0
214 15 neutral 0.08 0.05 905.1757000990156 -9.482429990098444 1496 269.5513433703725 76.95965566395986 -55.92848521443341 -147.88151729119272 0.858957219251337 -33.6550514189881 0 0.0 50.0
215 25 long 0.08 0.05 1083.629915586647 8.362991558664703 1800 373.89821210317984 85.8764562474926 -111.92692120922152 -179.57504991988685 0.925 -34.19383730009609 5 20.0 50.0
216 25 long 0.08 0.05 1079.5465450309614 7.9546545030961395 1800 369.81422895002106 85.87584365001965 -111.92692120922152 -180.3029057185688 0.925 -34.638567145598756 5 20.0 80.0
217 25 long 0.08 0.08 1239.5468088164787 23.954680881647867 1881 927.819736467546 92.58407163905943 -165.51666830045815 -193.5361077653356 0.9766081871345029 -35.37712499675636 8 0.0 80.0
218 25 long 0.08 0.08 1234.331616946761 23.433161694676095 1874 922.3412228207794 92.32074986201238 -165.51666830045815 -193.53610776533537 0.9765208110992529 -35.89864418372812 8 40.0 80.0
219 25 neutral 0.1 0.03 906.3628160481298 -9.363718395187016 2888 207.19204221547852 138.1737804893506 -64.94214030179364 -145.47984940481342 0.8244459833795014 -36.12035295596578 0 0.0 50.0
220 15 long 0.08 0.0 1227.3961128748017 22.73961128748017 829 697.9347268062245 45.5905195229829 -167.99310421760356 -174.59950608867211 0.9577804583835947 -36.3882952822345 0 0.0 50.0
221 12 neutral 0.12 0.0 969.3566043989616 -3.064339560103838 453 745.0479952647905 35.217155627846786 -87.00908488029222 -149.45137337681047 0.9624724061810155 -36.639633693032025 0 0.0 50.0
222 25 long 0.08 0.0 1228.9582509087586 22.89582509087586 1706 1177.9286970976077 84.90879945990056 -164.37959391035884 -204.808440494122 0.9953106682297772 -36.658475106937885 8 20.0 80.0
223 12 neutral 0.08 0.08 1017.5268988730409 1.7526898873040864 939 642.0429221626582 55.486604857858254 -109.84218861048737 -110.42637689916171 0.9243876464323749 -36.72128554080021 0 0.0 50.0
224 25 long 0.1 0.08 1316.9263500053653 31.69263500053653 1567 863.4338174117532 80.21478847713934 -195.1137402743459 -202.50425458038717 0.9489470325462668 -36.966699810786594 0 0.0 50.0
225 20 neutral 0.12 0.03 874.4226048516447 -12.557739514835532 1518 62.59357657113197 76.88600010573118 -57.30136960786092 -163.13382195213535 0.7483530961791831 -37.90484149480058 0 0.0 50.0
226 12 neutral 0.1 0.08 959.0611392166089 -4.093886078339108 667 490.30403423333235 43.2330110457878 -94.21066522501121 -117.41301240124483 0.9010494752623688 -38.22773626590472 0 0.0 50.0
227 25 neutral 0.12 0.03 885.7225423471225 -11.42774576528775 2234 139.27716934255434 109.78796064866359 -65.18830656293073 -163.99841781207726 0.7931960608773501 -39.18415862477083 0 0.0 50.0
228 20 neutral 0.1 0.08 1019.9155307951296 1.99155307951296 1714 889.0116003101779 95.50972109837602 -111.55187576633205 -169.96014848227196 0.9387397899649942 -39.97201707450024 0 0.0 50.0
229 25 long 0.08 0.08 1201.244356605409 20.124435660540893 1813 874.0967884420804 90.07658046375604 -165.5166683004585 -209.48201046918098 0.97573083287369 -40.0046653530557 8 20.0 80.0
230 20 long 0.08 0.05 1124.5819461650653 12.458194616506535 1492 411.2270180323591 73.11772134759346 -142.86133759521113 -222.21167486844843 0.9088471849865952 -41.51079040547922 0 0.0 50.0
231 15 neutral 0.08 0.08 962.2733614713102 -3.7726638528689818 1390 731.6268276728515 77.71704193631616 -97.82223007855794 -173.32372563648516 0.9338129496402877 -41.78551915826062 0 0.0 50.0
232 25 long 0.1 0.0 1313.1987801079035 31.319878010790354 1562 900.3658461399156 80.34530684975778 -208.96662361050812 -216.36198885118438 0.9519846350832266 -42.1882085149213 0 0.0 50.0
233 20 neutral 0.08 0.03 829.4339026671721 -17.05660973328279 2636 98.19159368509234 124.5297032156403 -50.45636658278261 -215.42374875258838 0.8171471927162367 -42.96470714574699 0 0.0 50.0
234 15 neutral 0.1 0.0 958.7020508349266 -4.1297949165073415 952 877.943488361327 59.83872248961458 -94.57765310639593 -220.2343940423009 0.9537815126050421 -43.51481055054116 0 0.0 50.0
235 15 neutral 0.12 0.0 915.1260245021808 -8.487397549781917 681 852.6782963054246 48.21569346198492 -80.02389538542047 -229.63375181486947 0.960352422907489 -43.976253756151536 0 0.0 50.0
236 25 neutral 0.1 0.05 957.9505861549574 -4.204941384504264 2693 508.3431872295519 135.33386878994648 -107.53165470993815 -162.52408992777555 0.8971407352395099 -44.59064229387449 0 0.0 50.0
237 25 long 0.08 0.0 1261.2510255067548 26.12510255067548 1962 1241.518453175452 97.51089000134886 -199.61125096898286 -228.045925259608 0.9898063200815495 -45.16056900299978 10 0.0 80.0
238 25 long 0.08 0.08 1263.004536227681 26.3004536227681 2047 994.3289831906201 100.93357667030716 -200.74832535908251 -234.30900361061288 0.9755740107474352 -45.6394941654873 10 0.0 80.0
239 25 long 0.08 0.03 977.8030252525732 -2.2196974747426794 2360 171.53530836186184 107.69807878640938 -108.99847089762079 -218.1390860908691 0.8593220338983051 -45.82619304857237 0 0.0 50.0
240 25 long 0.08 0.0 1247.6337518181654 24.763375181816535 1944 1227.2240353241866 96.83374583867123 -199.6112509689831 -229.54555467016212 0.9897119341563786 -46.59727784238649 10 40.0 80.0
241 20 long 0.08 0.0 1253.9827072613166 25.39827072613166 1425 842.2815443716456 73.60409985214305 -205.2864268826097 -215.18491317778285 0.9536842105263158 -46.94690299754039 0 0.0 50.0
242 25 long 0.08 0.08 1249.3872625390923 24.938726253909227 2029 980.0345653393548 100.25643250762954 -200.74832535908274 -235.80863302116722 0.9753573188762937 -47.07620300487395 10 40.0 80.0
243 25 long 0.08 0.05 1156.3011102933785 15.630111029337854 2244 527.1697975637469 106.47584069366704 -170.6942396219963 -239.92570159008744 0.9295900178253119 -47.57444593676541 10 40.0 80.0
244 25 long 0.08 0.05 1156.3011102933785 15.630111029337854 2244 527.1697975637469 106.47584069366704 -170.6942396219963 -239.92570159008744 0.9295900178253119 -47.57444593676541 10 0.0 80.0
245 12 neutral 0.1 0.0 908.7043890282025 -9.12956109717975 631 763.220257812243 44.28853244365189 -94.21066522501121 -203.76964277656498 0.9492868462757528 -47.58124280351136 0 0.0 50.0
246 12 neutral 0.08 0.0 942.564965429586 -5.743503457041402 905 887.4298730720966 56.35697626431882 -109.84218861048794 -177.77224939405562 0.958011049723757 -47.584772509890556 0 0.0 50.0
247 20 long 0.08 0.08 1238.5115422947035 23.851154229470353 1432 770.8758322716842 73.50250478563372 -205.2864268826097 -215.18491317778285 0.9490223463687151 -48.494019494201694 0 0.0 50.0
248 25 neutral 0.12 0.08 951.1715940359319 -4.882840596406811 1934 893.587242548015 107.84552558600296 -122.6044020665829 -157.87084081117223 0.93846949327818 -49.55770325694029 0 0.0 50.0
249 25 long 0.08 0.05 1140.2052710481846 14.020527104818461 2192 507.0421467208481 104.22221702668796 -171.42644373863436 -243.43094321578212 0.9292883211678832 -49.57895317756095 8 0.0 80.0
250 25 long 0.08 0.05 1140.2052710481846 14.020527104818461 2192 507.0421467208481 104.22221702668796 -171.42644373863436 -243.43094321578212 0.9292883211678832 -49.57895317756095 8 40.0 80.0
251 25 long 0.08 0.05 1130.7394017322986 13.073940173229857 2247 507.79962905841853 106.77293516839114 -170.6942396219963 -246.24068604468005 0.9283489096573209 -50.44636601560303 0 0.0 80.0
252 25 long 0.08 0.05 1130.7394017322986 13.073940173229857 2247 507.79962905841853 106.77293516839114 -170.6942396219963 -246.24068604468005 0.9283489096573209 -50.44636601560303 0 40.0 80.0
253 20 neutral 0.12 0.08 922.7526156562791 -7.724738434372091 1268 674.6355346682385 74.98528389955857 -115.15929631232211 -168.85788441401166 0.9211356466876972 -50.715421548769314 0 0.0 50.0
254 25 long 0.08 0.05 1123.792464942301 12.379246494230097 2201 493.0435332730257 104.85822175402342 -170.6942396219963 -244.45747103753422 0.9282144479781917 -51.0518989442455 10 20.0 80.0
255 25 long 0.08 0.08 1213.0890273538441 21.308902735384414 1952 918.5667128387636 97.1097026371753 -200.74832535908274 -245.18204336073813 0.9743852459016393 -51.17469704037731 10 20.0 80.0
256 25 long 0.08 0.0 1204.8948358787318 20.489483587873178 1869 1167.522764050186 93.69978095540102 -199.61125096898297 -245.57495399993752 0.9892990904226859 -51.67263940281858 10 20.0 80.0
257 20 neutral 0.08 0.05 843.9156120270152 -15.608438797298481 2457 345.8560483495332 121.90691029950048 -81.38855124452266 -240.35299600281314 0.8917378917378918 -52.04265397079594 0 0.0 50.0
258 25 long 0.08 0.05 1113.8793847526845 11.387938475268447 2157 479.3996140454485 102.90557064678663 -171.42644373863436 -247.9627126632289 0.9281409364858599 -52.4381302794833 8 20.0 80.0
259 25 long 0.08 0.05 1101.8441240869888 10.184412408698881 2198 477.0622408048723 104.93082456015318 -170.6942396219963 -248.1048958985108 0.9272065514103731 -53.42910427282554 0 20.0 80.0
260 20 neutral 0.08 0.08 933.7151944535493 -6.628480554645068 2335 909.5540468508254 122.11614293315958 -127.75056090327416 -222.0555457341295 0.9408993576017131 -56.05642611233379 0 0.0 50.0
261 15 neutral 0.08 0.0 893.2798589855879 -10.67201410144121 1351 999.0722921013755 78.81239461941462 -111.65674089040158 -259.08071225882327 0.9607698001480385 -57.12307198150284 0 0.0 50.0
262 20 neutral 0.12 0.0 893.2481570336073 -10.67518429663927 1226 965.1856697126141 76.02582293352991 -115.15929631232211 -246.80425997403324 0.9502446982055465 -57.563186189037566 0 0.0 50.0
263 20 neutral 0.1 0.0 892.2381775176088 -10.776182248239115 1680 1015.4979053676461 96.11117696167355 -111.55187576633205 -275.58768912213407 0.9517857142857142 -58.02112943424543 0 0.0 50.0
264 20 neutral 0.08 0.0 907.7165314110839 -9.228346858891609 2310 1073.1891314194672 123.22985895655859 -127.75056090327416 -224.72118979536845 0.9493506493506494 -58.78957461964228 0 0.0 50.0
265 25 long 0.08 0.08 1246.3778914445222 24.63778914445222 2174 966.0754452181279 107.87418295211393 -249.51298036242326 -268.0871479032645 0.9668813247470102 -63.62046235943798 0 0.0 80.0
266 25 neutral 0.12 0.0 876.9849725322533 -12.301502746774668 1883 1173.335843416292 108.5738726747974 -136.44625603703173 -233.93550504181076 0.9569835369091875 -64.93215480997472 0 0.0 50.0
267 25 long 0.08 0.08 1231.2854478125905 23.128544781259052 2154 950.2306248631428 107.1218062290607 -249.5129803624235 -269.5867773138185 0.9665738161559888 -65.20468819315892 0 40.0 80.0
268 25 long 0.08 0.0 1250.129294503415 25.012929450341495 2159 1095.3846784387028 108.18324616531072 -263.3769106549943 -280.311776303294 0.9735988883742474 -68.01573256132149 0 0.0 80.0
269 25 long 0.08 0.0 1235.0368508714841 23.503685087148416 2139 1079.5398580837168 107.43086944225746 -263.37691065499405 -281.81140571384753 0.9733520336605891 -69.59995839504218 0 40.0 80.0
270 25 long 0.08 0.08 1186.755101595493 18.675510159549297 2078 889.6085148619517 103.98741680426937 -249.51298036242326 -285.6161766435938 0.9653512993262753 -70.45919278135737 0 20.0 80.0
271 25 neutral 0.1 0.08 896.2498454068138 -10.375015459318615 2557 951.9026603241215 135.6213145995644 -172.48094645206368 -211.1600905658389 0.9421196714900274 -72.67730392322966 0 0.0 50.0
272 25 neutral 0.08 0.03 667.6452507448552 -33.23547492551448 3848 25.05767319412064 178.75037479320912 -83.26174105150335 -354.0556578479617 0.8435550935550935 -75.91678013336357 0 0.0 50.0
273 25 long 0.08 0.0 1178.6678874078664 17.86678874078664 2047 1005.4810992466884 103.56946452014068 -263.37691065499405 -297.84080504362305 0.9721543722520762 -76.03832470789273 0 20.0 80.0
274 25 neutral 0.08 0.05 754.8750095955463 -24.51249904044537 3639 400.9700275229705 176.1617337979003 -127.58504206956457 -301.28041541625385 0.9084913437757626 -77.85203243212743 0 0.0 50.0
275 25 neutral 0.08 0.0 956.1631788661102 -4.383682113388977 3465 1342.2749906710937 175.64727713885594 -204.1786834260496 -249.2685574601693 0.9512265512265512 -78.10071501421231 0 0.0 50.0
276 25 neutral 0.08 0.08 899.6206335365904 -10.037936646340961 3490 1093.1066894313235 175.5638321579994 -190.3147531334788 -234.46730157901732 0.9449856733524356 -78.85572766533546 0 0.0 50.0
277 25 neutral 0.1 0.0 856.4548169989196 -14.354518300108044 2508 1267.1084544600399 136.81912532955567 -186.333829788226 -238.37432065779933 0.9589314194577353 -82.1733832694658 0 0.0 50.0

Binary file not shown.

BIN
models/trading_model.pkl Normal file

Binary file not shown.

View File

@@ -8,3 +8,4 @@ scikit-learn
joblib joblib
lightgbm>=3.0.0 lightgbm>=3.0.0
optuna>=3.0.0 optuna>=3.0.0
matplotlib

1
strategy/__init__.py Normal file
View File

@@ -0,0 +1 @@
from .bb_backtest import BBConfig, BBResult, BBTrade, run_bb_backtest

315
strategy/bb_backtest.py Normal file
View File

@@ -0,0 +1,315 @@
"""Bollinger Band mean-reversion strategy backtest.
Logic:
- Price touches upper BB → close any long, open short
- Price touches lower BB → close any short, open long
- Always in position (flip between long and short)
Uses 5-minute OHLC data from the database.
"""
from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime, timezone
from typing import List, Optional
import numpy as np
import pandas as pd
from .data_loader import KlineSource, load_klines
from .indicators import bollinger
# ---------------------------------------------------------------------------
# Config & result types
# ---------------------------------------------------------------------------
@dataclass
class BBConfig:
# Bollinger Band parameters
bb_period: int = 20 # SMA window
bb_std: float = 2.0 # standard deviation multiplier
# Position sizing
margin_per_trade: float = 80.0
leverage: float = 100.0
initial_capital: float = 1000.0
# Risk management
max_daily_loss: float = 150.0 # stop trading after this daily loss
stop_loss_pct: float = 0.0 # 0 = disabled; e.g. 0.02 = 2% SL from entry
# Dynamic sizing: if > 0, margin = equity * margin_pct (overrides margin_per_trade)
margin_pct: float = 0.0 # e.g. 0.01 = 1% of equity per trade
# Fee structure (taker)
fee_rate: float = 0.0006 # 0.06%
rebate_rate: float = 0.0 # instant maker rebate (if any)
# Delayed rebate: rebate_pct of daily fees returned next day at rebate_hour UTC
rebate_pct: float = 0.0 # e.g. 0.70 = 70% rebate
rebate_hour_utc: int = 0 # hour in UTC when rebate arrives (0 = 8am UTC+8)
@dataclass
class BBTrade:
side: str # "long" or "short"
entry_price: float
exit_price: float
entry_time: object # pd.Timestamp
exit_time: object
margin: float
leverage: float
qty: float
gross_pnl: float
fee: float
net_pnl: float
@dataclass
class BBResult:
equity_curve: pd.DataFrame # columns: equity, balance, price, position
trades: List[BBTrade]
daily_stats: pd.DataFrame # daily equity + pnl
total_fee: float
total_rebate: float
config: BBConfig
# ---------------------------------------------------------------------------
# Backtest engine
# ---------------------------------------------------------------------------
def run_bb_backtest(df: pd.DataFrame, cfg: BBConfig) -> BBResult:
"""Run Bollinger Band mean-reversion backtest on 5m OHLC data."""
close = df["close"].astype(float)
high = df["high"].astype(float)
low = df["low"].astype(float)
n = len(df)
# Compute Bollinger Bands
bb_mid, bb_upper, bb_lower, bb_width = bollinger(close, cfg.bb_period, cfg.bb_std)
# Convert to numpy for speed
arr_close = close.values
arr_high = high.values
arr_low = low.values
arr_upper = bb_upper.values
arr_lower = bb_lower.values
ts_index = df.index
# State
balance = cfg.initial_capital
position = 0 # +1 = long, -1 = short, 0 = flat
entry_price = 0.0
entry_time = None
entry_margin = 0.0
entry_qty = 0.0
trades: List[BBTrade] = []
total_fee = 0.0
total_rebate = 0.0
# Daily tracking
day_pnl = 0.0
day_stopped = False
current_day = None
# Delayed rebate tracking
pending_rebate = 0.0 # fees from previous day to be rebated
today_fees = 0.0 # fees accumulated today
rebate_applied_today = False
# Output arrays
out_equity = np.full(n, np.nan)
out_balance = np.full(n, np.nan)
out_position = np.zeros(n)
def unrealised(price):
if position == 0:
return 0.0
if position == 1:
return entry_qty * (price - entry_price)
else:
return entry_qty * (entry_price - price)
def close_position(exit_price, exit_idx):
nonlocal balance, position, entry_price, entry_time, entry_margin, entry_qty
nonlocal total_fee, total_rebate, day_pnl, today_fees
if position == 0:
return
if position == 1:
gross = entry_qty * (exit_price - entry_price)
else:
gross = entry_qty * (entry_price - exit_price)
exit_notional = entry_qty * exit_price
fee = exit_notional * cfg.fee_rate
rebate = exit_notional * cfg.rebate_rate # instant rebate only
net = gross - fee + rebate
trades.append(BBTrade(
side="long" if position == 1 else "short",
entry_price=entry_price,
exit_price=exit_price,
entry_time=entry_time,
exit_time=ts_index[exit_idx],
margin=entry_margin,
leverage=cfg.leverage,
qty=entry_qty,
gross_pnl=gross,
fee=fee,
net_pnl=net,
))
balance += net
total_fee += fee
total_rebate += rebate
today_fees += fee
day_pnl += net
position = 0
entry_price = 0.0
entry_time = None
entry_margin = 0.0
entry_qty = 0.0
def open_position(side, price, idx):
nonlocal position, entry_price, entry_time, entry_margin, entry_qty
nonlocal balance, total_fee, day_pnl, today_fees
if cfg.margin_pct > 0:
equity = balance + unrealised(price) if position != 0 else balance
margin = equity * cfg.margin_pct
else:
margin = cfg.margin_per_trade
margin = min(margin, balance * 0.95)
if margin <= 0:
return
notional = margin * cfg.leverage
qty = notional / price
fee = notional * cfg.fee_rate
balance -= fee
total_fee += fee
today_fees += fee
day_pnl -= fee
position = 1 if side == "long" else -1
entry_price = price
entry_time = ts_index[idx]
entry_margin = margin
entry_qty = qty
# Main loop
for i in range(n):
# Daily reset + delayed rebate
bar_day = ts_index[i].date() if hasattr(ts_index[i], 'date') else None
bar_hour = ts_index[i].hour if hasattr(ts_index[i], 'hour') else 0
if bar_day is not None and bar_day != current_day:
# New day: move today's fees to pending, reset
if cfg.rebate_pct > 0:
pending_rebate = today_fees * cfg.rebate_pct
today_fees = 0.0
rebate_applied_today = False
day_pnl = 0.0
day_stopped = False
current_day = bar_day
# Apply delayed rebate at specified hour
if cfg.rebate_pct > 0 and not rebate_applied_today and bar_hour >= cfg.rebate_hour_utc and pending_rebate > 0:
balance += pending_rebate
total_rebate += pending_rebate
pending_rebate = 0.0
rebate_applied_today = True
# Skip if BB not ready
if np.isnan(arr_upper[i]) or np.isnan(arr_lower[i]):
out_equity[i] = balance + unrealised(arr_close[i])
out_balance[i] = balance
out_position[i] = position
continue
# Daily loss check
if day_stopped:
out_equity[i] = balance + unrealised(arr_close[i])
out_balance[i] = balance
out_position[i] = position
continue
cur_equity = balance + unrealised(arr_close[i])
if day_pnl + unrealised(arr_close[i]) <= -cfg.max_daily_loss:
close_position(arr_close[i], i)
day_stopped = True
out_equity[i] = balance
out_balance[i] = balance
out_position[i] = 0
continue
# Stop loss check
if position != 0 and cfg.stop_loss_pct > 0:
if position == 1 and arr_low[i] <= entry_price * (1 - cfg.stop_loss_pct):
sl_price = entry_price * (1 - cfg.stop_loss_pct)
close_position(sl_price, i)
elif position == -1 and arr_high[i] >= entry_price * (1 + cfg.stop_loss_pct):
sl_price = entry_price * (1 + cfg.stop_loss_pct)
close_position(sl_price, i)
# Signal detection: use high/low to check if price touched BB
touched_upper = arr_high[i] >= arr_upper[i]
touched_lower = arr_low[i] <= arr_lower[i]
if touched_upper and touched_lower:
# Both touched in same bar (wide bar) — skip, too volatile
pass
elif touched_upper:
# Price touched upper BB → go short
if position == 1:
# Close long at upper BB price
close_position(arr_upper[i], i)
if position != -1:
# Open short
open_position("short", arr_upper[i], i)
elif touched_lower:
# Price touched lower BB → go long
if position == -1:
# Close short at lower BB price
close_position(arr_lower[i], i)
if position != 1:
# Open long
open_position("long", arr_lower[i], i)
# Record equity
out_equity[i] = balance + unrealised(arr_close[i])
out_balance[i] = balance
out_position[i] = position
# Force close at end
if position != 0:
close_position(arr_close[n - 1], n - 1)
out_equity[n - 1] = balance
out_balance[n - 1] = balance
out_position[n - 1] = 0
# Build equity DataFrame
eq_df = pd.DataFrame({
"equity": out_equity,
"balance": out_balance,
"price": arr_close,
"position": out_position,
}, index=ts_index)
# Daily stats
daily_eq = eq_df["equity"].resample("1D").last().dropna().to_frame("equity")
daily_eq["pnl"] = daily_eq["equity"].diff().fillna(0.0)
return BBResult(
equity_curve=eq_df,
trades=trades,
daily_stats=daily_eq,
total_fee=total_fee,
total_rebate=total_rebate,
config=cfg,
)

53
strategy/data_loader.py Normal file
View File

@@ -0,0 +1,53 @@
from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
from typing import Optional
import pandas as pd
import sqlite3
@dataclass(frozen=True)
class KlineSource:
db_path: Path
table_name: str
def _to_ms(dt: datetime) -> int:
if dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone.utc)
return int(dt.timestamp() * 1000)
def load_klines(
source: KlineSource,
start: datetime,
end: datetime,
) -> pd.DataFrame:
start_ms = _to_ms(start)
end_ms = _to_ms(end)
con = sqlite3.connect(str(source.db_path))
try:
df = pd.read_sql_query(
f"SELECT id, open, high, low, close FROM {source.table_name} WHERE id >= ? AND id <= ? ORDER BY id ASC",
con,
params=(start_ms, end_ms),
)
finally:
con.close()
if df.empty:
return df
df["timestamp_ms"] = df["id"].astype("int64")
df["dt"] = pd.to_datetime(df["timestamp_ms"], unit="ms", utc=True)
df = df.drop(columns=["id"]).set_index("dt")
for c in ("open", "high", "low", "close"):
df[c] = pd.to_numeric(df[c], errors="coerce")
df = df.dropna(subset=["open", "high", "low", "close"])
return df

104
strategy/indicators.py Normal file
View File

@@ -0,0 +1,104 @@
from __future__ import annotations
import numpy as np
import pandas as pd
def ema(s: pd.Series, span: int) -> pd.Series:
return s.ewm(span=span, adjust=False).mean()
def rsi(close: pd.Series, period: int) -> pd.Series:
delta = close.diff()
up = delta.clip(lower=0.0)
down = (-delta).clip(lower=0.0)
roll_up = up.ewm(alpha=1 / period, adjust=False).mean()
roll_down = down.ewm(alpha=1 / period, adjust=False).mean()
rs = roll_up / roll_down.replace(0.0, np.nan)
return 100.0 - (100.0 / (1.0 + rs))
def atr(high: pd.Series, low: pd.Series, close: pd.Series, period: int) -> pd.Series:
prev_close = close.shift(1)
tr = pd.concat(
[
(high - low).abs(),
(high - prev_close).abs(),
(low - prev_close).abs(),
],
axis=1,
).max(axis=1)
return tr.ewm(alpha=1 / period, adjust=False).mean()
def bollinger(close: pd.Series, window: int, n_std: float):
mid = close.rolling(window=window, min_periods=window).mean()
std = close.rolling(window=window, min_periods=window).std(ddof=0)
upper = mid + n_std * std
lower = mid - n_std * std
width = (upper - lower) / mid
return mid, upper, lower, width
def macd(close: pd.Series, fast: int, slow: int, signal: int):
fast_ema = ema(close, fast)
slow_ema = ema(close, slow)
line = fast_ema - slow_ema
sig = ema(line, signal)
hist = line - sig
return line, sig, hist
def stochastic(high: pd.Series, low: pd.Series, close: pd.Series,
k_period: int = 14, d_period: int = 3):
"""Stochastic Oscillator (%K and %D)."""
lowest = low.rolling(window=k_period, min_periods=k_period).min()
highest = high.rolling(window=k_period, min_periods=k_period).max()
denom = highest - lowest
k = 100.0 * (close - lowest) / denom.replace(0.0, np.nan)
d = k.rolling(window=d_period, min_periods=d_period).mean()
return k, d
def cci(high: pd.Series, low: pd.Series, close: pd.Series,
period: int = 20) -> pd.Series:
"""Commodity Channel Index."""
tp = (high + low + close) / 3.0
sma = tp.rolling(window=period, min_periods=period).mean()
mad = tp.rolling(window=period, min_periods=period).apply(
lambda x: np.mean(np.abs(x - np.mean(x))), raw=True
)
return (tp - sma) / (0.015 * mad.replace(0.0, np.nan))
def adx(high: pd.Series, low: pd.Series, close: pd.Series,
period: int = 14) -> pd.Series:
"""Average Directional Index (returns ADX line only)."""
up_move = high.diff()
down_move = -low.diff()
plus_dm = pd.Series(np.where((up_move > down_move) & (up_move > 0), up_move, 0.0),
index=high.index)
minus_dm = pd.Series(np.where((down_move > up_move) & (down_move > 0), down_move, 0.0),
index=high.index)
atr_val = atr(high, low, close, period)
plus_di = 100.0 * plus_dm.ewm(alpha=1 / period, adjust=False).mean() / atr_val.replace(0.0, np.nan)
minus_di = 100.0 * minus_dm.ewm(alpha=1 / period, adjust=False).mean() / atr_val.replace(0.0, np.nan)
dx = 100.0 * (plus_di - minus_di).abs() / (plus_di + minus_di).replace(0.0, np.nan)
adx_line = dx.ewm(alpha=1 / period, adjust=False).mean()
return adx_line
def keltner_channel(high: pd.Series, low: pd.Series, close: pd.Series,
ema_period: int = 20, atr_period: int = 14, atr_mult: float = 1.5):
"""Keltner Channel (mid, upper, lower)."""
mid = ema(close, ema_period)
atr_val = atr(high, low, close, atr_period)
upper = mid + atr_mult * atr_val
lower = mid - atr_mult * atr_val
return mid, upper, lower

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

199
strategy/run_bb_backtest.py Normal file
View File

@@ -0,0 +1,199 @@
"""Run Bollinger Band mean-reversion backtest on ETH 2023+2024.
Preloads data once, then sweeps parameters in-memory for speed.
"""
import sys, time
sys.stdout.reconfigure(line_buffering=True)
sys.path.insert(0, str(__import__("pathlib").Path(__file__).resolve().parents[1]))
import numpy as np
import pandas as pd
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from pathlib import Path
from collections import defaultdict
from strategy.bb_backtest import BBConfig, run_bb_backtest
from strategy.data_loader import KlineSource, load_klines
from datetime import datetime, timezone
root = Path(__file__).resolve().parents[1]
src = KlineSource(db_path=root / "models" / "database.db", table_name="bitmart_eth_5m")
out_dir = root / "strategy" / "results"
out_dir.mkdir(parents=True, exist_ok=True)
t0 = time.time()
# Preload data once
print("Loading data...")
df_23 = load_klines(src, datetime(2023,1,1,tzinfo=timezone.utc),
datetime(2023,12,31,23,59,tzinfo=timezone.utc))
df_24 = load_klines(src, datetime(2024,1,1,tzinfo=timezone.utc),
datetime(2024,12,31,23,59,tzinfo=timezone.utc))
data = {2023: df_23, 2024: df_24}
print(f"Loaded: 2023={len(df_23)} bars, 2024={len(df_24)} bars ({time.time()-t0:.1f}s)")
# ================================================================
# Sweep
# ================================================================
print("\n" + "=" * 120)
print(" Bollinger Band Mean-Reversion — ETH 5min | 1000U capital")
print(" touch upper BB -> short, touch lower BB -> long (flip)")
print("=" * 120)
results = []
def test(label, cfg):
"""Run on both years, print summary, store results."""
row = {"label": label, "cfg": cfg}
for year in [2023, 2024]:
r = run_bb_backtest(data[year], cfg)
d = r.daily_stats
pnl = d["pnl"].astype(float)
eq = d["equity"].astype(float)
dd = float((eq - eq.cummax()).min())
final = float(eq.iloc[-1])
nt = len(r.trades)
wr = sum(1 for t in r.trades if t.net_pnl > 0) / max(nt, 1) * 100
nf = r.total_fee - r.total_rebate
row[f"a{year}"] = float(pnl.mean())
row[f"d{year}"] = dd
row[f"r{year}"] = r
row[f"n{year}"] = nt
row[f"w{year}"] = wr
row[f"f{year}"] = nf
row[f"eq{year}"] = final
mn = min(row["a2023"], row["a2024"])
avg = (row["a2023"] + row["a2024"]) / 2
mark = " <<<" if mn >= 20 else (" **" if mn >= 10 else "")
print(f" {label:52s} 23:{row['a2023']:+6.1f} 24:{row['a2024']:+6.1f} "
f"avg:{avg:+5.1f} n23:{row['n2023']:3d} n24:{row['n2024']:3d} "
f"dd:{min(row['d2023'],row['d2024']):+7.0f}{mark}")
row["mn"] = mn; row["avg"] = avg
results.append(row)
# [1] BB period
print("\n[1] Period sweep")
for p in [10, 15, 20, 30, 40]:
test(f"BB({p},2.0) 80u 100x", BBConfig(bb_period=p, bb_std=2.0, margin_per_trade=80, leverage=100))
# [2] BB std
print("\n[2] Std sweep")
for s in [1.5, 1.8, 2.0, 2.5, 3.0]:
test(f"BB(20,{s}) 80u 100x", BBConfig(bb_period=20, bb_std=s, margin_per_trade=80, leverage=100))
# [3] Margin
print("\n[3] Margin sweep")
for m in [40, 60, 80, 100, 120]:
test(f"BB(20,2.0) {m}u 100x", BBConfig(bb_period=20, bb_std=2.0, margin_per_trade=m, leverage=100))
# [4] SL
print("\n[4] Stop-loss sweep")
for sl in [0.0, 0.01, 0.02, 0.03, 0.05]:
test(f"BB(20,2.0) 80u SL={sl:.0%}", BBConfig(bb_period=20, bb_std=2.0, margin_per_trade=80, leverage=100, stop_loss_pct=sl))
# [5] MDL
print("\n[5] Max daily loss")
for mdl in [50, 100, 150, 200]:
test(f"BB(20,2.0) 80u mdl={mdl}", BBConfig(bb_period=20, bb_std=2.0, margin_per_trade=80, leverage=100, max_daily_loss=mdl))
# [6] Combined fine-tune
print("\n[6] Fine-tune")
for p in [15, 20, 30]:
for s in [1.5, 2.0, 2.5]:
for m in [80, 100]:
test(f"BB({p},{s}) {m}u mdl=150",
BBConfig(bb_period=p, bb_std=s, margin_per_trade=m, leverage=100, max_daily_loss=150))
# ================================================================
# Ranking
# ================================================================
results.sort(key=lambda x: x["mn"], reverse=True)
print(f"\n{'='*120}")
print(f" TOP 10 — ranked by min(daily_avg_2023, daily_avg_2024)")
print(f"{'='*120}")
for i, r in enumerate(results[:10]):
print(f" {i+1:2d}. {r['label']:50s} 23:{r['a2023']:+6.1f} 24:{r['a2024']:+6.1f} "
f"min:{r['mn']:+6.1f} dd:{min(r['d2023'],r['d2024']):+7.0f} "
f"wr23:{r['w2023']:.0f}% wr24:{r['w2024']:.0f}%")
# ================================================================
# Detailed report for best
# ================================================================
best = results[0]
print(f"\n{'#'*70}")
print(f" BEST: {best['label']}")
print(f"{'#'*70}")
for year in [2023, 2024]:
r = best[f"r{year}"]
cfg = best["cfg"]
d = r.daily_stats
pnl = d["pnl"].astype(float)
eq = d["equity"].astype(float)
dd = (eq - eq.cummax()).min()
final = float(eq.iloc[-1])
nt = len(r.trades)
wr = sum(1 for t in r.trades if t.net_pnl > 0) / max(nt, 1)
nf = r.total_fee - r.total_rebate
loss_streak = max_ls = 0
for v in pnl.values:
if v < 0: loss_streak += 1; max_ls = max(max_ls, loss_streak)
else: loss_streak = 0
print(f"\n --- {year} ---")
print(f" Final equity : {final:,.2f} U ({final-cfg.initial_capital:+,.2f}, "
f"{(final-cfg.initial_capital)/cfg.initial_capital*100:+.1f}%)")
print(f" Max drawdown : {dd:,.2f} U")
print(f" Avg daily PnL : {pnl.mean():+,.2f} U")
print(f" Median daily PnL : {pnl.median():+,.2f} U")
print(f" Best/worst day : {pnl.max():+,.2f} / {pnl.min():+,.2f}")
print(f" Profitable days : {(pnl>0).sum()}/{len(pnl)} ({(pnl>0).mean():.1%})")
print(f" Days >= 20U : {(pnl>=20).sum()}")
print(f" Max loss streak : {max_ls} days")
print(f" Trades : {nt} (win rate {wr:.1%})")
print(f" Net fees : {nf:,.0f} U")
sharpe = pnl.mean() / max(pnl.std(), 1e-10) * np.sqrt(365)
print(f" Sharpe (annual) : {sharpe:.2f}")
# ================================================================
# Chart
# ================================================================
fig, axes = plt.subplots(3, 2, figsize=(18, 12),
gridspec_kw={"height_ratios": [3, 1.5, 1]})
for col, year in enumerate([2023, 2024]):
r = best[f"r{year}"]
cfg = best["cfg"]
d = r.daily_stats
eq = d["equity"].astype(float)
pnl = d["pnl"].astype(float)
dd = eq - eq.cummax()
axes[0, col].plot(eq.index, eq.values, linewidth=1.2, color="#1f77b4")
axes[0, col].axhline(cfg.initial_capital, color="gray", ls="--", lw=0.5)
axes[0, col].set_title(f"BB Strategy Equity — {year}\n"
f"BB({cfg.bb_period},{cfg.bb_std}) {cfg.margin_per_trade}u {cfg.leverage:.0f}x",
fontsize=11)
axes[0, col].set_ylabel("Equity (U)")
axes[0, col].grid(True, alpha=0.3)
colors = ["#2ca02c" if v >= 0 else "#d62728" for v in pnl.values]
axes[1, col].bar(pnl.index, pnl.values, color=colors, width=0.8)
axes[1, col].axhline(20, color="orange", ls="--", lw=1, label="20U target")
axes[1, col].axhline(0, color="gray", lw=0.5)
axes[1, col].set_ylabel("Daily PnL (U)")
axes[1, col].legend(fontsize=8)
axes[1, col].grid(True, alpha=0.3)
axes[2, col].fill_between(dd.index, dd.values, 0, color="#d62728", alpha=0.4)
axes[2, col].set_ylabel("Drawdown (U)")
axes[2, col].grid(True, alpha=0.3)
fig.tight_layout()
fig.savefig(out_dir / "bb_strategy_report.png", dpi=150)
plt.close(fig)
print(f"\nChart: {out_dir / 'bb_strategy_report.png'}")
print(f"Total time: {time.time()-t0:.0f}s")