optimize statistics
This commit is contained in:
parent
ccc5637f9e
commit
b322aaa421
Binary file not shown.
|
|
@ -45,7 +45,7 @@ class MeanReversionSandbox:
|
||||||
desc_dict = {
|
desc_dict = {
|
||||||
"买入": [
|
"买入": [
|
||||||
"1. 窗口周期为100, 即100个K线",
|
"1. 窗口周期为100, 即100个K线",
|
||||||
"2. 当前close_10_low为1, 即当前收盘价在窗口周期的10分位以下",
|
"2. 满足close_10_low为1, 即当前收盘价在窗口周期的10分位以下",
|
||||||
"3. 之前2个K线与当前K线, 存在任意一个K线huge_volume为1, 即存在一个K线是巨量",
|
"3. 之前2个K线与当前K线, 存在任意一个K线huge_volume为1, 即存在一个K线是巨量",
|
||||||
"4. 当前K线为阳线, 即close > open或者K线为一字, 长倒T线, 倒T线, 长十字星, 十字星",
|
"4. 当前K线为阳线, 即close > open或者K线为一字, 长倒T线, 倒T线, 长十字星, 十字星",
|
||||||
# "5. 相同symbol的1H当前周期, ma5大于ma10",
|
# "5. 相同symbol的1H当前周期, ma5大于ma10",
|
||||||
|
|
@ -143,7 +143,7 @@ class MeanReversionSandbox:
|
||||||
for index, row in market_data.iterrows():
|
for index, row in market_data.iterrows():
|
||||||
# check buy condition
|
# check buy condition
|
||||||
if trade_pair_dict.get("buy_timestamp", None) is None:
|
if trade_pair_dict.get("buy_timestamp", None) is None:
|
||||||
buy_condition = self.check_buy_condition(market_data, row, index)
|
buy_condition = self.check_buy_condition(market_data, row, index, window_size)
|
||||||
else:
|
else:
|
||||||
buy_condition = False
|
buy_condition = False
|
||||||
if buy_condition:
|
if buy_condition:
|
||||||
|
|
@ -170,17 +170,20 @@ class MeanReversionSandbox:
|
||||||
sell_condition = False
|
sell_condition = False
|
||||||
# check stop loss condition
|
# check stop loss condition
|
||||||
sell_condition = self.check_stop_loss_condition(trade_pair_dict, row)
|
sell_condition = self.check_stop_loss_condition(trade_pair_dict, row)
|
||||||
if sell_condition:
|
sell = sell_condition["sell"]
|
||||||
|
if sell:
|
||||||
trade_pair_dict["sell_type"] = "止损"
|
trade_pair_dict["sell_type"] = "止损"
|
||||||
else:
|
else:
|
||||||
# check take profit condition
|
# check take profit condition
|
||||||
sell_condition = self.check_take_profit_condition(
|
sell_condition = self.check_take_profit_condition(
|
||||||
trade_pair_dict, market_data, row, index
|
trade_pair_dict, market_data, row, index
|
||||||
)
|
)
|
||||||
if sell_condition:
|
sell = sell_condition["sell"]
|
||||||
|
if sell:
|
||||||
trade_pair_dict["sell_type"] = "止盈"
|
trade_pair_dict["sell_type"] = "止盈"
|
||||||
|
|
||||||
if sell_condition:
|
if sell:
|
||||||
|
trade_pair_dict["sell_reason"] = sell_condition["reason"]
|
||||||
trade_pair_dict["sell_timestamp"] = row["timestamp"]
|
trade_pair_dict["sell_timestamp"] = row["timestamp"]
|
||||||
trade_pair_dict["sell_date_time"] = timestamp_to_datetime(
|
trade_pair_dict["sell_date_time"] = timestamp_to_datetime(
|
||||||
row["timestamp"]
|
row["timestamp"]
|
||||||
|
|
@ -218,17 +221,50 @@ class MeanReversionSandbox:
|
||||||
if len(trade_list) == 0:
|
if len(trade_list) == 0:
|
||||||
return None
|
return None
|
||||||
trade_data = pd.DataFrame(trade_list)
|
trade_data = pd.DataFrame(trade_list)
|
||||||
|
trade_data = trade_data[
|
||||||
|
[
|
||||||
|
"solution",
|
||||||
|
"symbol",
|
||||||
|
"bar",
|
||||||
|
"window_size",
|
||||||
|
"sell_type",
|
||||||
|
"sell_reason",
|
||||||
|
"profit_pct",
|
||||||
|
"buy_timestamp",
|
||||||
|
"buy_date_time",
|
||||||
|
"sell_timestamp",
|
||||||
|
"sell_date_time",
|
||||||
|
"buy_close",
|
||||||
|
"buy_pct_chg",
|
||||||
|
"sell_close",
|
||||||
|
"sell_pct_chg",
|
||||||
|
"buy_volume",
|
||||||
|
"buy_huge_volume",
|
||||||
|
"buy_volume_ratio",
|
||||||
|
"buy_k_shape",
|
||||||
|
"buy_close_10_low",
|
||||||
|
"buy_ma5_lt_ma10",
|
||||||
|
"sell_volume",
|
||||||
|
"sell_huge_volume",
|
||||||
|
"sell_volume_ratio",
|
||||||
|
"sell_k_shape",
|
||||||
|
"sell_close_80_high",
|
||||||
|
"sell_close_90_high",
|
||||||
|
"sell_close_10_low",
|
||||||
|
"sell_close_20_low",
|
||||||
|
]
|
||||||
|
]
|
||||||
trade_data.sort_values(by="buy_timestamp", inplace=True)
|
trade_data.sort_values(by="buy_timestamp", inplace=True)
|
||||||
trade_data.reset_index(drop=True, inplace=True)
|
trade_data.reset_index(drop=True, inplace=True)
|
||||||
return trade_data
|
return trade_data
|
||||||
|
|
||||||
def check_buy_condition(
|
def check_buy_condition(
|
||||||
self, market_data: pd.DataFrame, row: pd.Series, index: int
|
self, market_data: pd.DataFrame, row: pd.Series, index: int, window_size: int
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
买入条件
|
买入条件
|
||||||
1. 窗口周期为100, 即100个K线,
|
1. 窗口周期为100, 即100个K线,
|
||||||
2. 当前close_10_low为1, 即当前收盘价在窗口周期的10分位以下,
|
2. 满足close_10_low为1, 即当前收盘价在窗口周期的10分位以下
|
||||||
3. 之前2个K线与当前K线, 存在任意一个K线huge_volume为1, 即存在一个K线是巨量,
|
3. 之前2个K线与当前K线, 存在任意一个K线huge_volume为1, 即存在一个K线是巨量,
|
||||||
4. (当前K线为阳线, 即close > open)或者K线为一字, 长倒T线, 倒T线, 长十字星, 十字星,
|
4. (当前K线为阳线, 即close > open)或者K线为一字, 长倒T线, 倒T线, 长十字星, 十字星,
|
||||||
"""
|
"""
|
||||||
|
|
@ -243,6 +279,8 @@ class MeanReversionSandbox:
|
||||||
]:
|
]:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# 满足close_10_low为1, 即当前收盘价在窗口周期的10分位以下
|
||||||
if row["close_10_low"] != 1:
|
if row["close_10_low"] != 1:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
@ -310,13 +348,18 @@ class MeanReversionSandbox:
|
||||||
)
|
)
|
||||||
buy_close = trade_pair_dict["buy_close"]
|
buy_close = trade_pair_dict["buy_close"]
|
||||||
current_close = row["close"]
|
current_close = row["close"]
|
||||||
|
result = {"sell": False, "reason": ""}
|
||||||
if (
|
if (
|
||||||
current_close < buy_close
|
current_close < buy_close
|
||||||
and (current_close - buy_close) / buy_close < down_median
|
and (current_close - buy_close) / buy_close < down_median
|
||||||
):
|
):
|
||||||
logger.info(f"符合止损条件")
|
logger.info(f"符合止损条件")
|
||||||
return True
|
result["sell"] = True
|
||||||
return False
|
result["reason"] = f"亏损超过下跌波段跌幅中位数"
|
||||||
|
return result
|
||||||
|
result["sell"] = False
|
||||||
|
result["reason"] = "未达到止损条件"
|
||||||
|
return result
|
||||||
|
|
||||||
def check_take_profit_condition(
|
def check_take_profit_condition(
|
||||||
self,
|
self,
|
||||||
|
|
@ -353,16 +396,23 @@ class MeanReversionSandbox:
|
||||||
1. 当前close_80_high为1或者close_90_high为1
|
1. 当前close_80_high为1或者close_90_high为1
|
||||||
2. 之前2个K线与当前K线, 存在任意一个K线huge_volume为1, 即存在一个K线是巨量
|
2. 之前2个K线与当前K线, 存在任意一个K线huge_volume为1, 即存在一个K线是巨量
|
||||||
"""
|
"""
|
||||||
|
result = {"sell": False, "reason": ""}
|
||||||
if row["close_80_high"] != 1 and row["close_90_high"] != 1:
|
if row["close_80_high"] != 1 and row["close_90_high"] != 1:
|
||||||
return False
|
result["sell"] = False
|
||||||
|
result["reason"] = "未达到止盈条件"
|
||||||
|
return result
|
||||||
if (
|
if (
|
||||||
row["huge_volume"] != 1
|
row["huge_volume"] != 1
|
||||||
and market_data.loc[index - 1, "huge_volume"] != 1
|
and market_data.loc[index - 1, "huge_volume"] != 1
|
||||||
and market_data.loc[index - 2, "huge_volume"] != 1
|
and market_data.loc[index - 2, "huge_volume"] != 1
|
||||||
):
|
):
|
||||||
return False
|
result["sell"] = False
|
||||||
|
result["reason"] = "未达到止盈条件"
|
||||||
|
return result
|
||||||
logger.info(f"符合高位放量止盈 - 简易版条件")
|
logger.info(f"符合高位放量止盈 - 简易版条件")
|
||||||
return True
|
result["sell"] = True
|
||||||
|
result["reason"] = "符合高位放量止盈 - 简易版条件"
|
||||||
|
return result
|
||||||
|
|
||||||
def check_take_profit_condition_solution_2(
|
def check_take_profit_condition_solution_2(
|
||||||
self,
|
self,
|
||||||
|
|
@ -380,11 +430,16 @@ class MeanReversionSandbox:
|
||||||
2. K线为阳线, 即close >= open, 且k_shape满足:
|
2. K线为阳线, 即close >= open, 且k_shape满足:
|
||||||
一字, 长吊锤线, 吊锤线, 长倒T线, 倒T线, 长十字星, 十字星, 长上影线纺锤体, 长下影线纺锤体
|
一字, 长吊锤线, 吊锤线, 长倒T线, 倒T线, 长十字星, 十字星, 长上影线纺锤体, 长下影线纺锤体
|
||||||
"""
|
"""
|
||||||
|
result = {"sell": False, "reason": ""}
|
||||||
if not self.check_take_profit_condition_solution_1(market_data, row, index):
|
if not self.check_take_profit_condition_solution_1(market_data, row, index):
|
||||||
return False
|
result["sell"] = False
|
||||||
|
result["reason"] = "未达到止盈条件"
|
||||||
|
return result
|
||||||
if row["close"] < row["open"]:
|
if row["close"] < row["open"]:
|
||||||
logger.info(f"符合高位放量止盈 - 复杂版条件")
|
logger.info(f"符合高位放量止盈 - 复杂版条件")
|
||||||
return True
|
result["sell"] = True
|
||||||
|
result["reason"] = "符合高位放量止盈 - 复杂版条件"
|
||||||
|
return result
|
||||||
elif row["k_shape"] in [
|
elif row["k_shape"] in [
|
||||||
"一字",
|
"一字",
|
||||||
"长吊锤线",
|
"长吊锤线",
|
||||||
|
|
@ -397,9 +452,13 @@ class MeanReversionSandbox:
|
||||||
"长下影线纺锤体",
|
"长下影线纺锤体",
|
||||||
]:
|
]:
|
||||||
logger.info(f"符合高位放量止盈 - 复杂版条件")
|
logger.info(f"符合高位放量止盈 - 复杂版条件")
|
||||||
return True
|
result["sell"] = True
|
||||||
|
result["reason"] = "符合高位放量止盈 - 复杂版条件"
|
||||||
|
return result
|
||||||
else:
|
else:
|
||||||
return False
|
result["sell"] = False
|
||||||
|
result["reason"] = "未达到止盈条件"
|
||||||
|
return result
|
||||||
|
|
||||||
def check_take_profit_condition_solution_3(
|
def check_take_profit_condition_solution_3(
|
||||||
self, trade_pair_dict: dict, row: pd.Series
|
self, trade_pair_dict: dict, row: pd.Series
|
||||||
|
|
@ -413,12 +472,14 @@ class MeanReversionSandbox:
|
||||||
"""
|
"""
|
||||||
current_close = row["close"]
|
current_close = row["close"]
|
||||||
last_max_close = trade_pair_dict.get("last_max_close", None)
|
last_max_close = trade_pair_dict.get("last_max_close", None)
|
||||||
|
result = {"sell": False, "reason": ""}
|
||||||
if trade_pair_dict["buy_ma5_lt_ma10"]:
|
if trade_pair_dict["buy_ma5_lt_ma10"]:
|
||||||
if trade_pair_dict.get("process_ma5_gt_ma10", None):
|
if trade_pair_dict.get("process_ma5_gt_ma10", None):
|
||||||
if row["ma5"] < row["ma10"]:
|
if row["ma5"] < row["ma10"]:
|
||||||
logger.info(f"MA5小于MA10发生转势, 卖出")
|
logger.info(f"MA5小于MA10发生转势, 卖出")
|
||||||
return True
|
result["sell"] = True
|
||||||
|
result["reason"] = "MA5小于MA10发生转势"
|
||||||
|
return result
|
||||||
|
|
||||||
if row["ma5"] > row["ma10"]:
|
if row["ma5"] > row["ma10"]:
|
||||||
trade_pair_dict["process_ma5_gt_ma10"] = True
|
trade_pair_dict["process_ma5_gt_ma10"] = True
|
||||||
|
|
@ -429,10 +490,14 @@ class MeanReversionSandbox:
|
||||||
if current_close >= last_max_close:
|
if current_close >= last_max_close:
|
||||||
logger.info(f"价格上涨, 继续持仓")
|
logger.info(f"价格上涨, 继续持仓")
|
||||||
trade_pair_dict["last_max_close"] = current_close
|
trade_pair_dict["last_max_close"] = current_close
|
||||||
return False
|
result["sell"] = False
|
||||||
|
result["reason"] = "价格上涨, 继续持仓"
|
||||||
|
return result
|
||||||
else:
|
else:
|
||||||
logger.info(f"符合上涨波段盈利中位数止盈法条件")
|
logger.info(f"符合上涨波段盈利中位数止盈法条件")
|
||||||
return True
|
result["sell"] = True
|
||||||
|
result["reason"] = "符合上涨波段盈利中位数止盈条件"
|
||||||
|
return result
|
||||||
else:
|
else:
|
||||||
symbol = trade_pair_dict["symbol"]
|
symbol = trade_pair_dict["symbol"]
|
||||||
bar = trade_pair_dict["bar"]
|
bar = trade_pair_dict["bar"]
|
||||||
|
|
@ -461,7 +526,9 @@ class MeanReversionSandbox:
|
||||||
need_record = False
|
need_record = False
|
||||||
if need_record:
|
if need_record:
|
||||||
trade_pair_dict["last_max_close"] = current_close
|
trade_pair_dict["last_max_close"] = current_close
|
||||||
return False
|
result["sell"] = False
|
||||||
|
result["reason"] = "未达到止盈条件"
|
||||||
|
return result
|
||||||
|
|
||||||
def check_metrics_over_buy(self, row: pd.Series):
|
def check_metrics_over_buy(self, row: pd.Series):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ class MeanReversionSandboxMain:
|
||||||
profit_pct_max = bar["profit_pct"].max()
|
profit_pct_max = bar["profit_pct"].max()
|
||||||
profit_pct_min = bar["profit_pct"].min()
|
profit_pct_min = bar["profit_pct"].min()
|
||||||
profit_pct_mean = bar["profit_pct"].mean()
|
profit_pct_mean = bar["profit_pct"].mean()
|
||||||
|
profit_pct_sum = bar["profit_pct"].sum()
|
||||||
profit_pct_gt_0_mean = bar[bar["profit_pct"] > 0]["profit_pct"].mean()
|
profit_pct_gt_0_mean = bar[bar["profit_pct"] > 0]["profit_pct"].mean()
|
||||||
profit_pct_lt_0_mean = bar[bar["profit_pct"] < 0]["profit_pct"].mean()
|
profit_pct_lt_0_mean = bar[bar["profit_pct"] < 0]["profit_pct"].mean()
|
||||||
|
|
||||||
|
|
@ -125,6 +126,7 @@ class MeanReversionSandboxMain:
|
||||||
"solution": solution,
|
"solution": solution,
|
||||||
"symbol": symbol_name,
|
"symbol": symbol_name,
|
||||||
"bar": bar_name,
|
"bar": bar_name,
|
||||||
|
"profit_pct_sum": profit_pct_sum,
|
||||||
"take_profit_count": take_profit_count,
|
"take_profit_count": take_profit_count,
|
||||||
"take_profit_ratio": take_profit_ratio,
|
"take_profit_ratio": take_profit_ratio,
|
||||||
"stop_loss_count": stop_loss_count,
|
"stop_loss_count": stop_loss_count,
|
||||||
|
|
@ -133,9 +135,9 @@ class MeanReversionSandboxMain:
|
||||||
"profit_pct_gt_0_ratio": profit_pct_gt_0_ratio,
|
"profit_pct_gt_0_ratio": profit_pct_gt_0_ratio,
|
||||||
"profit_pct_lt_0_count": profit_pct_lt_0_count,
|
"profit_pct_lt_0_count": profit_pct_lt_0_count,
|
||||||
"profit_pct_lt_0_ratio": profit_pct_lt_0_ratio,
|
"profit_pct_lt_0_ratio": profit_pct_lt_0_ratio,
|
||||||
|
"profit_pct_mean": profit_pct_mean,
|
||||||
"profit_pct_max": profit_pct_max,
|
"profit_pct_max": profit_pct_max,
|
||||||
"profit_pct_min": profit_pct_min,
|
"profit_pct_min": profit_pct_min,
|
||||||
"profit_pct_mean": profit_pct_mean,
|
|
||||||
"profit_pct_gt_0_mean": profit_pct_gt_0_mean,
|
"profit_pct_gt_0_mean": profit_pct_gt_0_mean,
|
||||||
"profit_pct_lt_0_mean": profit_pct_lt_0_mean,
|
"profit_pct_lt_0_mean": profit_pct_lt_0_mean,
|
||||||
}
|
}
|
||||||
|
|
@ -176,6 +178,7 @@ class MeanReversionSandboxMain:
|
||||||
y_axis_fields = [
|
y_axis_fields = [
|
||||||
"take_profit_ratio",
|
"take_profit_ratio",
|
||||||
"stop_loss_ratio",
|
"stop_loss_ratio",
|
||||||
|
"profit_pct_sum",
|
||||||
"profit_pct_mean",
|
"profit_pct_mean",
|
||||||
"profit_pct_gt_0_mean",
|
"profit_pct_gt_0_mean",
|
||||||
"profit_pct_lt_0_mean",
|
"profit_pct_lt_0_mean",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue