Start to integration strategy
This commit is contained in:
+7
-2
@@ -32,6 +32,7 @@ class ChanLun():
|
||||
time30 = 30
|
||||
time60 = 60
|
||||
time4h = 240
|
||||
last_peak = {'high': 0, 'low': float('inf')}
|
||||
def create_all_data(self, dataframe, ticker_indicator):
|
||||
all_data = dict()
|
||||
all_data['1m'] = dataframe
|
||||
@@ -156,8 +157,8 @@ class ChanLun():
|
||||
else:
|
||||
fx_list.append(0)
|
||||
klc_strength_list.append(klc.cal_fx_strength(2))
|
||||
if klc.klc_fx_type != Chan_KLC_FX.UNKNOWN and klc.cal_fx_strength() > 1:
|
||||
print(klc.start_time, klc.end_time, klc.cal_fx_strength(), klc.klc_fx_type, fx_list[-1], klc_strength_list[-1])
|
||||
#if klc.klc_fx_type != Chan_KLC_FX.UNKNOWN and klc.cal_fx_strength() > 1:
|
||||
#print(klc.start_time, klc.end_time, klc.cal_fx_strength(), klc.klc_fx_type, fx_list[-1], klc_strength_list[-1])
|
||||
else:
|
||||
klc_strength_list.append(0)
|
||||
fx_list.append(0)
|
||||
@@ -305,6 +306,10 @@ class ChanLun():
|
||||
c,
|
||||
v
|
||||
]
|
||||
if h > self.last_peak['high']:
|
||||
self.last_peak['high'] = h
|
||||
if l < self.last_peak['low']:
|
||||
self.last_peak['low'] = l
|
||||
#klu = KLU(self.create_item_dict(item_data, GetColumnNameFromFieldList(fields)))
|
||||
klu = ChanKLU(time_str, o, h, l, c, v)
|
||||
klu.set_idx(i)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import sys
|
||||
import os
|
||||
#sys.path.append(os.path.abspath("/Users/jack/Documents/GitHub/chan.py"))
|
||||
sys.path.append(os.path.abspath("/Users/jack/Project/chan.py"))
|
||||
sys.path.append(os.path.abspath("/Users/jack/Documents/GitHub/chan.py"))
|
||||
#sys.path.append(os.path.abspath("/Users/jack/Project/chan.py"))
|
||||
from Chan import CChan
|
||||
from BuySellPoint.BS_Point import CBS_Point
|
||||
from ChanConfig import CChanConfig
|
||||
@@ -193,7 +193,7 @@ class ChanPY():
|
||||
if bsp_list_pre_len > len(bsp_list):
|
||||
if abs(last_bsp_value) == 1 or abs(last_bsp_value) == 2:
|
||||
bsps.append(1)
|
||||
print(klu.time, klu.idx, last_bsp.klu.time, last_bsp.klu.idx, last_bsp_value, 98)
|
||||
#print(klu.time, klu.idx, last_bsp.klu.time, last_bsp.klu.idx, last_bsp_value, 98)
|
||||
else:
|
||||
bsps.append(99)
|
||||
else:
|
||||
@@ -201,13 +201,13 @@ class ChanPY():
|
||||
if klu.idx == last_bsp.klu.idx:
|
||||
last_bsp_value = self.get_bsp_type(last_bsp.type[0], last_bsp.is_buy)
|
||||
bsps.append(last_bsp_value)
|
||||
print(klu.time, klu.idx, last_bsp.klu.time, last_bsp.klu.idx, last_bsp_value)
|
||||
#print(klu.time, klu.idx, last_bsp.klu.time, last_bsp.klu.idx, last_bsp_value)
|
||||
else:
|
||||
bsps.append(0)
|
||||
else:
|
||||
last_bsp_value = self.get_bsp_type(last_bsp.type[0], last_bsp.is_buy)
|
||||
bsps.append(last_bsp_value)
|
||||
print(klu.time, klu.idx, last_bsp.klu.time, last_bsp.klu.idx, last_bsp_value)
|
||||
#print(klu.time, klu.idx, last_bsp.klu.time, last_bsp.klu.idx, last_bsp_value)
|
||||
else:
|
||||
bsps.append(0)
|
||||
bsp_list_pre_len = len(bsp_list)
|
||||
@@ -288,7 +288,68 @@ class ChanPY():
|
||||
#print(zs.begin.time, zs.end.time)
|
||||
return bsps, updown, bi_sure
|
||||
def get_bsp_state(self, dataframe:DataFrame):
|
||||
bsps, updown, bi_sure = self.get_bsps(dataframe)
|
||||
#print(bsps)
|
||||
fields = "time,open,high,low,close,volume"
|
||||
bsps = []
|
||||
if self.chanIn:
|
||||
kl_data = self.get_kl_data(dataframe)
|
||||
bsp_list = []
|
||||
bsp_list_pre_len = 0
|
||||
last_bsp_value = 0
|
||||
for klu in kl_data: # 获取单根K线
|
||||
self.chan.trigger_load({self.k_type: [klu]}) # 喂给CChan新增k线
|
||||
self.last_kline = klu
|
||||
bsp_list = self.chan.get_bsp()
|
||||
kl_datas = self.chan.kl_datas[self.k_type]
|
||||
bi_list = kl_datas.bi_list
|
||||
lst = kl_datas.lst
|
||||
if len(bsp_list) > 0:
|
||||
last_bsp = bsp_list[-1]
|
||||
#print(klu.time, klu.idx, last_bsp.klu.time, last_bsp.klu.idx, last_bsp_value, lst[-2].fx, bi_list[-1].dir, bi_list[-1].is_sure,klu.close)
|
||||
if bsp_list_pre_len > len(bsp_list):
|
||||
if abs(last_bsp_value) == 1 or abs(last_bsp_value) == 2:
|
||||
bsps.append(1)
|
||||
#print(klu.time, klu.idx, last_bsp.klu.time, last_bsp.klu.idx, last_bsp_value, 98)
|
||||
else:
|
||||
bsps.append(99)
|
||||
else:
|
||||
if bsp_list_pre_len == len(bsp_list):
|
||||
if klu.idx == last_bsp.klu.idx:
|
||||
last_bsp_value = self.get_bsp_type(last_bsp.type[0], last_bsp.is_buy)
|
||||
bsps.append(last_bsp_value)
|
||||
#if abs(last_bsp_value) == 1 or abs(last_bsp_value) == 2:
|
||||
#print(klu.time, klu.idx, last_bsp.klu.time, last_bsp.klu.idx, last_bsp_value, "Knonw")
|
||||
else:
|
||||
bsps.append(0)
|
||||
else:
|
||||
last_bsp_value = self.get_bsp_type(last_bsp.type[0], last_bsp.is_buy)
|
||||
bsps.append(last_bsp_value)
|
||||
#if abs(last_bsp_value) == 1 or abs(last_bsp_value) == 2:
|
||||
#print(klu.time, klu.idx, last_bsp.klu.time, last_bsp.klu.idx, last_bsp_value, "Unknow")
|
||||
else:
|
||||
bsps.append(0)
|
||||
bsp_list_pre_len = len(bsp_list)
|
||||
self.chanIn = False
|
||||
else:
|
||||
klu = CKLine_Unit(self.create_item_dict(self.get_last_item_data(dataframe), GetColumnNameFromFieldList(fields)), autofix=True)
|
||||
if self.last_kline.time < klu.time:
|
||||
self.chan.trigger_load({self.k_type: [klu]}) # 喂给CChan新增k线
|
||||
self.last_kline = klu
|
||||
bsp_list = self.chan.get_bsp()
|
||||
last_bsp = bsp_list[-1]
|
||||
if last_bsp.klu.idx == klu.idx:
|
||||
bsps.append(self.get_bsp_type(last_bsp.type[0], last_bsp.is_buy))
|
||||
else:
|
||||
bsps.append(0)
|
||||
for index in range(0, len(bsps)):
|
||||
if not (abs(bsps[index]) == 1 or abs(bsps[index]) == 2):
|
||||
bsps[index] = 0
|
||||
else:
|
||||
if bsps[index] == 2:
|
||||
bsps[index] = 1
|
||||
else:
|
||||
if bsps[index] == -2:
|
||||
bsps[index] = -1
|
||||
else:
|
||||
bsps[index] = 0
|
||||
return bsps
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ from technical.util import resample_to_interval, resampled_merge
|
||||
import talib.abstract as ta
|
||||
from pandas import DataFrame
|
||||
from datetime import datetime, timedelta
|
||||
from freqtrade.persistence import Trade
|
||||
from freqtrade.persistence import Trade, Order
|
||||
from typing import Optional
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -42,14 +42,14 @@ class ChanLun_BTC_30(IStrategy):
|
||||
"1200": 0
|
||||
}
|
||||
# 5m and 15m
|
||||
minimal_roi_1 = {
|
||||
minimal_roi = {
|
||||
"0": 0.1,
|
||||
"60": 0.05,
|
||||
"120": 0.02,
|
||||
"240": 0
|
||||
}
|
||||
# 15m and 30m
|
||||
minimal_roi_1 = {
|
||||
minimal_roi = {
|
||||
"0": 0.1,
|
||||
"240": 0.05,
|
||||
"480": 0.03,
|
||||
@@ -62,12 +62,12 @@ class ChanLun_BTC_30(IStrategy):
|
||||
"3600": 0
|
||||
}
|
||||
can_short = True
|
||||
lev = 1.0
|
||||
lev = 2.0
|
||||
stoploss = -0.3
|
||||
trailing_stop = False
|
||||
trailing_stop = True
|
||||
trailing_stop_positive = 0.025
|
||||
trailing_stop_positive_offset = 0.045
|
||||
trailing_only_offset_is_reached = False
|
||||
trailing_only_offset_is_reached = True
|
||||
|
||||
position_adjustment_enable = True
|
||||
startup_candle_count = 600
|
||||
@@ -81,6 +81,7 @@ class ChanLun_BTC_30(IStrategy):
|
||||
chan = ChanLun()
|
||||
chanpy = ChanPY()
|
||||
classifier = ChanLunClassifier(None)
|
||||
last_trade = None
|
||||
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
|
||||
# resample our dataframes
|
||||
@@ -104,17 +105,13 @@ class ChanLun_BTC_30(IStrategy):
|
||||
dataframe_4h = self.add_indicators(dataframe_4h)
|
||||
dataframe_1d = self.add_indicators(dataframe_1d)
|
||||
#self.chan.plot_dual(dataframe_5, dataframe_30)
|
||||
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
|
||||
dataframe_5['chanpy_state'] = self.chanpy.get_bsp_state(dataframe_5)
|
||||
state_list, fx_list = self.chan.get_klc_strength_list(dataframe_30)
|
||||
dataframe_30['state'] = state_list
|
||||
dataframe_30['fx'] = fx_list
|
||||
klc_list = self.chan.get_klc_list(dataframe_30)
|
||||
bi_list = self.chan.cal_bi_list(klc_list)
|
||||
|
||||
if self.last_time + timedelta(minutes=1) < datetime.now():
|
||||
print(state_list[-1], state_list[-2], state_list[-3], state_list[-4], state_list[-5])
|
||||
print(fx_list[-1], fx_list[-2], fx_list[-3], fx_list[-4], fx_list[-5])
|
||||
print(klc_list[-1].klc_fx_type, klc_list[-2].klc_fx_type, klc_list[-3].klc_fx_type, klc_list[-4].klc_fx_type, klc_list[-5].klc_fx_type)
|
||||
|
||||
print("-------------------------------------------------------------------------------")
|
||||
self.last_time = datetime.now()
|
||||
dataframe = resampled_merge(dataframe, dataframe_5)
|
||||
@@ -168,18 +165,84 @@ class ChanLun_BTC_30(IStrategy):
|
||||
else:
|
||||
new_exitprice = proposed_rate - 50
|
||||
return new_exitprice
|
||||
|
||||
|
||||
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float,
|
||||
time_in_force: str, current_time: datetime, entry_tag: str | None,
|
||||
side: str, **kwargs) -> bool:
|
||||
if self.last_trade:
|
||||
if self.last_trade.open_date + timedelta(minutes=30) > current_time:
|
||||
return False
|
||||
#if self.last_trade:
|
||||
#print(self.last_trade.open_date, current_time, self.last_trade.open_date + timedelta(minutes=self.time5))
|
||||
return True
|
||||
|
||||
def custom_exit(self, pair: str, trade: Trade, current_time: datetime, current_rate: float,
|
||||
current_profit: float, **kwargs):
|
||||
#dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
|
||||
#last_candle = dataframe.iloc[-1].squeeze()
|
||||
"""
|
||||
# Above 20% profit, sell when rsi < 80
|
||||
if current_profit > 0.2:
|
||||
if last_candle["rsi"] < 80:
|
||||
return "rsi_below_80"
|
||||
|
||||
# Between 2% and 10%, sell if EMA-long above EMA-short
|
||||
if 0.02 < current_profit < 0.1:
|
||||
if last_candle["emalong"] > last_candle["emashort"]:
|
||||
return "ema_long_below_80"
|
||||
|
||||
# Sell any positions at a loss if they are held for more than one day.
|
||||
if current_profit < 0.0 and (current_time - trade.open_date_utc).days >= 1:
|
||||
return "unclog"
|
||||
"""
|
||||
if trade.is_short:
|
||||
last_high = trade.get_custom_data(key="entry_candle_high")
|
||||
if current_rate > last_high:
|
||||
print(trade.open_date, last_high, current_rate, "Relay Top FX exit")
|
||||
return "Relay Top FX exit"
|
||||
else:
|
||||
last_low = trade.get_custom_data(key="entry_candle_low")
|
||||
if current_rate < last_low:
|
||||
print(trade.open_date, last_low, current_rate, "Relay Bottom FX exit")
|
||||
return "Relay Bottom FX exit"
|
||||
def order_filled(self, pair: str, trade: Trade, order: Order, current_time: datetime, **kwargs) -> None:
|
||||
"""
|
||||
Called right after an order fills.
|
||||
Will be called for all order types (entry, exit, stoploss, position adjustment).
|
||||
:param pair: Pair for trade
|
||||
:param trade: trade object.
|
||||
:param order: Order object.
|
||||
:param current_time: datetime object, containing the current datetime
|
||||
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
||||
"""
|
||||
# Obtain pair dataframe (just to show how to access it)
|
||||
dataframe, _ = self.dp.get_analyzed_dataframe(trade.pair, self.timeframe)
|
||||
#last_candle = dataframe.iloc[-1].squeeze()
|
||||
klc_list = self.chan.get_klc_list(resample_to_interval(dataframe, self.get_ticker_indicator() * 30))
|
||||
bi_list = self.chan.cal_bi_list(klc_list)
|
||||
last_high = klc_list[-3].high
|
||||
last_low = klc_list[-3].low
|
||||
if trade.is_short:
|
||||
if (trade.nr_of_successful_entries == 1) and (order.ft_order_side == trade.entry_side):
|
||||
trade.set_custom_data(key="entry_candle_high", value=last_high)
|
||||
else:
|
||||
if (trade.nr_of_successful_entries == 1) and (order.ft_order_side == trade.entry_side):
|
||||
trade.set_custom_data(key="entry_candle_low", value=last_low)
|
||||
print(trade.open_date, trade.close_date, last_high, last_low, order.ft_order_side, klc_list[-2].start_time, klc_list[-2].end_time)
|
||||
self.last_trade = trade
|
||||
return None
|
||||
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
state_str = 'resample_{}_state'.format(self.get_ticker_indicator()*self.time30)
|
||||
fx_str = 'resample_{}_fx'.format(self.get_ticker_indicator()*self.time30)
|
||||
chanpy_state_str = 'resample_{}_chanpy_state'.format(self.get_ticker_indicator()*self.time5)
|
||||
shift_time = self.time30
|
||||
shift_time = self.time30*2
|
||||
strength = 2.2
|
||||
dataframe.loc[
|
||||
(
|
||||
#(dataframe['state'] == "-30")
|
||||
(dataframe[state_str].shift(shift_time) > 1.0) &
|
||||
(dataframe[state_str].shift(shift_time) > strength) &
|
||||
(dataframe[fx_str].shift(shift_time) == -1) &
|
||||
(dataframe[chanpy_state_str].shift(shift_time) == 1)
|
||||
(dataframe[chanpy_state_str].shift(shift_time+10) == 1)
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)].shift(self.time5) == "-10") &
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)] == "-10") &
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)].shift(self.time5) == "-10")
|
||||
@@ -189,9 +252,9 @@ class ChanLun_BTC_30(IStrategy):
|
||||
dataframe.loc[
|
||||
(
|
||||
#(dataframe['state'] == "-30")
|
||||
(dataframe[state_str].shift(shift_time) > 1.0) &
|
||||
(dataframe[state_str].shift(shift_time) > strength) &
|
||||
(dataframe[fx_str].shift(shift_time) == 1) &
|
||||
(dataframe[chanpy_state_str].shift(shift_time) == -1)
|
||||
(dataframe[chanpy_state_str].shift(shift_time+10) == -1)
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)].shift(self.time5) == "-10") &
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)] == "-10") &
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)].shift(self.time5) == "-10")
|
||||
@@ -203,13 +266,14 @@ class ChanLun_BTC_30(IStrategy):
|
||||
state_str = 'resample_{}_state'.format(self.get_ticker_indicator()*self.time30)
|
||||
fx_str = 'resample_{}_fx'.format(self.get_ticker_indicator()*self.time30)
|
||||
chanpy_state_str = 'resample_{}_chanpy_state'.format(self.get_ticker_indicator()*self.time5)
|
||||
shift_time = self.time30
|
||||
shift_time = self.time30*2
|
||||
strength = 2.2
|
||||
dataframe.loc[
|
||||
(
|
||||
#(dataframe['state']== "30")
|
||||
(dataframe[state_str].shift(shift_time) > 1.0) &
|
||||
(dataframe[state_str].shift(shift_time) > strength) &
|
||||
(dataframe[fx_str].shift(shift_time) == 1) &
|
||||
(dataframe[chanpy_state_str].shift(shift_time) == -1)
|
||||
(dataframe[chanpy_state_str].shift(shift_time+10) == -1)
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)] == "10") &
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time60)] == "10")
|
||||
),
|
||||
@@ -217,9 +281,9 @@ class ChanLun_BTC_30(IStrategy):
|
||||
dataframe.loc[
|
||||
(
|
||||
#(dataframe['state']== "30")
|
||||
(dataframe[state_str].shift(shift_time) > 1.0) &
|
||||
(dataframe[state_str].shift(shift_time) > strength) &
|
||||
(dataframe[fx_str].shift(shift_time) == -1) &
|
||||
(dataframe[chanpy_state_str].shift(shift_time) == 1)
|
||||
(dataframe[chanpy_state_str].shift(shift_time+10) == 1)
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)] == "10") &
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time60)] == "10")
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user