retreat commit
This commit is contained in:
594
v2realbot/archived/ENTRY_KLARA.py
Normal file
594
v2realbot/archived/ENTRY_KLARA.py
Normal file
@ -0,0 +1,594 @@
|
||||
import os,sys
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
from v2realbot.strategy.base import StrategyState
|
||||
from v2realbot.strategy.StrategyOrderLimitVykladaciNormalizedMYSELL import StrategyOrderLimitVykladaciNormalizedMYSELL
|
||||
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, OrderSide, OrderType
|
||||
from v2realbot.indicators.indicators import ema
|
||||
from v2realbot.indicators.oscillators import rsi
|
||||
from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY, price2dec, print, safe_get, get_tick, round2five, is_open_rush, is_close_rush, eval_cond_dict
|
||||
from datetime import datetime
|
||||
#from icecream import install, ic
|
||||
#from rich import print
|
||||
from threading import Event
|
||||
from msgpack import packb, unpackb
|
||||
import asyncio
|
||||
import os
|
||||
from traceback import format_exc
|
||||
import inspect
|
||||
|
||||
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
""""
|
||||
MYSELL, CBAR
|
||||
|
||||
Rychloobratka KLARA
|
||||
|
||||
- profit 0.005
|
||||
- buy signal nejspis RSI, cilem co nejvic obchodu - rychle ven
|
||||
|
||||
|
||||
|
||||
"""
|
||||
stratvars = AttributeDict(maxpozic = 400,
|
||||
def_mode_from = 200,
|
||||
chunk = 10,
|
||||
MA = 2,
|
||||
Trend = 2,
|
||||
profit = 0.02,
|
||||
def_profit = 0.01,
|
||||
lastbuyindex=-6,
|
||||
pendingbuys={},
|
||||
limitka = None,
|
||||
limitka_price = None,
|
||||
jevylozeno=0,
|
||||
vykladka=5,
|
||||
curve = [0.01, 0.01, 0.01, 0, 0.02, 0.02, 0.01,0.01, 0.01,0.03, 0.01, 0.01, 0.01,0.04, 0.01,0.01, 0.01,0.05, 0.01,0.01, 0.01,0.01, 0.06,0.01, 0.01,0.01, 0.01],
|
||||
curve_def = [0.02, 0.02, 0.02, 0, 0, 0.02, 0, 0, 0, 0.02],
|
||||
blockbuy = 0,
|
||||
ticks2reset = 0.04,
|
||||
consolidation_bar_count = 10,
|
||||
slope_lookback = 300,
|
||||
lookback_offset = 20,
|
||||
minimum_slope = -0.05,
|
||||
first_buy_market = False
|
||||
)
|
||||
##toto rozparsovat a strategii spustit stejne jako v main
|
||||
toml_string = """
|
||||
[[strategies]]
|
||||
name = "V1 na BAC"
|
||||
symbol = "BAC"
|
||||
script = "ENTRY_backtest_strategyVykladaci"
|
||||
class = "StrategyOrderLimitVykladaci"
|
||||
open_rush = 0
|
||||
close_rush = 0
|
||||
[strategies.stratvars]
|
||||
maxpozic = 200
|
||||
chunk = 10
|
||||
MA = 6
|
||||
Trend = 5
|
||||
profit = 0.02
|
||||
lastbuyindex=-6
|
||||
pendingbuys={}
|
||||
limitka = "None"
|
||||
jevylozeno=0
|
||||
vykladka=5
|
||||
curve = [0.01, 0.01, 0.01,0.01, 0.02, 0.01,0.01, 0.01,0.03, 0.01, 0.01, 0.01,0.04, 0.01,0.01, 0.01,0.05, 0.01,0.01, 0.01,0.01, 0.06,0.01, 0.01,0.01, 0.01]
|
||||
blockbuy = 0
|
||||
ticks2reset = 0.04
|
||||
[[strategies.add_data]]
|
||||
symbol="BAC"
|
||||
rectype="bar"
|
||||
timeframe=5
|
||||
update_ltp=true
|
||||
align="round"
|
||||
mintick=0
|
||||
minsize=100
|
||||
exthours=false
|
||||
"""
|
||||
|
||||
def next(data, state: StrategyState):
|
||||
print(10*"*","NEXT START",10*"*")
|
||||
#ic(state.avgp, state.positions)
|
||||
#ic(state.vars)
|
||||
#ic(data)
|
||||
|
||||
#
|
||||
def is_defensive_mode():
|
||||
akt_pozic = int(state.positions)
|
||||
max_pozic = int(state.vars.maxpozic)
|
||||
def_mode_from = safe_get(state.vars, "def_mode_from",max_pozic/2)
|
||||
if akt_pozic >= int(def_mode_from):
|
||||
#state.ilog(e=f"DEFENSIVE mode ACTIVE {state.vars.def_mode_from=}", msg=state.positions)
|
||||
return True
|
||||
else:
|
||||
#state.ilog(e=f"STANDARD mode ACTIVE {state.vars.def_mode_from=}", msg=state.positions)
|
||||
return False
|
||||
|
||||
def get_limitka_price():
|
||||
def_profit = safe_get(state.vars, "def_profit",state.vars.profit)
|
||||
cena = float(state.avgp)
|
||||
#v MYSELL hrajeme i na 3 desetinna cisla - TBD mozna hrat jen na 5ky (0.125, 0.130, 0.135 atp.)
|
||||
if is_defensive_mode():
|
||||
return price2dec(cena+get_tick(cena,float(def_profit)),3)
|
||||
else:
|
||||
return price2dec(cena+get_tick(cena,float(state.vars.profit)),3)
|
||||
|
||||
def consolidation():
|
||||
##CONSOLIDATION PART - moved here, musí být před nákupem, jinak to dělalo nepořádek v pendingbuys
|
||||
#docasne zkusime konzolidovat i kdyz neni vylozeno (aby se srovnala limitka ve vsech situacich)
|
||||
if state.vars.jevylozeno == 1 or 1==1:
|
||||
##CONSOLIDATION PART kazdy Nty bar dle nastaveni
|
||||
if int(data["index"])%int(state.vars.consolidation_bar_count) == 0:
|
||||
print("***CONSOLIDATION ENTRY***")
|
||||
state.ilog(e="CONSOLIDATION ENTRY ***")
|
||||
|
||||
orderlist = state.interface.get_open_orders(symbol=state.symbol, side=None)
|
||||
#pro jistotu jeste dotahneme aktualni pozice
|
||||
state.avgp, state.positions = state.interface.pos()
|
||||
|
||||
#print(orderlist)
|
||||
pendingbuys_new = {}
|
||||
#zaciname s cistym stitem
|
||||
state.vars.limitka = None
|
||||
state.vars.limitka_price = None
|
||||
for o in orderlist:
|
||||
if o.side == OrderSide.BUY and o.order_type == OrderType.LIMIT:
|
||||
pendingbuys_new[str(o.id)]=float(o.limit_price)
|
||||
|
||||
if pendingbuys_new != state.vars.pendingbuys:
|
||||
state.ilog(e="Rozdilna PB prepsana", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys)
|
||||
print("ROZDILNA PENDINGBUYS přepsána")
|
||||
print("OLD",state.vars.pendingbuys)
|
||||
state.vars.pendingbuys = unpackb(packb(pendingbuys_new))
|
||||
print("NEW", state.vars.pendingbuys)
|
||||
else:
|
||||
print("PENDINGBUYS sedí - necháváme", state.vars.pendingbuys)
|
||||
state.ilog(e="PB sedi nechavame", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys)
|
||||
print("OLD jevylozeno", state.vars.jevylozeno)
|
||||
if len(state.vars.pendingbuys) > 0:
|
||||
state.vars.jevylozeno = 1
|
||||
else:
|
||||
state.vars.jevylozeno = 0
|
||||
print("NEW jevylozeno", state.vars.jevylozeno)
|
||||
state.ilog(e="Nove jevylozeno", msg=state.vars.jevylozeno)
|
||||
|
||||
print("***CONSOLIDATION EXIT***")
|
||||
state.ilog(e="CONSOLIDATION EXIT ***")
|
||||
else:
|
||||
state.ilog(e="No time for consolidation", msg=data["index"])
|
||||
print("no time for consolidation", data["index"])
|
||||
#mozna presunout o level vys
|
||||
def vyloz():
|
||||
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
|
||||
#curve = [0.01, 0.01, 0, 0, 0.01, 0, 0, 0, 0.02, 0, 0, 0, 0.03, 0,0,0,0,0, 0.02, 0,0,0,0,0,0, 0.02]
|
||||
curve = state.vars.curve
|
||||
##defenzivni krivka pro
|
||||
curve_def = state.vars.curve_def
|
||||
#vykladani po 5ti kusech, když zbývají 2 a méně, tak děláme nový výklad
|
||||
vykladka = state.vars.vykladka
|
||||
#kolik muzu max vylozit
|
||||
kolikmuzu = int((int(state.vars.maxpozic) - int(state.positions))/int(state.vars.chunk))
|
||||
akt_pozic = int(state.positions)
|
||||
max_pozic = int(state.vars.maxpozic)
|
||||
|
||||
if akt_pozic >= max_pozic:
|
||||
state.ilog(e="MAX pozic reached, cannot vyklad")
|
||||
return
|
||||
|
||||
#mame polovinu a vic vylozeno, pouzivame defenzicni krivku
|
||||
if is_defensive_mode():
|
||||
state.ilog(e="DEF: Pouzivame defenzivni krivku", akt_pozic=akt_pozic, max_pozic=max_pozic, curve_def=curve_def)
|
||||
curve = curve_def
|
||||
#zaroven docasne menime ticks2reset na defenzivni 0.06
|
||||
state.vars.ticks2reset = 0.06
|
||||
state.ilog(e="DEF: Menime tick2reset na 0.06", ticks2reset=state.vars.ticks2reset, ticks2reset_backup=state.vars.ticks2reset_backup)
|
||||
else:
|
||||
#vracime zpet, pokud bylo zmeneno
|
||||
if state.vars.ticks2reset != state.vars.ticks2reset_backup:
|
||||
state.vars.ticks2reset = state.vars.ticks2reset_backup
|
||||
state.ilog(e="DEF: Menime tick2reset zpet na"+str(state.vars.ticks2reset), ticks2reset=state.vars.ticks2reset, ticks2reset_backup=state.vars.ticks2reset_backup)
|
||||
|
||||
if kolikmuzu < vykladka: vykladka = kolikmuzu
|
||||
|
||||
if len(curve) < vykladka:
|
||||
vykladka = len(curve)
|
||||
qty = int(state.vars.chunk)
|
||||
last_price = price2dec(state.interface.get_last_price(state.symbol))
|
||||
#profit = float(state.vars.profit)
|
||||
price = last_price
|
||||
state.ilog(e="BUY Vykladame", msg=f"first price {price=} {vykladka=}", curve=curve, ema=state.indicators.ema[-1], trend=state.vars.Trend, price=price, vykladka=vykladka)
|
||||
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
|
||||
|
||||
##VAR - na zaklade conf. muzeme jako prvni posilat MARKET order
|
||||
if safe_get(state.vars, "first_buy_market") == True:
|
||||
#pri defenzivnim rezimu pouzivame vzdy LIMIT order
|
||||
if is_defensive_mode():
|
||||
state.ilog(e="DEF mode on, odesilame jako prvni limitku")
|
||||
state.buy_l(price=price, size=qty)
|
||||
else:
|
||||
state.ilog(e="Posilame jako prvni MARKET order")
|
||||
state.buy(size=qty)
|
||||
else:
|
||||
state.buy_l(price=price, size=qty)
|
||||
print("prvni limitka na aktuální cenu. Další podle křivky", price, qty)
|
||||
for i in range(0,vykladka-1):
|
||||
price = price2dec(float(price - get_tick(price, curve[i])))
|
||||
if price == last_price:
|
||||
qty = qty + int(state.vars.chunk)
|
||||
else:
|
||||
state.buy_l(price=price, size=qty)
|
||||
#print(i,"BUY limitka - delta",curve[i]," cena:", price, "mnozstvi:", qty)
|
||||
qty = int(state.vars.chunk)
|
||||
last_price = price
|
||||
state.vars.blockbuy = 1
|
||||
state.vars.jevylozeno = 1
|
||||
state.vars.last_buysignal_index = data['index']
|
||||
|
||||
def eval_sell():
|
||||
""""
|
||||
TBD
|
||||
Když je RSI nahoře tak neprodávat, dokud 1) RSI neprestane stoupat 2)nedosahne to nad im not greedy limit
|
||||
"""
|
||||
##mame pozice
|
||||
##aktualni cena je vetsi nebo rovna cene limitky
|
||||
#muzeme zde jet i na pulcenty
|
||||
curr_price = float(data['close'])
|
||||
state.ilog(e="Eval SELL", price=curr_price, pos=state.positions, avgp=state.avgp, sell_in_progress=state.vars.sell_in_progress)
|
||||
if int(state.positions) > 0 and float(state.avgp)>0 and state.vars.sell_in_progress is False:
|
||||
goal_price = get_limitka_price()
|
||||
state.ilog(e=f"Goal price {goal_price}")
|
||||
if curr_price>=goal_price:
|
||||
|
||||
#TODO cekat az slope prestane intenzivn erust, necekat az na klesani
|
||||
#TODO mozna cekat na nejaky signal RSI
|
||||
#TODO pripadne pokud dosahne TGTBB prodat ihned
|
||||
|
||||
#OPTIMALIZACE pri stoupajícím angle
|
||||
if sell_protection_enabled() is False:
|
||||
state.interface.sell(size=state.positions)
|
||||
state.vars.sell_in_progress = True
|
||||
state.ilog(e=f"market SELL was sent {curr_price=}", positions=state.positions, avgp=state.avgp, sellinprogress=state.vars.sell_in_progress)
|
||||
|
||||
def populate_ema_indicator():
|
||||
#BAR EMA INDICATOR -
|
||||
#plnime MAcko - nyni posilame jen N poslednich hodnot
|
||||
#zaroven osetrujeme pripady, kdy je malo dat a ukladame nulu
|
||||
try:
|
||||
ma = int(state.vars.MA)
|
||||
#poslednich ma hodnot
|
||||
source = state.bars.close[-ma:] #state.bars.vwap
|
||||
ema_value = ema(source, ma)
|
||||
|
||||
##pokus MACKO zakrouhlit na tri desetina a petku
|
||||
state.indicators.ema[-1]=round2five(ema_value[-1])
|
||||
##state.indicators.ema[-1]=trunc(ema_value[-1],3)
|
||||
#state.ilog(e=f"EMA {state.indicators.ema[-1]}", ema_last=state.indicators.ema[-6:])
|
||||
except Exception as e:
|
||||
state.ilog(e="EMA nechavame 0", message=str(e)+format_exc())
|
||||
#state.indicators.ema[-1]=(0)
|
||||
#evaluate buy signal
|
||||
#consolidation
|
||||
|
||||
def populate_slope_indicator():
|
||||
#SLOPE INDICATOR
|
||||
#úhel stoupání a klesání vyjádřený mezi -1 až 1
|
||||
#pravý bod přímky je aktuální cena, levý je průměr X(lookback offset) starších hodnot od slope_lookback.
|
||||
#obsahuje statický indikátor (angle) pro vizualizaci
|
||||
try:
|
||||
slope = 99
|
||||
slope_lookback = int(state.vars.slope_lookback)
|
||||
minimum_slope = float(state.vars.minimum_slope)
|
||||
lookback_offset = int(state.vars.lookback_offset)
|
||||
|
||||
if len(state.bars.close) > (slope_lookback + lookback_offset):
|
||||
array_od = slope_lookback + lookback_offset
|
||||
array_do = slope_lookback
|
||||
lookbackprice_array = state.bars.vwap[-array_od:-array_do]
|
||||
#obycejný prumer hodnot
|
||||
lookbackprice = round(sum(lookbackprice_array)/lookback_offset,3)
|
||||
|
||||
#výpočet úhlu - a jeho normalizace
|
||||
slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100
|
||||
slope = round(slope, 4)
|
||||
state.indicators.slope[-1]=slope
|
||||
|
||||
#angle je ze slope
|
||||
state.statinds.angle = dict(time=state.bars.time[-1], price=state.bars.close[-1], lookbacktime=state.bars.time[-slope_lookback], lookbackprice=lookbackprice, minimum_slope=minimum_slope, maximum_slope=safe_get(state.vars, "bigwave_slope_above",0.20))
|
||||
|
||||
#slope MA vyrovna vykyvy ve slope, dále pracujeme se slopeMA
|
||||
slope_MA_length = 5
|
||||
source = state.indicators.slope[-slope_MA_length:]
|
||||
slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap
|
||||
slopeMA = slopeMAseries[-1]
|
||||
state.indicators.slopeMA[-1]=slopeMA
|
||||
|
||||
state.ilog(e=f"{slope=} {slopeMA=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:], last_slopesMA=state.indicators.slopeMA[-10:])
|
||||
|
||||
#dale pracujeme s timto MAckovanym slope
|
||||
slope = slopeMA
|
||||
else:
|
||||
#pokud plnime historii musime ji plnit od zacatku, vsehcny idenitifkatory maji spolecny time
|
||||
#kvuli spravnemu zobrazovani na gui
|
||||
#state.indicators.slopeMA[-1]=0
|
||||
#state.indicators.slopeMA.append(0)
|
||||
state.ilog(e="Slope - not enough data", slope_lookback=slope_lookback, slope=state.indicators.slope, slopeMA=state.indicators.slopeMA)
|
||||
except Exception as e:
|
||||
print("Exception in NEXT Slope Indicator section", str(e))
|
||||
state.ilog(e="EXCEPTION", msg="Exception in Slope Indicator section" + str(e) + format_exc())
|
||||
|
||||
def populate_rsi_indicator():
|
||||
#RSI14 INDICATOR
|
||||
try:
|
||||
rsi_length = int(safe_get(state.vars, "rsi_length",14))
|
||||
source = state.bars.close #[-rsi_length:] #state.bars.vwap
|
||||
rsi_res = rsi(source, rsi_length)
|
||||
rsi_value = trunc(rsi_res[-1],3)
|
||||
state.indicators.RSI14[-1]=rsi_value
|
||||
#state.ilog(e=f"RSI {rsi_length=} {rsi_value=} {rsi_dont_buy=} {rsi_buy_signal=}", rsi_indicator=state.indicators.RSI14[-5:])
|
||||
except Exception as e:
|
||||
state.ilog(e=f"RSI {rsi_length=} necháváme 0", message=str(e)+format_exc())
|
||||
#state.indicators.RSI14[-1]=0
|
||||
|
||||
def populate_cbar_rsi_indicator():
|
||||
#CBAR RSI indicator
|
||||
try:
|
||||
crsi_length = int(safe_get(state.vars, "crsi_length",14))
|
||||
source = state.cbar_indicators.tick_price #[-rsi_length:] #state.bars.vwap
|
||||
crsi_res = rsi(source, crsi_length)
|
||||
crsi_value = trunc(crsi_res[-1],3)
|
||||
state.cbar_indicators.CRSI[-1]=crsi_value
|
||||
#state.ilog(e=f"RSI {rsi_length=} {rsi_value=} {rsi_dont_buy=} {rsi_buy_signal=}", rsi_indicator=state.indicators.RSI14[-5:])
|
||||
except Exception as e:
|
||||
state.ilog(e=f"CRSI {crsi_length=} necháváme 0", message=str(e)+format_exc())
|
||||
#state.indicators.RSI14[-1]=0
|
||||
|
||||
def slope_too_low():
|
||||
return state.indicators.slopeMA[-1] < float(state.vars.minimum_slope)
|
||||
|
||||
def slope_too_high():
|
||||
return state.indicators.slopeMA[-1] > float(safe_get(state.vars, "bigwave_slope_above",0.20))
|
||||
|
||||
#resetujeme, kdyz 1) je aktivni buy protection 2) kdyz to ujede
|
||||
#TODO mozna tick2reset spoustet jednou za X opakovani
|
||||
def pendingbuys_optimalization():
|
||||
if len(state.vars.pendingbuys)>0:
|
||||
if buy_protection_enabled():
|
||||
#state.ilog(e="PENDINGBUYS reset", message=inspect.currentframe().f_code.co_name)
|
||||
res = asyncio.run(state.cancel_pending_buys())
|
||||
state.ilog(e="CANCEL pendingbuyes", pb=state.vars.pendingbuys, res=res)
|
||||
else:
|
||||
#pokud mame vylozeno a cena je vetsi nez tick2reset
|
||||
maxprice = max(state.vars.pendingbuys.values())
|
||||
if state.interface.get_last_price(state.symbol) > float(maxprice) + get_tick(maxprice, float(state.vars.ticks2reset)):
|
||||
res = asyncio.run(state.cancel_pending_buys())
|
||||
state.ilog(e=f"UJELO to. Rusime PB", msg=f"{state.vars.ticks2reset=}", pb=state.vars.pendingbuys)
|
||||
|
||||
#PENDING BUYS SPENT - PART
|
||||
#pokud mame vylozeno a pendingbuys se vyklepou a
|
||||
# 1 vykladame idned znovu
|
||||
# vyloz()
|
||||
# 2 nebo - počkat zase na signál a pokračovat dál
|
||||
# state.vars.blockbuy = 0
|
||||
# state.vars.jevylozeno = 0
|
||||
# 3 nebo - počkat na signál s enablovaným lastbuy indexem (tzn. počká nutně ještě pár barů)
|
||||
#podle BT vyhodnejsi vylozit ihned
|
||||
if len(state.vars.pendingbuys) == 0:
|
||||
state.vars.blockbuy = 0
|
||||
state.vars.jevylozeno = 0
|
||||
state.ilog(e="PB prazdne nastavujeme: neni vylozeno", jevylozeno=state.vars.jevylozeno)
|
||||
|
||||
##kdy nesmí být žádné nákupní objednávky - zruší se
|
||||
def buy_protection_enabled():
|
||||
dont_buy_when = dict(AND=dict(), OR=dict())
|
||||
##add conditions here
|
||||
dont_buy_when['rsi_too_high'] = state.indicators.RSI14[-1] > safe_get(state.vars, "rsi_dont_buy_above",50)
|
||||
dont_buy_when['slope_too_low'] = slope_too_low()
|
||||
|
||||
result, cond_met = eval_cond_dict(dont_buy_when)
|
||||
if result:
|
||||
state.ilog(e=f"BUY_PROTECTION {cond_met}")
|
||||
return result
|
||||
|
||||
def sell_protection_enabled():
|
||||
dont_sell_when = dict(AND=dict(), OR=dict())
|
||||
##add conditions here
|
||||
|
||||
#IDENTIFIKOVAce rustoveho MOMENTA - pokud je momentum, tak prodávat později
|
||||
|
||||
#pokud je slope too high, pak prodavame jakmile slopeMA zacne klesat, napr. 4MA (TODO 3)
|
||||
|
||||
#toto docasne pryc dont_sell_when['slope_too_high'] = slope_too_high() and not isfalling(state.indicators.slopeMA,4)
|
||||
dont_sell_when['AND']['slopeMA_rising'] = isrising(state.indicators.slopeMA,2)
|
||||
dont_sell_when['AND']['rsi_not_falling'] = not isfalling(state.indicators.RSI14,3)
|
||||
#dont_sell_when['rsi_dont_buy'] = state.indicators.RSI14[-1] > safe_get(state.vars, "rsi_dont_buy_above",50)
|
||||
|
||||
result, conditions_met = eval_cond_dict(dont_sell_when)
|
||||
if result:
|
||||
state.ilog(e=f"SELL_PROTECTION {conditions_met} enabled")
|
||||
return result
|
||||
|
||||
#preconditions and conditions of BUY SIGNAL
|
||||
def buy_conditions_met():
|
||||
#preconditions
|
||||
dont_buy_when = dict(AND=dict(), OR=dict())
|
||||
|
||||
|
||||
if safe_get(state.vars, "buy_only_on_confirmed",True):
|
||||
dont_buy_when['bar_not_confirmed'] = (data['confirmed'] == 0)
|
||||
#od posledniho vylozeni musi ubehnout N baru
|
||||
dont_buy_when['last_buy_offset_too_soon'] = data['index'] < (state.vars.last_buysignal_index + safe_get(state.vars, "lastbuy_offset",3))
|
||||
dont_buy_when['blockbuy_active'] = (state.vars.blockbuy == 1)
|
||||
dont_buy_when['jevylozeno_active'] = (state.vars.jevylozeno == 1)
|
||||
dont_buy_when['rsi_too_high'] = state.indicators.RSI14[-1] > safe_get(state.vars, "rsi_dont_buy_above",50)
|
||||
dont_buy_when['slope_too_low'] = slope_too_low()
|
||||
dont_buy_when['open_rush'] = is_open_rush(datetime.fromtimestamp(data['updated']).astimezone(zoneNY), safe_get(state.vars, "open_rush",0))
|
||||
dont_buy_when['close_rush'] = is_close_rush(datetime.fromtimestamp(data['updated']).astimezone(zoneNY), safe_get(state.vars, "close_rush",0))
|
||||
dont_buy_when['rsi_is_zero'] = (state.indicators.RSI14[-1] == 0)
|
||||
|
||||
#testing preconditions
|
||||
result, cond_met = eval_cond_dict(dont_buy_when)
|
||||
if result:
|
||||
state.ilog(e=f"BUY precondition not met {cond_met}")
|
||||
return False
|
||||
|
||||
#conditions - bud samostatne nebo v groupe - ty musi platit dohromady
|
||||
buy_cond = dict(AND=dict(), OR=dict())
|
||||
##add buy conditions here
|
||||
#cond groups ["AND"]
|
||||
#cond groups ["OR"]
|
||||
#no cond group - takes first
|
||||
#TEST BUY SIGNALu z cbartick_price - 3klesave za sebou
|
||||
#buy_cond['tick_price_falling_trend'] = isfalling(state.cbar_indicators.tick_price,state.vars.Trend)
|
||||
|
||||
#slopeMA jde dolu, rsi jde nahoru
|
||||
#buy mame kazdy potvrzeny, tzn. rsi falling muze byt jen 2
|
||||
|
||||
#buy_cond['AND']['slopeMA_falling'] = isfalling(state.indicators.slopeMA,3)
|
||||
#buy_cond['AND']['rsi_is_rising'] = isrising(state.indicators.RSI14,2)
|
||||
#buy_cond["AND"]["rsi_buy_signal_below"] = state.indicators.RSI14[-1] < safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
|
||||
#puvodni buy conditiony RSI pod + EMA klesajici
|
||||
#buy_cond["AND"]["rsi_buy_signal_below"] = state.indicators.RSI14[-1] < safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
#buy_cond["AND"]["ema_trend_is_falling"] = isfalling(state.indicators.ema,state.vars.Trend)
|
||||
|
||||
#pouze RSI nizke a RSI klesa
|
||||
buy_cond["AND"]["rsi_buy_signal_below"] = state.indicators.RSI14[-1] < safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
buy_cond["AND"]["rsi_is_falling"] = isfalling(state.indicators.RSI14,state.vars.Trend)
|
||||
|
||||
#buy_cond['crsi_below_crsi_buy_limit'] = state.cbar_indicators.CRSI[-1] < safe_get(state.vars, "crsi_buy_signal_below",30)
|
||||
|
||||
#slopME klesa a RSI začalo stoupat
|
||||
# buy_cond["AND"]["rsi_is_rising2"] = isrising(state.indicators.RSI14,2)
|
||||
# buy_cond['AND']['slopeMA_falling_Trend'] = isfalling(state.indicators.slopeMA,state.vars.Trend)
|
||||
# buy_cond["AND"]["rsi_buy_signal_below"] = state.indicators.RSI14[-1] < safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
|
||||
|
||||
#zkusit jako doplnkovy BUY SIGNAL 3 klesavy cbar RSI pripadne TICK PRICE
|
||||
|
||||
result, conditions_met = eval_cond_dict(buy_cond)
|
||||
if result:
|
||||
state.ilog(e=f"BUY SIGNAL {conditions_met}")
|
||||
return result
|
||||
|
||||
def eval_buy():
|
||||
if buy_conditions_met():
|
||||
vyloz()
|
||||
|
||||
def populate_cbar_tick_price_indicator():
|
||||
try:
|
||||
#pokud v potvrzovacím baru nebyly zmeny, nechavam puvodni hodnoty
|
||||
# if tick_delta_volume == 0:
|
||||
# state.indicators.tick_price[-1] = state.indicators.tick_price[-2]
|
||||
# state.indicators.tick_volume[-1] = state.indicators.tick_volume[-2]
|
||||
# else:
|
||||
|
||||
tick_price = round2five(data['close'])
|
||||
tick_delta_volume = data['volume'] - state.vars.last_tick_volume
|
||||
|
||||
#docasne dame pryc volume deltu a davame absolutni cislo
|
||||
state.cbar_indicators.tick_price[-1] = tick_price
|
||||
state.cbar_indicators.tick_volume[-1] = tick_delta_volume
|
||||
except:
|
||||
pass
|
||||
|
||||
state.ilog(e=f"TICK PRICE {tick_price} VOLUME {tick_delta_volume} {conf_bar=}", prev_price=state.vars.last_tick_price, prev_volume=state.vars.last_tick_volume)
|
||||
|
||||
state.vars.last_tick_price = tick_price
|
||||
state.vars.last_tick_volume = data['volume']
|
||||
|
||||
def get_last_ind_vals():
|
||||
last_ind_vals = {}
|
||||
#print(state.indicators.items())
|
||||
for key in state.indicators:
|
||||
if key != 'time':
|
||||
last_ind_vals[key] = state.indicators[key][-5:]
|
||||
|
||||
for key in state.cbar_indicators:
|
||||
if key != 'time':
|
||||
last_ind_vals[key] = state.cbar_indicators[key][-5:]
|
||||
return last_ind_vals
|
||||
|
||||
conf_bar = data['confirmed']
|
||||
last_update_delta = round((float(data['updated']) - state.vars.last_update_time),6) if state.vars.last_update_time != 0 else 0
|
||||
state.vars.last_update_time = float(data['updated'])
|
||||
state.ilog(e=f"---{data['index']}-{conf_bar}--delta:{last_update_delta}")
|
||||
|
||||
#kroky pro CONFIRMED BAR only
|
||||
if conf_bar == 1:
|
||||
#logika pouze pro potvrzeny bar
|
||||
state.ilog(e="BAR potvrzeny")
|
||||
|
||||
|
||||
#pri potvrzem CBARu nulujeme counter volume pro tick based indicator
|
||||
state.vars.last_tick_volume = 0
|
||||
state.vars.next_new = 1
|
||||
|
||||
#kroky pro CONTINOUS TICKS only
|
||||
else:
|
||||
#CBAR INDICATOR pro tick price a deltu VOLUME
|
||||
populate_cbar_tick_price_indicator()
|
||||
populate_cbar_rsi_indicator()
|
||||
|
||||
#SPOLECNA LOGIKA - bar indikatory muzeme populovat kazdy tick (dobre pro RT GUI), ale uklada se stejne az pri confirmu
|
||||
|
||||
|
||||
populate_ema_indicator()
|
||||
populate_slope_indicator()
|
||||
populate_rsi_indicator()
|
||||
eval_sell()
|
||||
consolidation()
|
||||
|
||||
#HLAVNI ITERACNI LOG JESTE PRED AKCI - obsahuje aktualni hodnoty vetsiny parametru
|
||||
lp = state.interface.get_last_price(symbol=state.symbol)
|
||||
state.ilog(e="ENTRY", msg=f"LP:{lp} P:{state.positions}/{round(float(state.avgp),3)} profit:{round(float(state.profit),2)} Trades:{len(state.tradeList)} DEF:{str(is_defensive_mode())}", last_price=lp, data=data, stratvars=state.vars)
|
||||
state.ilog(e="Indikatory", msg=str(get_last_ind_vals()))
|
||||
|
||||
eval_buy()
|
||||
pendingbuys_optimalization()
|
||||
|
||||
def init(state: StrategyState):
|
||||
#place to declare new vars
|
||||
print("INIT v main",state.name)
|
||||
|
||||
state.vars['sell_in_progress'] = False
|
||||
state.vars.last_tick_price = 0
|
||||
state.vars.last_tick_volume = 0
|
||||
state.vars.next_new = 0
|
||||
state.vars.last_buysignal_index = 0
|
||||
state.vars.last_update_time = 0
|
||||
#state.cbar_indicators['ivwap'] = []
|
||||
state.cbar_indicators['tick_price'] = []
|
||||
state.cbar_indicators['tick_volume'] = []
|
||||
state.cbar_indicators['CRSI'] = []
|
||||
state.indicators['ema'] = []
|
||||
state.indicators['slope'] = []
|
||||
state.indicators['slopeMA'] = []
|
||||
state.indicators['RSI14'] = []
|
||||
#static indicators - those not series based
|
||||
state.statinds['angle'] = dict(minimum_slope=state.vars["minimum_slope"], maximum_slope=safe_get(state.vars, "bigwave_slope_above",0.20))
|
||||
state.vars["ticks2reset_backup"] = state.vars.ticks2reset
|
||||
|
||||
def main():
|
||||
name = os.path.basename(__file__)
|
||||
se = Event()
|
||||
pe = Event()
|
||||
s = StrategyOrderLimitVykladaciNormalizedMYSELL(name = name, symbol = "BAC", account=Account.ACCOUNT1, next=next, init=init, stratvars=stratvars, open_rush=10, close_rush=0, pe=pe, se=se, ilog_save=True)
|
||||
s.set_mode(mode = Mode.BT,
|
||||
debug = False,
|
||||
start = datetime(2023, 4, 14, 10, 42, 0, 0, tzinfo=zoneNY),
|
||||
end = datetime(2023, 4, 14, 14, 35, 0, 0, tzinfo=zoneNY),
|
||||
cash=100000)
|
||||
|
||||
#na sekundovem baru nezaokrouhlovat MAcko
|
||||
s.add_data(symbol="BAC",rectype=RecordType.BAR,timeframe=2,minsize=100,update_ltp=True,align=StartBarAlign.ROUND,mintick=0, exthours=False)
|
||||
#s.add_data(symbol="C",rectype=RecordType.BAR,timeframe=1,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=0)
|
||||
|
||||
s.start()
|
||||
print("zastavujeme")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
487
v2realbot/archived/ENTRY_VykladaciTest.py
Normal file
487
v2realbot/archived/ENTRY_VykladaciTest.py
Normal file
@ -0,0 +1,487 @@
|
||||
import os,sys
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
from v2realbot.strategy.base import StrategyState
|
||||
from v2realbot.strategy.StrategyOrderLimitVykladaci import StrategyOrderLimitVykladaci
|
||||
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, OrderSide, OrderType
|
||||
from v2realbot.indicators.indicators import ema
|
||||
from v2realbot.indicators.oscillators import rsi, stochastic_oscillator, stochastic_rsi, absolute_price_oscillator, percentage_price_oscillator
|
||||
from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY, price2dec, print, safe_get
|
||||
from datetime import datetime
|
||||
#from icecream import install, ic
|
||||
#from rich import print
|
||||
from threading import Event
|
||||
from msgpack import packb, unpackb
|
||||
import asyncio
|
||||
import os
|
||||
from traceback import format_exc
|
||||
|
||||
def next(data, state: StrategyState):
|
||||
print(10*"*","NEXT START",10*"*")
|
||||
#ic(state.avgp, state.positions)
|
||||
#ic(state.vars)
|
||||
#ic(data)
|
||||
|
||||
#
|
||||
def is_defensive_mode():
|
||||
akt_pozic = int(state.positions)
|
||||
max_pozic = int(state.vars.maxpozic)
|
||||
def_mode_from = safe_get(state.vars, "def_mode_from")
|
||||
if def_mode_from == None: def_mode_from = max_pozic/2
|
||||
if akt_pozic >= int(def_mode_from):
|
||||
state.ilog(e=f"DEFENSIVE mode ACTIVE {state.vars.def_mode_from=}", msg=state.positions)
|
||||
return True
|
||||
else:
|
||||
state.ilog(e=f"STANDARD mode ACTIVE {state.vars.def_mode_from=}", msg=state.positions)
|
||||
return False
|
||||
|
||||
def get_limitka_price():
|
||||
def_profit = safe_get(state.vars, "def_profit")
|
||||
if def_profit == None: def_profit = state.vars.profit
|
||||
if is_defensive_mode():
|
||||
return price2dec(float(state.avgp)+float(def_profit))
|
||||
else:
|
||||
return price2dec(float(state.avgp)+float(state.vars.profit))
|
||||
|
||||
def consolidation():
|
||||
##CONSOLIDATION PART - moved here, musí být před nákupem, jinak to dělalo nepořádek v pendingbuys
|
||||
#docasne zkusime konzolidovat i kdyz neni vylozeno (aby se srovnala limitka ve vsech situacich)
|
||||
if state.vars.jevylozeno == 1 or 1==1:
|
||||
##CONSOLIDATION PART kazdy Nty bar dle nastaveni
|
||||
if int(data["index"])%int(state.vars.consolidation_bar_count) == 0:
|
||||
print("***CONSOLIDATION ENTRY***")
|
||||
state.ilog(e="CONSOLIDATION ENTRY ***")
|
||||
|
||||
orderlist = state.interface.get_open_orders(symbol=state.symbol, side=None)
|
||||
#pro jistotu jeste dotahneme aktualni pozice
|
||||
state.avgp, state.positions = state.interface.pos()
|
||||
|
||||
#print(orderlist)
|
||||
pendingbuys_new = {}
|
||||
limitka_old = state.vars.limitka
|
||||
#print("Puvodni LIMITKA", limitka_old)
|
||||
#zaciname s cistym stitem
|
||||
state.vars.limitka = None
|
||||
state.vars.limitka_price = None
|
||||
limitka_found = False
|
||||
limitka_qty = 0
|
||||
limitka_filled_qty = 0
|
||||
for o in orderlist:
|
||||
if o.side == OrderSide.SELL:
|
||||
|
||||
if limitka_found:
|
||||
state.ilog(e="nalezeno vicero sell objednavek, bereme prvni, ostatni - rusime")
|
||||
result=state.interface.cancel(o.id)
|
||||
state.ilog(e="zrusena objednavka"+str(o.id), message=result)
|
||||
continue
|
||||
|
||||
#print("Nalezena LIMITKA")
|
||||
limitka_found = True
|
||||
state.vars.limitka = o.id
|
||||
state.vars.limitka_price = o.limit_price
|
||||
limitka_qty = int(o.qty)
|
||||
limitka_filled_qty = int(o.filled_qty)
|
||||
|
||||
#aktualni mnozstvi = puvodni minus filled
|
||||
if limitka_filled_qty is not None:
|
||||
print("prepocitavam filledmnozstvi od limitka_qty a filled_qty", limitka_qty, limitka_filled_qty)
|
||||
limitka_qty = int(limitka_qty) - int(limitka_filled_qty)
|
||||
##TODO sem pridat upravu ceny
|
||||
if o.side == OrderSide.BUY and o.order_type == OrderType.LIMIT:
|
||||
pendingbuys_new[str(o.id)]=float(o.limit_price)
|
||||
|
||||
state.ilog(e="Konzolidace limitky", msg=f"stejna:{(str(limitka_old)==str(state.vars.limitka))}", limitka_old=str(limitka_old), limitka_new=str(state.vars.limitka), limitka_new_price=state.vars.limitka_price, limitka_qty=limitka_qty, limitka_filled_qty=limitka_filled_qty)
|
||||
|
||||
#pokud mame
|
||||
|
||||
#neni limitka, ale mela by byt - vytváříme ji
|
||||
if int(state.positions) > 0 and state.vars.limitka is None:
|
||||
state.ilog(e="Limitka neni, ale mela by být.", msg=f"{state.positions=}")
|
||||
price=get_limitka_price()
|
||||
state.vars.limitka = asyncio.run(state.interface.sell_l(price=price, size=int(state.positions)))
|
||||
state.vars.limitka_price = price
|
||||
if state.vars.limitka == -1:
|
||||
state.ilog(e="Vytvoreni limitky neprobehlo, vracime None", msg=f"{state.vars.limitka=}")
|
||||
state.vars.limitka = None
|
||||
state.vars.limitka_price = None
|
||||
else:
|
||||
state.ilog(e="Vytvořena nová limitka", limitka=str(state.vars.limitka), limtka_price=state.vars.limitka_price, qty=state.positions)
|
||||
|
||||
#existuje a nesedi mnozstvi nebo cena
|
||||
elif state.vars.limitka is not None and int(state.positions) > 0 and ((int(state.positions) != int(limitka_qty)) or float(state.vars.limitka_price) != float(get_limitka_price())):
|
||||
#limitka existuje, ale spatne mnostvi - updatujeme
|
||||
state.ilog(e=f"Limitka existuje, ale spatne mnozstvi nebo CENA - updatujeme", msg=f"{state.positions=} {limitka_qty=} {state.vars.limitka_price=}", nastavenacena=state.vars.limitka_price, spravna_cena=get_limitka_price(), pos=state.positions, limitka_qty=limitka_qty)
|
||||
#snad to nespadne, kdyztak pridat exception handling
|
||||
puvodni = state.vars.limitka
|
||||
#TBD zde odchytit nejak result
|
||||
state.vars.limitka = asyncio.run(state.interface.repl(price=get_limitka_price(), orderid=state.vars.limitka, size=int(state.positions)))
|
||||
|
||||
if state.vars.limitka == -1:
|
||||
state.ilog(e="Replace limitky neprobehl, vracime puvodni", msg=f"{state.vars.limitka=}", puvodni=puvodni)
|
||||
state.vars.limitka = puvodni
|
||||
else:
|
||||
limitka_qty = int(state.positions)
|
||||
state.ilog(e="Změněna limitka", limitka=str(state.vars.limitka), limitka_price=state.vars.limitka_price, limitka_qty=limitka_qty)
|
||||
|
||||
#tbd pokud se bude vyskytovat pak pridat ještě konzolidaci ceny limitky
|
||||
|
||||
if pendingbuys_new != state.vars.pendingbuys:
|
||||
state.ilog(e="Rozdilna PB prepsana", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys)
|
||||
print("ROZDILNA PENDINGBUYS přepsána")
|
||||
print("OLD",state.vars.pendingbuys)
|
||||
state.vars.pendingbuys = unpackb(packb(pendingbuys_new))
|
||||
print("NEW", state.vars.pendingbuys)
|
||||
else:
|
||||
print("PENDINGBUYS sedí - necháváme", state.vars.pendingbuys)
|
||||
state.ilog(e="PB sedi nechavame", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys)
|
||||
print("OLD jevylozeno", state.vars.jevylozeno)
|
||||
if len(state.vars.pendingbuys) > 0:
|
||||
state.vars.jevylozeno = 1
|
||||
else:
|
||||
state.vars.jevylozeno = 0
|
||||
print("NEW jevylozeno", state.vars.jevylozeno)
|
||||
state.ilog(e="Nove jevylozeno", msg=state.vars.jevylozeno)
|
||||
|
||||
#print(limitka)
|
||||
#print(pendingbuys_new)
|
||||
#print(pendingbuys)
|
||||
#print(len(pendingbuys))
|
||||
#print(len(pendingbuys_new))
|
||||
#print(jevylozeno)
|
||||
print("***CONSOLIDATION EXIT***")
|
||||
state.ilog(e="CONSOLIDATION EXIT ***")
|
||||
else:
|
||||
state.ilog(e="No time for consolidation", msg=data["index"])
|
||||
print("no time for consolidation", data["index"])
|
||||
|
||||
#mozna presunout o level vys
|
||||
def vyloz():
|
||||
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
|
||||
#curve = [0.01, 0.01, 0, 0, 0.01, 0, 0, 0, 0.02, 0, 0, 0, 0.03, 0,0,0,0,0, 0.02, 0,0,0,0,0,0, 0.02]
|
||||
curve = state.vars.curve
|
||||
##defenzivni krivka pro
|
||||
curve_def = state.vars.curve_def
|
||||
#vykladani po 5ti kusech, když zbývají 2 a méně, tak děláme nový výklad
|
||||
vykladka = state.vars.vykladka
|
||||
#kolik muzu max vylozit
|
||||
kolikmuzu = int((int(state.vars.maxpozic) - int(state.positions))/int(state.vars.chunk))
|
||||
akt_pozic = int(state.positions)
|
||||
max_pozic = int(state.vars.maxpozic)
|
||||
|
||||
#mame polovinu a vic vylozeno, pouzivame defenzicni krivku
|
||||
if is_defensive_mode():
|
||||
state.ilog(e="DEF: Pouzivame defenzivni krivku", akt_pozic=akt_pozic, max_pozic=max_pozic, curve_def=curve_def)
|
||||
curve = curve_def
|
||||
#zaroven docasne menime ticks2reset na defenzivni 0.06
|
||||
state.vars.ticks2reset = 0.06
|
||||
state.ilog(e="DEF: Menime tick2reset na 0.06", ticks2reset=state.vars.ticks2reset, ticks2reset_backup=state.vars.ticks2reset_backup)
|
||||
else:
|
||||
#vracime zpet, pokud bylo zmeneno
|
||||
if state.vars.ticks2reset != state.vars.ticks2reset_backup:
|
||||
state.vars.ticks2reset = state.vars.ticks2reset_backup
|
||||
state.ilog(e="DEF: Menime tick2reset zpet na"+str(state.vars.ticks2reset), ticks2reset=state.vars.ticks2reset, ticks2reset_backup=state.vars.ticks2reset_backup)
|
||||
|
||||
if kolikmuzu < vykladka: vykladka = kolikmuzu
|
||||
|
||||
if len(curve) < vykladka:
|
||||
vykladka = len(curve)
|
||||
qty = int(state.vars.chunk)
|
||||
last_price = price2dec(state.interface.get_last_price(state.symbol))
|
||||
#profit = float(state.vars.profit)
|
||||
price = last_price
|
||||
state.ilog(e="BUY Vykladame", msg=f"first price {price=} {vykladka=}", curve=curve, ema=state.indicators.ema[-1], trend=state.vars.Trend, price=price, vykladka=vykladka)
|
||||
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
|
||||
|
||||
##VAR - na zaklade conf. muzeme jako prvni posilat MARKET order
|
||||
if safe_get(state.vars, "first_buy_market") == True:
|
||||
#pri defenzivnim rezimu pouzivame vzdy LIMIT order
|
||||
if is_defensive_mode():
|
||||
state.ilog(e="DEF mode on, odesilame jako prvni limitku")
|
||||
state.buy_l(price=price, size=qty)
|
||||
else:
|
||||
state.ilog(e="Posilame jako prvni MARKET order")
|
||||
state.buy(size=qty)
|
||||
else:
|
||||
state.buy_l(price=price, size=qty)
|
||||
print("prvni limitka na aktuální cenu. Další podle křivky", price, qty)
|
||||
for i in range(0,vykladka-1):
|
||||
price = price2dec(float(price - curve[i]))
|
||||
if price == last_price:
|
||||
qty = qty + int(state.vars.chunk)
|
||||
else:
|
||||
state.buy_l(price=price, size=qty)
|
||||
#print(i,"BUY limitka - delta",curve[i]," cena:", price, "mnozstvi:", qty)
|
||||
qty = int(state.vars.chunk)
|
||||
last_price = price
|
||||
state.vars.blockbuy = 1
|
||||
state.vars.jevylozeno = 1
|
||||
|
||||
#CBAR protection, only 1x order per CBAR - then wait until another confirmed bar
|
||||
if state.vars.blockbuy == 1 and state.rectype == RecordType.CBAR:
|
||||
if state.bars.confirmed[-1] == 0:
|
||||
print("OCHR: multibuy protection. waiting for next bar")
|
||||
return 0
|
||||
# pop potvrzeni jeste jednou vratime (aby se nekoupilo znova, je stale ten stejny bar)
|
||||
# a pak dalsi vejde az po minticku
|
||||
else:
|
||||
# pro vykladaci
|
||||
state.vars.blockbuy = 0
|
||||
return 0
|
||||
|
||||
state.ilog(e="-----")
|
||||
|
||||
#EMA INDICATOR -
|
||||
#plnime MAcko - nyni posilame jen N poslednich hodnot
|
||||
#zaroven osetrujeme pripady, kdy je malo dat a ukladame nulu
|
||||
try:
|
||||
ma = int(state.vars.MA)
|
||||
#poslednich ma hodnot
|
||||
source = state.bars.close[-ma:] #state.bars.vwap
|
||||
ema_value = ema(source, ma)
|
||||
state.indicators.ema[-1]=trunc(ema_value[-1],3)
|
||||
except Exception as e:
|
||||
state.ilog(e="EMA ukladame 0", message=str(e)+format_exc())
|
||||
#state.indicators.ema[-1]=0
|
||||
|
||||
#EMA SLOW
|
||||
try:
|
||||
ma = 100
|
||||
#poslednich ma hodnot
|
||||
source = state.bars.hlcc4[-ma:] #state.bars.vwap
|
||||
emaSlow_value = ema(source, ma)
|
||||
emaSlow = trunc(emaSlow_value[-1],3)
|
||||
state.indicators.emaSlow[-1]=emaSlow
|
||||
state.ilog(e=f"emaSlow {emaSlow=}", emaSlow=state.indicators.emaSlow[-5:])
|
||||
except Exception as e:
|
||||
state.ilog(e=f"emaSlow {ma=} ukladame 0", message=str(e)+format_exc())
|
||||
#state.indicators.emaSlow.append(0)
|
||||
|
||||
|
||||
#EMA FAST
|
||||
try:
|
||||
ma = 20
|
||||
#poslednich ma hodnot
|
||||
source = state.bars.hlcc4[-ma:] #state.bars.vwap
|
||||
emaFast_value = ema(source, ma)
|
||||
emaFast = trunc(emaFast_value[-1],3)
|
||||
state.indicators.emaFast[-1]=emaFast
|
||||
state.ilog(e=f"emaFast {emaFast=}", emaFast=state.indicators.emaFast[-5:])
|
||||
except Exception as e:
|
||||
state.ilog(e=f"emaFast {ma=} ukladame 0", message=str(e)+format_exc())
|
||||
#state.indicators.emaFast.append(0)
|
||||
|
||||
|
||||
#RSI14
|
||||
try:
|
||||
rsi_length = 14
|
||||
#poslednich ma hodnot
|
||||
source = state.bars.close #[-rsi_length:] #state.bars.vwap
|
||||
rsi_res = rsi(source, rsi_length)
|
||||
rsi_value = trunc(rsi_res[-1],3)
|
||||
state.indicators.RSI14.append(rsi_value)
|
||||
state.ilog(e=f"RSI {rsi_length=} {rsi_value=}", rsi_indicator=state.indicators.RSI14[-5:])
|
||||
except Exception as e:
|
||||
state.ilog(e=f"RSI {rsi_length=} ukladame 0", message=str(e)+format_exc())
|
||||
state.indicators.RSI14.append(0)
|
||||
|
||||
#stoch
|
||||
try:
|
||||
stoch_length = 14
|
||||
#poslednich ma hodnot
|
||||
source_high = state.bars.high #[-rsi_length:] #state.bars.vwap
|
||||
source_low = state.bars.low
|
||||
source_close=state.bars.close
|
||||
stoch_res1, stoch_res2 = stochastic_oscillator(source_high, source_low, source_close)
|
||||
stoch_value1 = trunc(stoch_res1[-1],3)
|
||||
stoch_value2 = trunc(stoch_res2[-1],3)
|
||||
state.indicators.stoch1.append(stoch_value1)
|
||||
state.indicators.stoch2.append(stoch_value2)
|
||||
state.ilog(e=f"stoch {stoch_value1=} {stoch_value2=}", stoch1=state.indicators.stoch1[-5:], stoch2=state.indicators.stoch2[-5:])
|
||||
except Exception as e:
|
||||
state.ilog(e=f"stoch ukladame 0", message=str(e)+format_exc())
|
||||
state.indicators.stoch1.append(0)
|
||||
state.indicators.stoch2.append(0)
|
||||
|
||||
|
||||
#absolute price oscillator
|
||||
#meri mezeru mezi dvemi MACky (ato bud absolut price nebo percentage)
|
||||
try:
|
||||
short = 1
|
||||
long = 20
|
||||
#poslednich ma hodnot
|
||||
source = state.bars.close #[-rsi_length:] #state.bars.vwap
|
||||
apo_res = absolute_price_oscillator(source, short,long)
|
||||
apo_value = trunc(apo_res[-1],3)
|
||||
state.indicators.apo.append(apo_value)
|
||||
state.ilog(e=f"apo {apo_value=}", apo_indicator=state.indicators.apo[-5:])
|
||||
except Exception as e:
|
||||
state.ilog(e=f"apo ukladame 0", message=str(e)+format_exc())
|
||||
state.indicators.apo.append(0)
|
||||
|
||||
#percentage price oscillator
|
||||
try:
|
||||
short = 1
|
||||
long = 20
|
||||
#poslednich ma hodnot
|
||||
source = state.bars.close #[-rsi_length:] #state.bars.vwap
|
||||
ppo_res = percentage_price_oscillator(source, short,long)
|
||||
ppo_value = trunc(ppo_res[-1],3)
|
||||
state.indicators.ppo.append(ppo_value)
|
||||
state.ilog(e=f"poo {ppo_value=}", ppo_indicator=state.indicators.ppo[-5:])
|
||||
except Exception as e:
|
||||
state.ilog(e=f"ppo ukladame 0", message=str(e)+format_exc())
|
||||
state.indicators.ppo.append(0)
|
||||
|
||||
|
||||
#SLOPE INDICATOR
|
||||
#úhel stoupání a klesání vyjádřený mezi -1 až 1
|
||||
#pravý bod přímky je aktuální cena, levý je průměr X(lookback offset) starších hodnot od slope_lookback.
|
||||
#obsahuje statický indikátor (angle) pro vizualizaci
|
||||
try:
|
||||
slope = 99
|
||||
slope_lookback = int(state.vars.slope_lookback)
|
||||
minimum_slope = float(state.vars.minimum_slope)
|
||||
lookback_offset = int(state.vars.lookback_offset)
|
||||
|
||||
if len(state.bars.close) > (slope_lookback + lookback_offset):
|
||||
array_od = slope_lookback + lookback_offset
|
||||
array_do = slope_lookback
|
||||
lookbackprice_array = state.bars.vwap[-array_od:-array_do]
|
||||
#obycejný prumer hodnot
|
||||
lookbackprice = round(sum(lookbackprice_array)/lookback_offset,3)
|
||||
|
||||
#výpočet úhlu
|
||||
slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100
|
||||
slope = round(slope, 4)
|
||||
state.indicators.slope[-1]=slope
|
||||
|
||||
#angle je ze slope
|
||||
state.statinds.angle = dict(time=state.bars.time[-1], price=state.bars.close[-1], lookbacktime=state.bars.time[-slope_lookback], lookbackprice=lookbackprice, minimum_slope=minimum_slope)
|
||||
|
||||
#slope MA vyrovna vykyvy ve slope, dále pracujeme se slopeMA
|
||||
slope_MA_length = 5
|
||||
source = state.indicators.slope[-slope_MA_length:]
|
||||
slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap
|
||||
slopeMA = slopeMAseries[-1]
|
||||
state.indicators.slopeMA[-1]=slopeMA
|
||||
|
||||
state.ilog(e=f"{slope=} {slopeMA=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:])
|
||||
|
||||
#dale pracujeme s timto MAckovanym slope
|
||||
slope = slopeMA
|
||||
else:
|
||||
#pokud plnime historii musime ji plnit od zacatku, vsehcny idenitifkatory maji spolecny time
|
||||
#kvuli spravnemu zobrazovani na gui
|
||||
#state.indicators.slopeMA[-1]=0
|
||||
#state.indicators.slopeMA.append(0)
|
||||
state.ilog(e="Slope - not enough data", slope_lookback=slope_lookback, slope=state.indicators.slope, slopeMA=state.indicators.slopeMA)
|
||||
except Exception as e:
|
||||
print("Exception in NEXT Slope Indicator section", str(e))
|
||||
state.ilog(e="EXCEPTION", msg="Exception in Slope Indicator section" + str(e) + format_exc())
|
||||
|
||||
print("is falling",isfalling(state.indicators.ema,state.vars.Trend))
|
||||
print("is rising",isrising(state.indicators.ema,state.vars.Trend))
|
||||
|
||||
consolidation()
|
||||
|
||||
#HLAVNI ITERACNI LOG JESTE PRED AKCI - obsahuje aktualni hodnoty vetsiny parametru
|
||||
lp = state.interface.get_last_price(symbol=state.symbol)
|
||||
state.ilog(e="ENTRY", msg=f"LP:{lp} P:{state.positions}/{round(float(state.avgp),3)} profit:{round(float(state.profit),2)} Trades:{len(state.tradeList)} DEF:{str(is_defensive_mode())}", last_price=lp, data=data, stratvars=state.vars)
|
||||
|
||||
#SLOPE ANGLE PROTECTIONs
|
||||
#slope zachycuje rychle sestupy, pripadne zrusi nakupni objednavky
|
||||
if slope < minimum_slope: # or slopeMA<maxSlopeMA:
|
||||
print("OCHRANA SLOPE TOO HIGH")
|
||||
# if slopeMA<maxSlopeMA:
|
||||
# state.ilog(e="Slope MA too high "+str(slopeMA)+" max:"+str(maxSlopeMA))
|
||||
state.ilog(e=f"Slope too high {slope}")
|
||||
if len(state.vars.pendingbuys)>0:
|
||||
print("CANCEL PENDINGBUYS")
|
||||
#ic(state.vars.pendingbuys)
|
||||
res = asyncio.run(state.cancel_pending_buys())
|
||||
#ic(state.vars.pendingbuys)
|
||||
state.ilog(e="Rusime pendingbuyes", pb=state.vars.pendingbuys, res=res)
|
||||
print("slope", slope)
|
||||
print("min slope", minimum_slope)
|
||||
|
||||
if state.vars.jevylozeno == 0:
|
||||
print("Neni vylozeno, muzeme testovat nakup")
|
||||
|
||||
#pokud je defenziva, buy triggeruje defenzivni def_trend
|
||||
#TBD
|
||||
|
||||
|
||||
if isfalling(state.indicators.ema,state.vars.Trend) and slope > minimum_slope:
|
||||
vyloz()
|
||||
|
||||
if state.vars.jevylozeno == 1:
|
||||
#pokud mame vylozeno a cena je vetsi nez tick2reset
|
||||
if len(state.vars.pendingbuys)>0:
|
||||
maxprice = max(state.vars.pendingbuys.values())
|
||||
print("max cena v orderbuys", maxprice)
|
||||
if state.interface.get_last_price(state.symbol) > float(maxprice) + float(state.vars.ticks2reset):
|
||||
##TODO toto nejak vymyslet - duplikovat?
|
||||
res = asyncio.run(state.cancel_pending_buys())
|
||||
state.ilog(e=f"UJELO to. Rusime PB", msg=f"{state.vars.ticks2reset=}", pb=state.vars.pendingbuys)
|
||||
|
||||
#PENDING BUYS SPENT - PART
|
||||
#pokud mame vylozeno a pendingbuys se vyklepou a
|
||||
# 1 vykladame idned znovu
|
||||
# vyloz()
|
||||
# 2 nebo - počkat zase na signál a pokračovat dál
|
||||
# state.vars.blockbuy = 0
|
||||
# state.vars.jevylozeno = 0
|
||||
# 3 nebo - počkat na signál s enablovaným lastbuy indexem (tzn. počká nutně ještě pár barů)
|
||||
#podle BT vyhodnejsi vylozit ihned
|
||||
if len(state.vars.pendingbuys) == 0:
|
||||
state.vars.blockbuy = 0
|
||||
state.vars.jevylozeno = 0
|
||||
state.ilog(e="PB se vyklepaly nastavujeme: neni vylozeno", jevylozeno=state.vars.jevylozeno)
|
||||
|
||||
#TODO toto dodelat konzolidaci a mozna lock na limitku a pendingbuys a jevylozeno ??
|
||||
|
||||
#kdykoliv se muze notifikace ztratit
|
||||
# - pendingbuys - vsechny open orders buy
|
||||
# - limitka - open order sell
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pokud je vylozeno a mame pozice a neexistuje limitka - pak ji vytvorim
|
||||
# if int(state.oe.poz)>0 and state.oe.limitka == 0:
|
||||
# #pro jistotu updatujeme pozice
|
||||
# state.oe.avgp, state.oe.poz = state.oe.pos()
|
||||
# if int(state.oe.poz) > 0:
|
||||
# cena = round(float(state.oe.avgp) + float(state.oe.stratvars["profit"]),2)
|
||||
# print("BUGF: limitka neni vytvarime, a to za cenu",cena,"mnozstvi",state.oe.poz)
|
||||
# print("aktuzalni ltp",ltp.price[state.oe.symbol])
|
||||
|
||||
# try:
|
||||
# state.oe.limitka = state.oe.sell_noasync(cena, state.oe.poz)
|
||||
# print("vytvorena limitka", state.oe.limitka)
|
||||
# except Exception as e:
|
||||
# print("Neslo vytvorit profitku. Problem,ale jedeme dal",str(e))
|
||||
# pass
|
||||
# ##raise Exception(e)
|
||||
|
||||
print(10*"*","NEXT STOP",10*"*")
|
||||
|
||||
def init(state: StrategyState):
|
||||
#place to declare new vars
|
||||
print("INIT v main",state.name)
|
||||
state.indicators['ema'] = []
|
||||
state.indicators['slope'] = []
|
||||
state.indicators['slopeMA'] = []
|
||||
state.indicators['emaSlow'] = []
|
||||
state.indicators['emaFast'] = []
|
||||
state.indicators['RSI14'] = []
|
||||
state.indicators['stoch1'] = []
|
||||
state.indicators['stoch2'] = []
|
||||
state.indicators['apo'] = []
|
||||
state.indicators['ppo'] = []
|
||||
#static indicators - those not series based
|
||||
state.statinds['angle'] = dict(minimum_slope=state.vars["minimum_slope"])
|
||||
state.vars["ticks2reset_backup"] = state.vars.ticks2reset
|
||||
|
||||
|
||||
521
v2realbot/archived/ENTRY_Vykladaci_RSI.py
Normal file
521
v2realbot/archived/ENTRY_Vykladaci_RSI.py
Normal file
@ -0,0 +1,521 @@
|
||||
import os,sys
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
from v2realbot.strategy.base import StrategyState
|
||||
from v2realbot.strategy.StrategyOrderLimitVykladaci import StrategyOrderLimitVykladaci
|
||||
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, OrderSide, OrderType
|
||||
from v2realbot.indicators.indicators import ema
|
||||
from v2realbot.indicators.oscillators import rsi
|
||||
from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY, price2dec, print, safe_get
|
||||
from datetime import datetime
|
||||
#from icecream import install, ic
|
||||
#from rich import print
|
||||
from threading import Event
|
||||
from msgpack import packb, unpackb
|
||||
import asyncio
|
||||
import os
|
||||
from traceback import format_exc
|
||||
|
||||
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
""""
|
||||
Kope Vykladaci strategie s navic pridanym RSI
|
||||
|
||||
- pokud RSI > 50
|
||||
- rusime pendingbuye
|
||||
- netriggerujeme buy
|
||||
|
||||
"""
|
||||
stratvars = AttributeDict(maxpozic = 400,
|
||||
def_mode_from = 200,
|
||||
chunk = 10,
|
||||
MA = 2,
|
||||
Trend = 2,
|
||||
profit = 0.02,
|
||||
def_profit = 0.01,
|
||||
lastbuyindex=-6,
|
||||
pendingbuys={},
|
||||
limitka = None,
|
||||
limitka_price = None,
|
||||
jevylozeno=0,
|
||||
vykladka=5,
|
||||
curve = [0.01, 0.01, 0.01, 0, 0.02, 0.02, 0.01,0.01, 0.01,0.03, 0.01, 0.01, 0.01,0.04, 0.01,0.01, 0.01,0.05, 0.01,0.01, 0.01,0.01, 0.06,0.01, 0.01,0.01, 0.01],
|
||||
curve_def = [0.02, 0.02, 0.02, 0, 0, 0.02, 0, 0, 0, 0.02],
|
||||
blockbuy = 0,
|
||||
ticks2reset = 0.04,
|
||||
consolidation_bar_count = 10,
|
||||
slope_lookback = 300,
|
||||
lookback_offset = 20,
|
||||
minimum_slope = -0.05,
|
||||
first_buy_market = False
|
||||
)
|
||||
##toto rozparsovat a strategii spustit stejne jako v main
|
||||
toml_string = """
|
||||
[[strategies]]
|
||||
name = "V1 na BAC"
|
||||
symbol = "BAC"
|
||||
script = "ENTRY_backtest_strategyVykladaci"
|
||||
class = "StrategyOrderLimitVykladaci"
|
||||
open_rush = 0
|
||||
close_rush = 0
|
||||
[strategies.stratvars]
|
||||
maxpozic = 200
|
||||
chunk = 10
|
||||
MA = 6
|
||||
Trend = 5
|
||||
profit = 0.02
|
||||
lastbuyindex=-6
|
||||
pendingbuys={}
|
||||
limitka = "None"
|
||||
jevylozeno=0
|
||||
vykladka=5
|
||||
curve = [0.01, 0.01, 0.01,0.01, 0.02, 0.01,0.01, 0.01,0.03, 0.01, 0.01, 0.01,0.04, 0.01,0.01, 0.01,0.05, 0.01,0.01, 0.01,0.01, 0.06,0.01, 0.01,0.01, 0.01]
|
||||
blockbuy = 0
|
||||
ticks2reset = 0.04
|
||||
[[strategies.add_data]]
|
||||
symbol="BAC"
|
||||
rectype="bar"
|
||||
timeframe=5
|
||||
update_ltp=true
|
||||
align="round"
|
||||
mintick=0
|
||||
minsize=100
|
||||
exthours=false
|
||||
"""
|
||||
|
||||
def next(data, state: StrategyState):
|
||||
print(10*"*","NEXT START",10*"*")
|
||||
#ic(state.avgp, state.positions)
|
||||
#ic(state.vars)
|
||||
#ic(data)
|
||||
|
||||
#
|
||||
def is_defensive_mode():
|
||||
akt_pozic = int(state.positions)
|
||||
max_pozic = int(state.vars.maxpozic)
|
||||
def_mode_from = safe_get(state.vars, "def_mode_from")
|
||||
if def_mode_from == None: def_mode_from = max_pozic/2
|
||||
if akt_pozic >= int(def_mode_from):
|
||||
state.ilog(e=f"DEFENSIVE mode ACTIVE {state.vars.def_mode_from=}", msg=state.positions)
|
||||
return True
|
||||
else:
|
||||
state.ilog(e=f"STANDARD mode ACTIVE {state.vars.def_mode_from=}", msg=state.positions)
|
||||
return False
|
||||
|
||||
def get_limitka_price():
|
||||
def_profit = safe_get(state.vars, "def_profit")
|
||||
if def_profit == None: def_profit = state.vars.profit
|
||||
if is_defensive_mode():
|
||||
return price2dec(float(state.avgp)+float(def_profit))
|
||||
else:
|
||||
return price2dec(float(state.avgp)+float(state.vars.profit))
|
||||
|
||||
def consolidation():
|
||||
##CONSOLIDATION PART - moved here, musí být před nákupem, jinak to dělalo nepořádek v pendingbuys
|
||||
#docasne zkusime konzolidovat i kdyz neni vylozeno (aby se srovnala limitka ve vsech situacich)
|
||||
if state.vars.jevylozeno == 1 or 1==1:
|
||||
##CONSOLIDATION PART kazdy Nty bar dle nastaveni
|
||||
if int(data["index"])%int(state.vars.consolidation_bar_count) == 0:
|
||||
print("***CONSOLIDATION ENTRY***")
|
||||
state.ilog(e="CONSOLIDATION ENTRY ***")
|
||||
|
||||
orderlist = state.interface.get_open_orders(symbol=state.symbol, side=None)
|
||||
#pro jistotu jeste dotahneme aktualni pozice
|
||||
state.avgp, state.positions = state.interface.pos()
|
||||
|
||||
#print(orderlist)
|
||||
pendingbuys_new = {}
|
||||
limitka_old = state.vars.limitka
|
||||
#print("Puvodni LIMITKA", limitka_old)
|
||||
#zaciname s cistym stitem
|
||||
state.vars.limitka = None
|
||||
state.vars.limitka_price = None
|
||||
limitka_found = False
|
||||
limitka_qty = 0
|
||||
limitka_filled_qty = 0
|
||||
for o in orderlist:
|
||||
if o.side == OrderSide.SELL:
|
||||
|
||||
if limitka_found:
|
||||
state.ilog(e="nalezeno vicero sell objednavek, bereme prvni, ostatni - rusime")
|
||||
result=state.interface.cancel(o.id)
|
||||
state.ilog(e="zrusena objednavka"+str(o.id), message=result)
|
||||
continue
|
||||
|
||||
#print("Nalezena LIMITKA")
|
||||
limitka_found = True
|
||||
state.vars.limitka = o.id
|
||||
state.vars.limitka_price = o.limit_price
|
||||
limitka_qty = int(o.qty)
|
||||
limitka_filled_qty = int(o.filled_qty)
|
||||
|
||||
#aktualni mnozstvi = puvodni minus filled
|
||||
if limitka_filled_qty is not None:
|
||||
print("prepocitavam filledmnozstvi od limitka_qty a filled_qty", limitka_qty, limitka_filled_qty)
|
||||
limitka_qty = int(limitka_qty) - int(limitka_filled_qty)
|
||||
##TODO sem pridat upravu ceny
|
||||
if o.side == OrderSide.BUY and o.order_type == OrderType.LIMIT:
|
||||
pendingbuys_new[str(o.id)]=float(o.limit_price)
|
||||
|
||||
state.ilog(e="Konzolidace limitky", msg=f"stejna:{(str(limitka_old)==str(state.vars.limitka))}", limitka_old=str(limitka_old), limitka_new=str(state.vars.limitka), limitka_new_price=state.vars.limitka_price, limitka_qty=limitka_qty, limitka_filled_qty=limitka_filled_qty)
|
||||
|
||||
#pokud mame
|
||||
|
||||
#neni limitka, ale mela by byt - vytváříme ji
|
||||
if int(state.positions) > 0 and state.vars.limitka is None:
|
||||
state.ilog(e="Limitka neni, ale mela by být.", msg=f"{state.positions=}")
|
||||
price=get_limitka_price()
|
||||
state.vars.limitka = asyncio.run(state.interface.sell_l(price=price, size=int(state.positions)))
|
||||
state.vars.limitka_price = price
|
||||
if state.vars.limitka == -1:
|
||||
state.ilog(e="Vytvoreni limitky neprobehlo, vracime None", msg=f"{state.vars.limitka=}")
|
||||
state.vars.limitka = None
|
||||
state.vars.limitka_price = None
|
||||
else:
|
||||
state.ilog(e="Vytvořena nová limitka", limitka=str(state.vars.limitka), limtka_price=state.vars.limitka_price, qty=state.positions)
|
||||
|
||||
#existuje a nesedi mnozstvi nebo cena
|
||||
elif state.vars.limitka is not None and int(state.positions) > 0 and ((int(state.positions) != int(limitka_qty)) or float(state.vars.limitka_price) != float(get_limitka_price())):
|
||||
#limitka existuje, ale spatne mnostvi - updatujeme
|
||||
state.ilog(e=f"Limitka existuje, ale spatne mnozstvi nebo CENA - updatujeme", msg=f"{state.positions=} {limitka_qty=} {state.vars.limitka_price=}", nastavenacena=state.vars.limitka_price, spravna_cena=get_limitka_price(), pos=state.positions, limitka_qty=limitka_qty)
|
||||
#snad to nespadne, kdyztak pridat exception handling
|
||||
puvodni = state.vars.limitka
|
||||
#TBD zde odchytit nejak result
|
||||
state.vars.limitka = asyncio.run(state.interface.repl(price=get_limitka_price(), orderid=state.vars.limitka, size=int(state.positions)))
|
||||
|
||||
if state.vars.limitka == -1:
|
||||
state.ilog(e="Replace limitky neprobehl, vracime puvodni", msg=f"{state.vars.limitka=}", puvodni=puvodni)
|
||||
state.vars.limitka = puvodni
|
||||
else:
|
||||
limitka_qty = int(state.positions)
|
||||
state.ilog(e="Změněna limitka", limitka=str(state.vars.limitka), limitka_price=state.vars.limitka_price, limitka_qty=limitka_qty)
|
||||
|
||||
#tbd pokud se bude vyskytovat pak pridat ještě konzolidaci ceny limitky
|
||||
|
||||
if pendingbuys_new != state.vars.pendingbuys:
|
||||
state.ilog(e="Rozdilna PB prepsana", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys)
|
||||
print("ROZDILNA PENDINGBUYS přepsána")
|
||||
print("OLD",state.vars.pendingbuys)
|
||||
state.vars.pendingbuys = unpackb(packb(pendingbuys_new))
|
||||
print("NEW", state.vars.pendingbuys)
|
||||
else:
|
||||
print("PENDINGBUYS sedí - necháváme", state.vars.pendingbuys)
|
||||
state.ilog(e="PB sedi nechavame", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys)
|
||||
print("OLD jevylozeno", state.vars.jevylozeno)
|
||||
if len(state.vars.pendingbuys) > 0:
|
||||
state.vars.jevylozeno = 1
|
||||
else:
|
||||
state.vars.jevylozeno = 0
|
||||
print("NEW jevylozeno", state.vars.jevylozeno)
|
||||
state.ilog(e="Nove jevylozeno", msg=state.vars.jevylozeno)
|
||||
|
||||
#print(limitka)
|
||||
#print(pendingbuys_new)
|
||||
#print(pendingbuys)
|
||||
#print(len(pendingbuys))
|
||||
#print(len(pendingbuys_new))
|
||||
#print(jevylozeno)
|
||||
print("***CONSOLIDATION EXIT***")
|
||||
state.ilog(e="CONSOLIDATION EXIT ***")
|
||||
else:
|
||||
state.ilog(e="No time for consolidation", msg=data["index"])
|
||||
print("no time for consolidation", data["index"])
|
||||
|
||||
#mozna presunout o level vys
|
||||
def vyloz():
|
||||
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
|
||||
#curve = [0.01, 0.01, 0, 0, 0.01, 0, 0, 0, 0.02, 0, 0, 0, 0.03, 0,0,0,0,0, 0.02, 0,0,0,0,0,0, 0.02]
|
||||
curve = state.vars.curve
|
||||
##defenzivni krivka pro
|
||||
curve_def = state.vars.curve_def
|
||||
#vykladani po 5ti kusech, když zbývají 2 a méně, tak děláme nový výklad
|
||||
vykladka = state.vars.vykladka
|
||||
#kolik muzu max vylozit
|
||||
kolikmuzu = int((int(state.vars.maxpozic) - int(state.positions))/int(state.vars.chunk))
|
||||
akt_pozic = int(state.positions)
|
||||
max_pozic = int(state.vars.maxpozic)
|
||||
|
||||
#mame polovinu a vic vylozeno, pouzivame defenzicni krivku
|
||||
if is_defensive_mode():
|
||||
state.ilog(e="DEF: Pouzivame defenzivni krivku", akt_pozic=akt_pozic, max_pozic=max_pozic, curve_def=curve_def)
|
||||
curve = curve_def
|
||||
#zaroven docasne menime ticks2reset na defenzivni 0.06
|
||||
state.vars.ticks2reset = 0.06
|
||||
state.ilog(e="DEF: Menime tick2reset na 0.06", ticks2reset=state.vars.ticks2reset, ticks2reset_backup=state.vars.ticks2reset_backup)
|
||||
else:
|
||||
#vracime zpet, pokud bylo zmeneno
|
||||
if state.vars.ticks2reset != state.vars.ticks2reset_backup:
|
||||
state.vars.ticks2reset = state.vars.ticks2reset_backup
|
||||
state.ilog(e="DEF: Menime tick2reset zpet na"+str(state.vars.ticks2reset), ticks2reset=state.vars.ticks2reset, ticks2reset_backup=state.vars.ticks2reset_backup)
|
||||
|
||||
if kolikmuzu < vykladka: vykladka = kolikmuzu
|
||||
|
||||
if len(curve) < vykladka:
|
||||
vykladka = len(curve)
|
||||
qty = int(state.vars.chunk)
|
||||
last_price = price2dec(state.interface.get_last_price(state.symbol))
|
||||
#profit = float(state.vars.profit)
|
||||
price = last_price
|
||||
state.ilog(e="BUY Vykladame", msg=f"first price {price=} {vykladka=}", curve=curve, ema=state.indicators.ema[-1], trend=state.vars.Trend, price=price, vykladka=vykladka)
|
||||
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
|
||||
|
||||
##VAR - na zaklade conf. muzeme jako prvni posilat MARKET order
|
||||
if safe_get(state.vars, "first_buy_market") == True:
|
||||
#pri defenzivnim rezimu pouzivame vzdy LIMIT order
|
||||
if is_defensive_mode():
|
||||
state.ilog(e="DEF mode on, odesilame jako prvni limitku")
|
||||
state.buy_l(price=price, size=qty)
|
||||
else:
|
||||
state.ilog(e="Posilame jako prvni MARKET order")
|
||||
state.buy(size=qty)
|
||||
else:
|
||||
state.buy_l(price=price, size=qty)
|
||||
print("prvni limitka na aktuální cenu. Další podle křivky", price, qty)
|
||||
for i in range(0,vykladka-1):
|
||||
price = price2dec(float(price - curve[i]))
|
||||
if price == last_price:
|
||||
qty = qty + int(state.vars.chunk)
|
||||
else:
|
||||
state.buy_l(price=price, size=qty)
|
||||
#print(i,"BUY limitka - delta",curve[i]," cena:", price, "mnozstvi:", qty)
|
||||
qty = int(state.vars.chunk)
|
||||
last_price = price
|
||||
state.vars.blockbuy = 1
|
||||
state.vars.jevylozeno = 1
|
||||
|
||||
#CBAR protection, only 1x order per CBAR - then wait until another confirmed bar
|
||||
if state.vars.blockbuy == 1 and state.rectype == RecordType.CBAR:
|
||||
if state.bars.confirmed[-1] == 0:
|
||||
print("OCHR: multibuy protection. waiting for next bar")
|
||||
return 0
|
||||
# pop potvrzeni jeste jednou vratime (aby se nekoupilo znova, je stale ten stejny bar)
|
||||
# a pak dalsi vejde az po minticku
|
||||
else:
|
||||
# pro vykladaci
|
||||
state.vars.blockbuy = 0
|
||||
return 0
|
||||
|
||||
state.ilog(e="-----")
|
||||
|
||||
#EMA INDICATOR -
|
||||
#plnime MAcko - nyni posilame jen N poslednich hodnot
|
||||
#zaroven osetrujeme pripady, kdy je malo dat a ukladame nulu
|
||||
try:
|
||||
ma = int(state.vars.MA)
|
||||
#poslednich ma hodnot
|
||||
source = state.bars.close[-ma:] #state.bars.vwap
|
||||
ema_value = ema(source, ma)
|
||||
state.indicators.ema[-1]=trunc(ema_value[-1],3)
|
||||
except Exception as e:
|
||||
state.ilog(e="EMA ukladame 0", message=str(e)+format_exc())
|
||||
state.indicators.ema[-1]=0
|
||||
|
||||
#RSI14 INDICATOR
|
||||
try:
|
||||
##mame v atributech nastaveni?
|
||||
rsi_dont_buy_above = safe_get(state.vars, "rsi_dont_buy_above")
|
||||
if rsi_dont_buy_above == None:
|
||||
rsi_dont_buy_above = 50
|
||||
rsi_buy_signal = False
|
||||
rsi_dont_buy = False
|
||||
rsi_length = 14
|
||||
source = state.bars.close #[-rsi_length:] #state.bars.vwap
|
||||
rsi_res = rsi(source, rsi_length)
|
||||
rsi_value = trunc(rsi_res[-1],3)
|
||||
state.indicators.RSI14[-1]=rsi_value
|
||||
rsi_dont_buy = rsi_value > rsi_dont_buy_above
|
||||
rsi_buy_signal = rsi_value < 40
|
||||
state.ilog(e=f"RSI {rsi_length=} {rsi_value=} {rsi_dont_buy=} {rsi_buy_signal=}", rsi_indicator=state.indicators.RSI14[-5:])
|
||||
except Exception as e:
|
||||
state.ilog(e=f"RSI {rsi_length=} ukladame 0", message=str(e)+format_exc())
|
||||
#state.indicators.RSI14.append(0)
|
||||
|
||||
|
||||
#SLOPE INDICATOR
|
||||
#úhel stoupání a klesání vyjádřený mezi -1 až 1
|
||||
#pravý bod přímky je aktuální cena, levý je průměr X(lookback offset) starších hodnot od slope_lookback.
|
||||
#obsahuje statický indikátor (angle) pro vizualizaci
|
||||
try:
|
||||
slope = 99
|
||||
slope_lookback = int(state.vars.slope_lookback)
|
||||
minimum_slope = float(state.vars.minimum_slope)
|
||||
lookback_offset = int(state.vars.lookback_offset)
|
||||
|
||||
if len(state.bars.close) > (slope_lookback + lookback_offset):
|
||||
array_od = slope_lookback + lookback_offset
|
||||
array_do = slope_lookback
|
||||
lookbackprice_array = state.bars.vwap[-array_od:-array_do]
|
||||
#obycejný prumer hodnot
|
||||
lookbackprice = round(sum(lookbackprice_array)/lookback_offset,3)
|
||||
|
||||
#výpočet úhlu
|
||||
slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100
|
||||
slope = round(slope, 4)
|
||||
state.indicators.slope[-1]=slope
|
||||
|
||||
#angle je ze slope
|
||||
state.statinds.angle = dict(time=state.bars.time[-1], price=state.bars.close[-1], lookbacktime=state.bars.time[-slope_lookback], lookbackprice=lookbackprice, minimum_slope=minimum_slope)
|
||||
|
||||
#slope MA vyrovna vykyvy ve slope, dále pracujeme se slopeMA
|
||||
slope_MA_length = 5
|
||||
source = state.indicators.slope[-slope_MA_length:]
|
||||
slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap
|
||||
slopeMA = slopeMAseries[-1]
|
||||
state.indicators.slopeMA[-1]=slopeMA
|
||||
|
||||
state.ilog(e=f"{slope=} {slopeMA=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:], last_slopesMA=state.indicators.slopeMA[-10:])
|
||||
|
||||
#dale pracujeme s timto MAckovanym slope
|
||||
slope = slopeMA
|
||||
else:
|
||||
#pokud plnime historii musime ji plnit od zacatku, vsehcny idenitifkatory maji spolecny time
|
||||
#kvuli spravnemu zobrazovani na gui
|
||||
#state.indicators.slopeMA[-1]=0
|
||||
#state.indicators.slopeMA.append(0)
|
||||
state.ilog(e="Slope - not enough data", slope_lookback=slope_lookback, slope=state.indicators.slope, slopeMA=state.indicators.slopeMA)
|
||||
except Exception as e:
|
||||
print("Exception in NEXT Slope Indicator section", str(e))
|
||||
state.ilog(e="EXCEPTION", msg="Exception in Slope Indicator section" + str(e) + format_exc())
|
||||
|
||||
print("is falling",isfalling(state.indicators.ema,state.vars.Trend))
|
||||
print("is rising",isrising(state.indicators.ema,state.vars.Trend))
|
||||
|
||||
consolidation()
|
||||
|
||||
#HLAVNI ITERACNI LOG JESTE PRED AKCI - obsahuje aktualni hodnoty vetsiny parametru
|
||||
#TODO sem pridat aktualni hodnoty vsech indikatoru
|
||||
lp = state.interface.get_last_price(symbol=state.symbol)
|
||||
state.ilog(e="ENTRY", msg=f"LP:{lp} P:{state.positions}/{round(float(state.avgp),3)} profit:{round(float(state.profit),2)} Trades:{len(state.tradeList)} DEF:{str(is_defensive_mode())}", last_price=lp, data=data, stratvars=state.vars)
|
||||
|
||||
#SLOPE ANGLE PROTECTIONs
|
||||
#slope zachycuje rychle sestupy, pripadne zrusi nakupni objednavky
|
||||
if slope < minimum_slope or rsi_dont_buy: # or slopeMA<maxSlopeMA:
|
||||
print("OCHRANA SLOPE or RSI TOO HIGH")
|
||||
# if slopeMA<maxSlopeMA:
|
||||
# state.ilog(e="Slope MA too high "+str(slopeMA)+" max:"+str(maxSlopeMA))
|
||||
state.ilog(e=f"Slope or RSI too high {slope=} {rsi_value=}")
|
||||
if len(state.vars.pendingbuys)>0:
|
||||
print("CANCEL PENDINGBUYS")
|
||||
#ic(state.vars.pendingbuys)
|
||||
res = asyncio.run(state.cancel_pending_buys())
|
||||
#ic(state.vars.pendingbuys)
|
||||
state.ilog(e="Rusime pendingbuyes", pb=state.vars.pendingbuys, res=res)
|
||||
print("slope", slope)
|
||||
print("min slope", minimum_slope)
|
||||
|
||||
if state.vars.jevylozeno == 0:
|
||||
print("Neni vylozeno, muzeme testovat nakup")
|
||||
|
||||
#pokud je defenziva, buy triggeruje defenzivni def_trend
|
||||
#TBD
|
||||
|
||||
#NOVY BUY SIGNAL z RSI < 35
|
||||
#buy_signal = isfalling(state.indicators.ema,state.vars.Trend)
|
||||
buy_signal = rsi_buy_signal
|
||||
|
||||
if buy_signal and slope > minimum_slope and not rsi_dont_buy:
|
||||
vyloz()
|
||||
|
||||
## testuje aktualni cenu od nejvyssi visici limitky
|
||||
##toto spoustet jednou za X iterací - ted to jede pokazdé
|
||||
#pokud to ujede o vic, rusime limitky
|
||||
#TODO: zvazit jestli nechat i pri otevrenych pozicich, zatim nechavame
|
||||
#TODO int(int(state.oa.poz)/int(state.variables.chunk)) > X
|
||||
|
||||
#TODO predelat mechanismus ticků (zrelativizovat), aby byl pouzitelny na tituly s ruznou cenou
|
||||
#TODO spoustet 1x za X iteraci nebo cas
|
||||
if state.vars.jevylozeno == 1:
|
||||
#pokud mame vylozeno a cena je vetsi nez tick2reset
|
||||
if len(state.vars.pendingbuys)>0:
|
||||
maxprice = max(state.vars.pendingbuys.values())
|
||||
print("max cena v orderbuys", maxprice)
|
||||
if state.interface.get_last_price(state.symbol) > float(maxprice) + float(state.vars.ticks2reset):
|
||||
##TODO toto nejak vymyslet - duplikovat?
|
||||
res = asyncio.run(state.cancel_pending_buys())
|
||||
state.ilog(e=f"UJELO to. Rusime PB", msg=f"{state.vars.ticks2reset=}", pb=state.vars.pendingbuys)
|
||||
|
||||
#PENDING BUYS SPENT - PART
|
||||
#pokud mame vylozeno a pendingbuys se vyklepou a
|
||||
# 1 vykladame idned znovu
|
||||
# vyloz()
|
||||
# 2 nebo - počkat zase na signál a pokračovat dál
|
||||
# state.vars.blockbuy = 0
|
||||
# state.vars.jevylozeno = 0
|
||||
# 3 nebo - počkat na signál s enablovaným lastbuy indexem (tzn. počká nutně ještě pár barů)
|
||||
#podle BT vyhodnejsi vylozit ihned
|
||||
if len(state.vars.pendingbuys) == 0:
|
||||
state.vars.blockbuy = 0
|
||||
state.vars.jevylozeno = 0
|
||||
state.ilog(e="PB se vyklepaly nastavujeme: neni vylozeno", jevylozeno=state.vars.jevylozeno)
|
||||
|
||||
#TODO toto dodelat konzolidaci a mozna lock na limitku a pendingbuys a jevylozeno ??
|
||||
|
||||
#kdykoliv se muze notifikace ztratit
|
||||
# - pendingbuys - vsechny open orders buy
|
||||
# - limitka - open order sell
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pokud je vylozeno a mame pozice a neexistuje limitka - pak ji vytvorim
|
||||
# if int(state.oe.poz)>0 and state.oe.limitka == 0:
|
||||
# #pro jistotu updatujeme pozice
|
||||
# state.oe.avgp, state.oe.poz = state.oe.pos()
|
||||
# if int(state.oe.poz) > 0:
|
||||
# cena = round(float(state.oe.avgp) + float(state.oe.stratvars["profit"]),2)
|
||||
# print("BUGF: limitka neni vytvarime, a to za cenu",cena,"mnozstvi",state.oe.poz)
|
||||
# print("aktuzalni ltp",ltp.price[state.oe.symbol])
|
||||
|
||||
# try:
|
||||
# state.oe.limitka = state.oe.sell_noasync(cena, state.oe.poz)
|
||||
# print("vytvorena limitka", state.oe.limitka)
|
||||
# except Exception as e:
|
||||
# print("Neslo vytvorit profitku. Problem,ale jedeme dal",str(e))
|
||||
# pass
|
||||
# ##raise Exception(e)
|
||||
|
||||
print(10*"*","NEXT STOP",10*"*")
|
||||
|
||||
def init(state: StrategyState):
|
||||
#place to declare new vars
|
||||
print("INIT v main",state.name)
|
||||
state.indicators['ema'] = []
|
||||
state.indicators['slope'] = []
|
||||
state.indicators['slopeMA'] = []
|
||||
state.indicators['RSI14'] = []
|
||||
#static indicators - those not series based
|
||||
state.statinds['angle'] = dict(minimum_slope=state.vars["minimum_slope"])
|
||||
state.vars["ticks2reset_backup"] = state.vars.ticks2reset
|
||||
|
||||
def main():
|
||||
# try:
|
||||
# strat_settings = tomli.loads("]] this is invalid TOML [[")
|
||||
# except tomli.TOMLDecodeError:
|
||||
# print("Yep, definitely not valid.")
|
||||
|
||||
#strat_settings = dict_replace_value(strat_settings, "None", None)
|
||||
|
||||
name = os.path.basename(__file__)
|
||||
se = Event()
|
||||
pe = Event()
|
||||
s = StrategyOrderLimitVykladaci(name = name, symbol = "BAC", account=Account.ACCOUNT1, next=next, init=init, stratvars=stratvars, open_rush=10, close_rush=0, pe=pe, se=se, ilog_save=True)
|
||||
s.set_mode(mode = Mode.BT,
|
||||
debug = False,
|
||||
start = datetime(2023, 4, 14, 10, 42, 0, 0, tzinfo=zoneNY),
|
||||
end = datetime(2023, 4, 14, 14, 35, 0, 0, tzinfo=zoneNY),
|
||||
cash=100000)
|
||||
|
||||
#na sekundovem baru nezaokrouhlovat MAcko
|
||||
s.add_data(symbol="BAC",rectype=RecordType.BAR,timeframe=2,minsize=100,update_ltp=True,align=StartBarAlign.ROUND,mintick=0, exthours=False)
|
||||
#s.add_data(symbol="C",rectype=RecordType.BAR,timeframe=1,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=0)
|
||||
|
||||
s.start()
|
||||
print("zastavujeme")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
839
v2realbot/archived/ENTRY_Vykladaci_RSI_MYSELL.py
Normal file
839
v2realbot/archived/ENTRY_Vykladaci_RSI_MYSELL.py
Normal file
@ -0,0 +1,839 @@
|
||||
import os,sys
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
from v2realbot.strategy.base import StrategyState
|
||||
from v2realbot.strategy.StrategyOrderLimitVykladaciNormalizedMYSELL import StrategyOrderLimitVykladaciNormalizedMYSELL
|
||||
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, OrderSide, OrderType
|
||||
from v2realbot.indicators.indicators import ema
|
||||
from v2realbot.indicators.oscillators import rsi
|
||||
from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY, price2dec, print, safe_get, get_tick, round2five, is_open_rush, is_close_rush, eval_cond_dict, Average
|
||||
from datetime import datetime
|
||||
#from icecream import install, ic
|
||||
#from rich import print
|
||||
from threading import Event
|
||||
from msgpack import packb, unpackb
|
||||
import asyncio
|
||||
import os
|
||||
from traceback import format_exc
|
||||
|
||||
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
""""
|
||||
Využívá: StrategyOrderLimitVykladaciNormalizedMYSELL
|
||||
|
||||
Kopie RSI Normalizovane Vykladaci navíc s řízením prodeje.
|
||||
Nepoužíváme LIMITKU.
|
||||
|
||||
Required CBAR. (pouze se změnou ceny)
|
||||
|
||||
nepotvrzený CBAR bez minticku (pouze se změnou ceny)
|
||||
- se používá pro žízení prodeje
|
||||
|
||||
potvrzený CBAR
|
||||
- se používá pro BUY
|
||||
|
||||
|
||||
"""
|
||||
|
||||
stratvars = AttributeDict(maxpozic = 400,
|
||||
def_mode_from = 200,
|
||||
chunk = 10,
|
||||
MA = 2,
|
||||
Trend = 2,
|
||||
profit = 0.02,
|
||||
def_profit = 0.01,
|
||||
lastbuyindex=-6,
|
||||
pendingbuys={},
|
||||
limitka = None,
|
||||
limitka_price = None,
|
||||
jevylozeno=0,
|
||||
vykladka=5,
|
||||
curve = [0.01, 0.01, 0.01, 0, 0.02, 0.02, 0.01,0.01, 0.01,0.03, 0.01, 0.01, 0.01,0.04, 0.01,0.01, 0.01,0.05, 0.01,0.01, 0.01,0.01, 0.06,0.01, 0.01,0.01, 0.01],
|
||||
curve_def = [0.02, 0.02, 0.02, 0, 0, 0.02, 0, 0, 0, 0.02],
|
||||
blockbuy = 0,
|
||||
ticks2reset = 0.04,
|
||||
consolidation_bar_count = 10,
|
||||
slope_lookback = 300,
|
||||
lookback_offset = 20,
|
||||
minimum_slope = -0.05,
|
||||
first_buy_market = False
|
||||
)
|
||||
##toto rozparsovat a strategii spustit stejne jako v main
|
||||
toml_string = """
|
||||
[[strategies]]
|
||||
name = "V1 na BAC"
|
||||
symbol = "BAC"
|
||||
script = "ENTRY_backtest_strategyVykladaci"
|
||||
class = "StrategyOrderLimitVykladaci"
|
||||
open_rush = 0
|
||||
close_rush = 0
|
||||
[strategies.stratvars]
|
||||
maxpozic = 200
|
||||
chunk = 10
|
||||
MA = 6
|
||||
Trend = 5
|
||||
profit = 0.02
|
||||
lastbuyindex=-6
|
||||
pendingbuys={}
|
||||
limitka = "None"
|
||||
jevylozeno=0
|
||||
vykladka=5
|
||||
curve = [0.01, 0.01, 0.01,0.01, 0.02, 0.01,0.01, 0.01,0.03, 0.01, 0.01, 0.01,0.04, 0.01,0.01, 0.01,0.05, 0.01,0.01, 0.01,0.01, 0.06,0.01, 0.01,0.01, 0.01]
|
||||
blockbuy = 0
|
||||
ticks2reset = 0.04
|
||||
[[strategies.add_data]]
|
||||
symbol="BAC"
|
||||
rectype="bar"
|
||||
timeframe=5
|
||||
update_ltp=true
|
||||
align="round"
|
||||
mintick=0
|
||||
minsize=100
|
||||
exthours=false
|
||||
"""
|
||||
|
||||
def next(data, state: StrategyState):
|
||||
print(10*"*","NEXT START",10*"*")
|
||||
#ic(state.avgp, state.positions)
|
||||
#ic(state.vars)
|
||||
#ic(data)
|
||||
|
||||
#
|
||||
def is_defensive_mode():
|
||||
akt_pozic = int(state.positions)
|
||||
max_pozic = int(state.vars.maxpozic)
|
||||
def_mode_from = safe_get(state.vars, "def_mode_from",max_pozic/2)
|
||||
if akt_pozic >= int(def_mode_from):
|
||||
#state.ilog(e=f"DEFENSIVE mode ACTIVE {state.vars.def_mode_from=}", msg=state.positions)
|
||||
return True
|
||||
else:
|
||||
#state.ilog(e=f"STANDARD mode ACTIVE {state.vars.def_mode_from=}", msg=state.positions)
|
||||
return False
|
||||
|
||||
def get_profit_price():
|
||||
def_profit = safe_get(state.vars, "def_profit",state.vars.profit)
|
||||
cena = float(state.avgp)
|
||||
#v MYSELL hrajeme i na 3 desetinna cisla - TBD mozna hrat jen na 5ky (0.125, 0.130, 0.135 atp.)
|
||||
if is_defensive_mode():
|
||||
return price2dec(cena+get_tick(cena,float(def_profit)),3)
|
||||
else:
|
||||
return price2dec(cena+get_tick(cena,float(state.vars.profit)),3)
|
||||
|
||||
def get_max_profit_price():
|
||||
max_profit = float(safe_get(state.vars, "max_profit",0.03))
|
||||
cena = float(state.avgp)
|
||||
return price2dec(cena+get_tick(cena,max_profit),3)
|
||||
|
||||
def optimize_qty_multiplier():
|
||||
akt_pozic = int(state.positions)/int(state.vars.chunk)
|
||||
multiplier = 1
|
||||
|
||||
#zatim jednoduse pokud je akt. pozice 1 nebo 3 chunky (<4) tak zdvojnásubuju
|
||||
#aneb druhy a treti nakup
|
||||
if akt_pozic > 0 and akt_pozic < 4:
|
||||
multiplier = safe_get(state.vars, "market_buy_multiplier", 1)
|
||||
state.ilog(e=f"BUY MULTIPLIER: {multiplier}")
|
||||
return multiplier
|
||||
|
||||
|
||||
def consolidation():
|
||||
##CONSOLIDATION PART - moved here, musí být před nákupem, jinak to dělalo nepořádek v pendingbuys
|
||||
#docasne zkusime konzolidovat i kdyz neni vylozeno (aby se srovnala limitka ve vsech situacich)
|
||||
if state.vars.jevylozeno == 1 or 1==1:
|
||||
##CONSOLIDATION PART kazdy Nty bar dle nastaveni
|
||||
if int(data["index"])%int(state.vars.consolidation_bar_count) == 0:
|
||||
print("***CONSOLIDATION ENTRY***")
|
||||
state.ilog(e="CONSOLIDATION ENTRY ***")
|
||||
|
||||
orderlist = state.interface.get_open_orders(symbol=state.symbol, side=None)
|
||||
#pro jistotu jeste dotahneme aktualni pozice
|
||||
state.avgp, state.positions = state.interface.pos()
|
||||
|
||||
#print(orderlist)
|
||||
pendingbuys_new = {}
|
||||
#zaciname s cistym stitem
|
||||
state.vars.limitka = None
|
||||
state.vars.limitka_price = None
|
||||
for o in orderlist:
|
||||
if o.side == OrderSide.BUY and o.order_type == OrderType.LIMIT:
|
||||
pendingbuys_new[str(o.id)]=float(o.limit_price)
|
||||
|
||||
if pendingbuys_new != state.vars.pendingbuys:
|
||||
state.ilog(e="Rozdilna PB prepsana", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys)
|
||||
print("ROZDILNA PENDINGBUYS přepsána")
|
||||
print("OLD",state.vars.pendingbuys)
|
||||
state.vars.pendingbuys = unpackb(packb(pendingbuys_new))
|
||||
print("NEW", state.vars.pendingbuys)
|
||||
else:
|
||||
print("PENDINGBUYS sedí - necháváme", state.vars.pendingbuys)
|
||||
state.ilog(e="PB sedi nechavame", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys)
|
||||
print("OLD jevylozeno", state.vars.jevylozeno)
|
||||
if len(state.vars.pendingbuys) > 0:
|
||||
state.vars.jevylozeno = 1
|
||||
else:
|
||||
state.vars.jevylozeno = 0
|
||||
print("NEW jevylozeno", state.vars.jevylozeno)
|
||||
state.ilog(e="Nove jevylozeno", msg=state.vars.jevylozeno)
|
||||
|
||||
print("***CONSOLIDATION EXIT***")
|
||||
state.ilog(e="CONSOLIDATION EXIT ***")
|
||||
else:
|
||||
state.ilog(e="No time for consolidation", msg=data["index"])
|
||||
print("no time for consolidation", data["index"])
|
||||
#mozna presunout o level vys
|
||||
def vyloz():
|
||||
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
|
||||
#curve = [0.01, 0.01, 0, 0, 0.01, 0, 0, 0, 0.02, 0, 0, 0, 0.03, 0,0,0,0,0, 0.02, 0,0,0,0,0,0, 0.02]
|
||||
curve = state.vars.curve
|
||||
##defenzivni krivka pro
|
||||
curve_def = state.vars.curve_def
|
||||
#vykladani po 5ti kusech, když zbývají 2 a méně, tak děláme nový výklad
|
||||
vykladka = state.vars.vykladka
|
||||
#kolik muzu max vylozit
|
||||
kolikmuzu = int((int(state.vars.maxpozic) - int(state.positions))/int(state.vars.chunk))
|
||||
akt_pozic = int(state.positions)
|
||||
max_pozic = int(state.vars.maxpozic)
|
||||
|
||||
if akt_pozic >= max_pozic:
|
||||
state.ilog(e="MAX pozic reached, cannot vyklad")
|
||||
return
|
||||
|
||||
#mame polovinu a vic vylozeno, pouzivame defenzicni krivku
|
||||
if is_defensive_mode():
|
||||
state.ilog(e="DEF: Pouzivame defenzivni krivku", akt_pozic=akt_pozic, max_pozic=max_pozic, curve_def=curve_def)
|
||||
curve = curve_def
|
||||
#zaroven docasne menime ticks2reset na defenzivni 0.06
|
||||
state.vars.ticks2reset = 0.06
|
||||
state.ilog(e="DEF: Menime tick2reset na 0.06", ticks2reset=state.vars.ticks2reset, ticks2reset_backup=state.vars.ticks2reset_backup)
|
||||
else:
|
||||
#vracime zpet, pokud bylo zmeneno
|
||||
if state.vars.ticks2reset != state.vars.ticks2reset_backup:
|
||||
state.vars.ticks2reset = state.vars.ticks2reset_backup
|
||||
state.ilog(e="DEF: Menime tick2reset zpet na"+str(state.vars.ticks2reset), ticks2reset=state.vars.ticks2reset, ticks2reset_backup=state.vars.ticks2reset_backup)
|
||||
|
||||
if kolikmuzu < vykladka: vykladka = kolikmuzu
|
||||
|
||||
if len(curve) < vykladka:
|
||||
vykladka = len(curve)
|
||||
qty = int(state.vars.chunk)
|
||||
last_price = price2dec(state.interface.get_last_price(state.symbol))
|
||||
#profit = float(state.vars.profit)
|
||||
price = last_price
|
||||
state.ilog(e="BUY Vykladame", msg=f"first price {price=} {vykladka=}", curve=curve, ema=state.indicators.ema[-1], trend=state.vars.Trend, price=price, vykladka=vykladka)
|
||||
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
|
||||
|
||||
##VAR - na zaklade conf. muzeme jako prvni posilat MARKET order
|
||||
if safe_get(state.vars, "first_buy_market") == True:
|
||||
#pri defenzivnim rezimu pouzijeme LIMIT nebo MARKET podle nastaveni
|
||||
if is_defensive_mode() and safe_get(state.vars, "first_buy_market_def_mode", False) is False:
|
||||
state.ilog(e="DEF mode on, odesilame jako prvni limitku")
|
||||
state.buy_l(price=price, size=qty)
|
||||
else:
|
||||
state.ilog(e="Posilame jako prvni MARKET order")
|
||||
#market size optimalization based on conditions
|
||||
state.buy(size=optimize_qty_multiplier()*qty)
|
||||
else:
|
||||
state.buy_l(price=price, size=qty)
|
||||
print("prvni limitka na aktuální cenu. Další podle křivky", price, qty)
|
||||
for i in range(0,vykladka-1):
|
||||
price = price2dec(float(price - get_tick(price, curve[i])))
|
||||
if price == last_price:
|
||||
qty = qty + int(state.vars.chunk)
|
||||
else:
|
||||
state.buy_l(price=price, size=qty)
|
||||
#print(i,"BUY limitka - delta",curve[i]," cena:", price, "mnozstvi:", qty)
|
||||
qty = int(state.vars.chunk)
|
||||
last_price = price
|
||||
state.vars.blockbuy = 1
|
||||
state.vars.jevylozeno = 1
|
||||
state.vars.last_buysignal_index = data['index']
|
||||
|
||||
def eval_sell():
|
||||
""""
|
||||
TBD
|
||||
Když je RSI nahoře tak neprodávat, dokud 1) RSI neprestane stoupat 2)nedosahne to nad im not greedy limit
|
||||
"""
|
||||
##mame pozice
|
||||
##aktualni cena je vetsi nebo rovna cene limitky
|
||||
#muzeme zde jet i na pulcenty
|
||||
curr_price = float(data['close'])
|
||||
state.ilog(e="Eval SELL", price=curr_price, pos=state.positions, avgp=state.avgp, sell_in_progress=state.vars.sell_in_progress)
|
||||
if int(state.positions) > 0 and float(state.avgp)>0 and state.vars.sell_in_progress is False:
|
||||
goal_price = get_profit_price()
|
||||
max_price = get_max_profit_price()
|
||||
state.ilog(e=f"Goal price {goal_price} max price {max_price}")
|
||||
|
||||
#pokud je cena vyssi
|
||||
if curr_price>=goal_price:
|
||||
|
||||
#TODO cekat az slope prestane intenzivn erust, necekat az na klesani
|
||||
#TODO mozna cekat na nejaky signal RSI
|
||||
#TODO pripadne pokud dosahne TGTBB prodat ihned
|
||||
max_price_signal = curr_price>=max_price
|
||||
#OPTIMALIZACE pri stoupajícím angle
|
||||
if max_price_signal or sell_protection_enabled() is False:
|
||||
state.interface.sell(size=state.positions)
|
||||
state.vars.sell_in_progress = True
|
||||
state.ilog(e=f"market SELL was sent {curr_price=} {max_price_signal=}", positions=state.positions, avgp=state.avgp, sellinprogress=state.vars.sell_in_progress)
|
||||
#pokud je cena nizsi, testujeme REVERSE POZITION PROTECTION
|
||||
else:
|
||||
pass
|
||||
#reverse_position()
|
||||
|
||||
# def reverse_position():
|
||||
# """"
|
||||
# Reverse position - ochrana pred vetsim klesanim
|
||||
# - proda kdyz je splnena podminka
|
||||
# - nakoupi opet ve stejnem mnozstvi, kdyz je splnena podminka
|
||||
|
||||
# required STRATVARS:
|
||||
# reverse_position_slope = -0.9
|
||||
# reverse_position_on_confirmed_only = true
|
||||
# reverse_position_waiting_amount = 0
|
||||
# """""
|
||||
# #reverse position preconditions
|
||||
# dont_do_reverse_when = {}
|
||||
|
||||
# dont_do_reverse_when['reverse_position_waiting_amount_not_0'] = (state.vars.reverse_position_waiting_amount != 0)
|
||||
|
||||
# result, conditions_met = eval_cond_dict(dont_do_reverse_when)
|
||||
# if result:
|
||||
# state.ilog(e=f"REVERSE_PRECOND PROTECTION {conditions_met}")
|
||||
# return result
|
||||
|
||||
|
||||
# #reverse position for
|
||||
# confirmrequried = safe_get(state.vars, "reverse_position_on_confirmed_only", True)
|
||||
# if (confirmrequried and data['confirmed'] == 1) or confirmrequried is False:
|
||||
# #check reverse position
|
||||
# state.ilog(e="REVERSE POSITION check - GO")
|
||||
# else:
|
||||
# #not time for reverse position
|
||||
# state.ilog(e="REVERSE POSITION check - NO TIME")
|
||||
|
||||
# #predpokladame, ze uz byly testovany pozice a mame je if int(state.positions) > 0 and float(state.avgp)>0
|
||||
# if state.indicators.slopeMA[-1] < float(safe_get(state.vars, "reverse_position_slope", -0.10)):
|
||||
# state.interface.sell(size=state.positions)
|
||||
# state.vars.sell_in_progress = True
|
||||
# state.ilog(e=f"REV POS market SELL was sent {curr_price=}", positions=state.positions, avgp=state.avgp, sellinprogress=state.vars.sell_in_progress)
|
||||
# state.vars.rev_position_waiting_amount =
|
||||
|
||||
|
||||
|
||||
# None - standard, defaults mode - attributes are read from general stratvars section
|
||||
# other modes - attributtes are read from mode specific stratvars section, defaults to general section
|
||||
#WIP
|
||||
def set_mode():
|
||||
state.vars.mode = None
|
||||
|
||||
#dotahne hodnotu z prislusne sekce
|
||||
#pouziva se namisto safe_get
|
||||
# stratvars
|
||||
# buysignal = 1
|
||||
# stratvars.mode1
|
||||
# buysignal = 2
|
||||
# PARAMS:
|
||||
# - section: napr. stratvars.buysignal
|
||||
# - var name: MA_length
|
||||
# - default: defaultní hodnota, kdyz nenalezeno
|
||||
# Kroky: 1)
|
||||
# vrati danou hodnotu nastaveni podle aktualniho modu state.vars.mode
|
||||
# pokud je None, vrati pro standardni mod, pokud neni nalezeno vrati default
|
||||
# EXAMPLE:
|
||||
# get_modded_vars("state")
|
||||
#get_modded_vars(state.vars, 'buysignal', 1) - namista safe_get
|
||||
|
||||
#WIP
|
||||
def get_modded_vars(section, name: str, default = None):
|
||||
if state.vars.mode is None:
|
||||
return safe_get(section, name, default)
|
||||
else:
|
||||
try:
|
||||
modded_section = section[state.vars.mode]
|
||||
except KeyError:
|
||||
modded_section = section
|
||||
return safe_get(modded_section, name, safe_get(section, name, default))
|
||||
|
||||
def populate_ema_indicator():
|
||||
#BAR EMA INDICATOR -
|
||||
#plnime MAcko - nyni posilame jen N poslednich hodnot
|
||||
#zaroven osetrujeme pripady, kdy je malo dat a ukladame nulu
|
||||
try:
|
||||
ma = int(state.vars.MA)
|
||||
#poslednich ma hodnot
|
||||
source = state.bars.close[-ma:] #state.bars.vwap
|
||||
ema_value = ema(source, ma)
|
||||
|
||||
##pokus MACKO zakrouhlit na tri desetina a petku
|
||||
state.indicators.ema[-1]=round2five(ema_value[-1])
|
||||
##state.indicators.ema[-1]=trunc(ema_value[-1],3)
|
||||
#state.ilog(e=f"EMA {state.indicators.ema[-1]}", ema_last=state.indicators.ema[-6:])
|
||||
except Exception as e:
|
||||
state.ilog(e="EMA nechavame 0", message=str(e)+format_exc())
|
||||
#state.indicators.ema[-1]=(0)
|
||||
#evaluate buy signal
|
||||
#consolidation
|
||||
|
||||
# [stratvars.indicators.slope]
|
||||
# lookback
|
||||
# lookback_offset
|
||||
def populate_slow_slope_indicator():
|
||||
options = safe_get(state.vars.indicators, 'slow_slope', None)
|
||||
if options is None:
|
||||
state.ilog(e="No options for slow slope in stratvars")
|
||||
return
|
||||
|
||||
|
||||
#SLOW SLOPE INDICATOR
|
||||
#úhel stoupání a klesání vyjádřený mezi -1 až 1
|
||||
#pravý bod přímky je aktuální cena, levý je průměr X(lookback offset) starších hodnot od slope_lookback.
|
||||
#obsahuje statický indikátor (angle) pro vizualizaci
|
||||
try:
|
||||
slow_slope = 99
|
||||
slope_lookback = safe_get(options, 'slope_lookback', 100)
|
||||
minimum_slope = safe_get(options, 'minimum_slope', 25)
|
||||
maximum_slope = safe_get(options, "maximum_slope",0.9)
|
||||
lookback_offset = safe_get(options, 'lookback_offset', 25)
|
||||
|
||||
if len(state.bars.close) > (slope_lookback + lookback_offset):
|
||||
array_od = slope_lookback + lookback_offset
|
||||
array_do = slope_lookback
|
||||
lookbackprice_array = state.bars.vwap[-array_od:-array_do]
|
||||
#obycejný prumer hodnot
|
||||
lookbackprice = round(sum(lookbackprice_array)/lookback_offset,3)
|
||||
lookbacktime = state.bars.time[-slope_lookback]
|
||||
else:
|
||||
#kdyz neni dostatek hodnot, pouzivame jako levy bod open hodnotu close[0]
|
||||
lookbackprice = state.bars.close[0]
|
||||
lookbacktime = state.bars.time[0]
|
||||
state.ilog(e="Slow Slope - not enough data bereme left bod open", slope_lookback=slope_lookback, slope=state.indicators.slope, slopeMA=state.indicators.slopeMA)
|
||||
|
||||
#výpočet úhlu - a jeho normalizace
|
||||
slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100
|
||||
slope = round(slope, 4)
|
||||
state.indicators.slow_slope[-1]=slope
|
||||
|
||||
#angle je ze slope
|
||||
state.statinds.angle_slow = dict(time=state.bars.time[-1], price=state.bars.close[-1], lookbacktime=lookbacktime, lookbackprice=lookbackprice, minimum_slope=minimum_slope, maximum_slope=maximum_slope)
|
||||
|
||||
#slope MA vyrovna vykyvy ve slope, dále pracujeme se slopeMA
|
||||
slope_MA_length = safe_get(options, 'MA_length', 5)
|
||||
source = state.indicators.slow_slope[-slope_MA_length:]
|
||||
slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap
|
||||
slopeMA = slopeMAseries[-1]
|
||||
state.indicators.slow_slopeMA[-1]=slopeMA
|
||||
|
||||
state.ilog(e=f"SLOW {slope=} {slopeMA=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:], last_slopesMA=state.indicators.slopeMA[-10:])
|
||||
#dale pracujeme s timto MAckovanym slope
|
||||
#slope = slopeMA
|
||||
|
||||
except Exception as e:
|
||||
print("Exception in NEXT Slow Slope Indicator section", str(e))
|
||||
state.ilog(e="EXCEPTION", msg="Exception in Slow Slope Indicator section" + str(e) + format_exc())
|
||||
|
||||
def populate_slope_indicator():
|
||||
#populuje indikator typu SLOPE
|
||||
|
||||
|
||||
#SLOPE INDICATOR
|
||||
#úhel stoupání a klesání vyjádřený mezi -1 až 1
|
||||
#pravý bod přímky je aktuální cena, levý je průměr X(lookback offset) starších hodnot od slope_lookback.
|
||||
#obsahuje statický indikátor (angle) pro vizualizaci
|
||||
try:
|
||||
slope = 99
|
||||
slope_lookback = int(state.vars.slope_lookback)
|
||||
minimum_slope = float(state.vars.minimum_slope)
|
||||
lookback_offset = int(state.vars.lookback_offset)
|
||||
|
||||
if len(state.bars.close) > (slope_lookback + lookback_offset):
|
||||
array_od = slope_lookback + lookback_offset
|
||||
array_do = slope_lookback
|
||||
lookbackprice_array = state.bars.vwap[-array_od:-array_do]
|
||||
#obycejný prumer hodnot
|
||||
lookbackprice = round(sum(lookbackprice_array)/lookback_offset,3)
|
||||
|
||||
#výpočet úhlu - a jeho normalizace
|
||||
slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100
|
||||
slope = round(slope, 4)
|
||||
state.indicators.slope[-1]=slope
|
||||
|
||||
#angle je ze slope
|
||||
state.statinds.angle = dict(time=state.bars.time[-1], price=state.bars.close[-1], lookbacktime=state.bars.time[-slope_lookback], lookbackprice=lookbackprice, minimum_slope=minimum_slope, maximum_slope=safe_get(state.vars, "bigwave_slope_above",0.20))
|
||||
|
||||
#slope MA vyrovna vykyvy ve slope, dále pracujeme se slopeMA
|
||||
slope_MA_length = 5
|
||||
source = state.indicators.slope[-slope_MA_length:]
|
||||
slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap
|
||||
slopeMA = slopeMAseries[-1]
|
||||
state.indicators.slopeMA[-1]=slopeMA
|
||||
|
||||
state.ilog(e=f"{slope=} {slopeMA=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:], last_slopesMA=state.indicators.slopeMA[-10:])
|
||||
|
||||
#dale pracujeme s timto MAckovanym slope
|
||||
slope = slopeMA
|
||||
else:
|
||||
#pokud plnime historii musime ji plnit od zacatku, vsehcny idenitifkatory maji spolecny time
|
||||
#kvuli spravnemu zobrazovani na gui
|
||||
#state.indicators.slopeMA[-1]=0
|
||||
#state.indicators.slopeMA.append(0)
|
||||
state.ilog(e="Slope - not enough data", slope_lookback=slope_lookback, slope=state.indicators.slope, slopeMA=state.indicators.slopeMA)
|
||||
except Exception as e:
|
||||
print("Exception in NEXT Slope Indicator section", str(e))
|
||||
state.ilog(e="EXCEPTION", msg="Exception in Slope Indicator section" + str(e) + format_exc())
|
||||
|
||||
def populate_rsi_indicator():
|
||||
#RSI14 INDICATOR
|
||||
try:
|
||||
rsi_length = int(safe_get(state.vars, "rsi_length",14))
|
||||
source = state.bars.close #[-rsi_length:] #state.bars.vwap
|
||||
|
||||
#cekame na dostatek dat
|
||||
if len(source) > rsi_length:
|
||||
rsi_res = rsi(source, rsi_length)
|
||||
rsi_value = trunc(rsi_res[-1],3)
|
||||
state.indicators.RSI14[-1]=rsi_value
|
||||
else:
|
||||
state.ilog(e=f"RSI {rsi_length=} necháváme 0", message="not enough source data")
|
||||
#state.ilog(e=f"RSI {rsi_length=} {rsi_value=} {rsi_dont_buy=} {rsi_buy_signal=}", rsi_indicator=state.indicators.RSI14[-5:])
|
||||
except Exception as e:
|
||||
state.ilog(e=f"RSI {rsi_length=} necháváme 0", message=str(e)+format_exc())
|
||||
#state.indicators.RSI14[-1]=0
|
||||
|
||||
def populate_cbar_rsi_indicator():
|
||||
#CBAR RSI indicator
|
||||
options = safe_get(state.vars.indicators, 'crsi', None)
|
||||
if options is None:
|
||||
state.ilog(e="No options for crsi in stratvars")
|
||||
return
|
||||
|
||||
try:
|
||||
crsi_length = int(safe_get(options, 'crsi_length', 14))
|
||||
source = state.cbar_indicators.tick_price #[-rsi_length:] #state.bars.vwap
|
||||
crsi_res = rsi(source, crsi_length)
|
||||
crsi_value = crsi_res[-1]
|
||||
if str(crsi_value) == "nan":
|
||||
crsi_value = 0
|
||||
state.cbar_indicators.CRSI[-1]=crsi_value
|
||||
#state.ilog(e=f"RSI {rsi_length=} {rsi_value=} {rsi_dont_buy=} {rsi_buy_signal=}", rsi_indicator=state.indicators.RSI14[-5:])
|
||||
except Exception as e:
|
||||
state.ilog(e=f"CRSI {crsi_length=} necháváme 0", message=str(e)+format_exc())
|
||||
#state.indicators.RSI14[-1]=0
|
||||
|
||||
# def populate_secondary_rsi_indicator():
|
||||
# #SBAR RSI indicator
|
||||
# try:
|
||||
# srsi_length = int(safe_get(state.vars, "srsi_length",14))
|
||||
# source = state.secondary_indicators.sec_price #[-rsi_length:] #state.bars.vwap
|
||||
# srsi_res = rsi(source, srsi_length)
|
||||
# srsi_value = trunc(srsi_res[-1],3)
|
||||
# state.secondary_indicators.SRSI[-1]=srsi_value
|
||||
# #state.ilog(e=f"RSI {rsi_length=} {rsi_value=} {rsi_dont_buy=} {rsi_buy_signal=}", rsi_indicator=state.indicators.RSI14[-5:])
|
||||
# except Exception as e:
|
||||
# state.ilog(e=f"SRSI {srsi_length=} necháváme 0", message=str(e)+format_exc())
|
||||
# #state.indicators.RSI14[-1]=0
|
||||
|
||||
def slope_too_low():
|
||||
return state.indicators.slopeMA[-1] < float(state.vars.minimum_slope)
|
||||
|
||||
def slope_too_high():
|
||||
return state.indicators.slopeMA[-1] > float(safe_get(state.vars, "bigwave_slope_above",0.20))
|
||||
|
||||
#resetujeme, kdyz 1) je aktivni buy protection 2) kdyz to ujede
|
||||
#TODO mozna tick2reset spoustet jednou za X opakovani
|
||||
def pendingbuys_optimalization():
|
||||
if len(state.vars.pendingbuys)>0:
|
||||
if buy_protection_enabled():
|
||||
#state.ilog(e="PENDINGBUYS reset", message=inspect.currentframe().f_code.co_name)
|
||||
res = asyncio.run(state.cancel_pending_buys())
|
||||
state.ilog(e="CANCEL pendingbuyes", pb=state.vars.pendingbuys, res=res)
|
||||
else:
|
||||
#pokud mame vylozeno a cena je vetsi nez tick2reset
|
||||
maxprice = max(state.vars.pendingbuys.values())
|
||||
if state.interface.get_last_price(state.symbol) > float(maxprice) + get_tick(maxprice, float(state.vars.ticks2reset)):
|
||||
res = asyncio.run(state.cancel_pending_buys())
|
||||
state.ilog(e=f"UJELO to. Rusime PB", msg=f"{state.vars.ticks2reset=}", pb=state.vars.pendingbuys)
|
||||
|
||||
#PENDING BUYS SPENT - PART
|
||||
#pokud mame vylozeno a pendingbuys se vyklepou a
|
||||
# 1 vykladame idned znovu
|
||||
# vyloz()
|
||||
# 2 nebo - počkat zase na signál a pokračovat dál
|
||||
# state.vars.blockbuy = 0
|
||||
# state.vars.jevylozeno = 0
|
||||
# 3 nebo - počkat na signál s enablovaným lastbuy indexem (tzn. počká nutně ještě pár barů)
|
||||
#podle BT vyhodnejsi vylozit ihned
|
||||
if len(state.vars.pendingbuys) == 0:
|
||||
state.vars.blockbuy = 0
|
||||
state.vars.jevylozeno = 0
|
||||
state.ilog(e="PB prazdne nastavujeme: neni vylozeno", jevylozeno=state.vars.jevylozeno)
|
||||
|
||||
##kdy nesmí být žádné nákupní objednávky - zruší se
|
||||
def buy_protection_enabled():
|
||||
dont_buy_when = dict(AND=dict(), OR=dict())
|
||||
##add conditions here
|
||||
dont_buy_when['rsi_too_high'] = state.indicators.RSI14[-1] > safe_get(state.vars, "rsi_dont_buy_above",50)
|
||||
dont_buy_when['slope_too_low'] = slope_too_low()
|
||||
|
||||
result, cond_met = eval_cond_dict(dont_buy_when)
|
||||
if result:
|
||||
state.ilog(e=f"BUY_PROTECTION {cond_met}")
|
||||
return result
|
||||
|
||||
def sell_protection_enabled():
|
||||
options = safe_get(state.vars, 'sell_protection', None)
|
||||
if options is None:
|
||||
state.ilog(e="No options for sell protection in stratvars")
|
||||
return False
|
||||
|
||||
disable_sell_proteciton_when = dict(AND=dict(), OR=dict())
|
||||
|
||||
#preconditions
|
||||
disable_sell_proteciton_when['disabled_in_config'] = safe_get(options, 'enabled', False) is False
|
||||
#too good to be true (maximum profit)
|
||||
#disable_sell_proteciton_when['tgtbt_reached'] = safe_get(options, 'tgtbt', False) is False
|
||||
|
||||
|
||||
#testing preconditions
|
||||
result, conditions_met = eval_cond_dict(disable_sell_proteciton_when)
|
||||
if result:
|
||||
state.ilog(e=f"SELL_PROTECTION DISABLED by precondition {conditions_met}")
|
||||
return False
|
||||
|
||||
dont_sell_when = dict(AND=dict(), OR=dict())
|
||||
##add conditions here
|
||||
|
||||
#IDENTIFIKOVAce rustoveho MOMENTA - pokud je momentum, tak prodávat později
|
||||
|
||||
#pokud je slope too high, pak prodavame jakmile slopeMA zacne klesat, napr. 4MA (TODO 3)
|
||||
|
||||
#TODO zkusit pro pevny profit, jednoduse pozdrzet prodej - dokud tick_price roste nebo se drzi tak neprodavat, pokud klesne prodat
|
||||
#mozna mit dva mody - pri vetsi volatilite pouzivat momentum, pri mensi nebo kdyz potrebuju pryc, tak prodat hned
|
||||
|
||||
|
||||
#toto docasne pryc dont_sell_when['slope_too_high'] = slope_too_high() and not isfalling(state.indicators.slopeMA,4)
|
||||
dont_sell_when['AND']['slopeMA_rising'] = isrising(state.indicators.slopeMA,safe_get(options, 'slopeMA_rising', 2))
|
||||
dont_sell_when['AND']['rsi_not_falling'] = not isfalling(state.indicators.RSI14,safe_get(options, 'rsi_not_falling',3))
|
||||
#dont_sell_when['rsi_dont_buy'] = state.indicators.RSI14[-1] > safe_get(state.vars, "rsi_dont_buy_above",50)
|
||||
|
||||
result, conditions_met = eval_cond_dict(dont_sell_when)
|
||||
if result:
|
||||
state.ilog(e=f"SELL_PROTECTION {conditions_met} enabled")
|
||||
return result
|
||||
|
||||
#preconditions and conditions of BUY SIGNAL
|
||||
def buy_conditions_met():
|
||||
#preconditions
|
||||
dont_buy_when = dict(AND=dict(), OR=dict())
|
||||
|
||||
if safe_get(state.vars, "buy_only_on_confirmed",True):
|
||||
dont_buy_when['bar_not_confirmed'] = (data['confirmed'] == 0)
|
||||
#od posledniho vylozeni musi ubehnout N baru
|
||||
dont_buy_when['last_buy_offset_too_soon'] = data['index'] < (state.vars.last_buysignal_index + safe_get(state.vars, "lastbuy_offset",3))
|
||||
dont_buy_when['blockbuy_active'] = (state.vars.blockbuy == 1)
|
||||
dont_buy_when['jevylozeno_active'] = (state.vars.jevylozeno == 1)
|
||||
dont_buy_when['rsi_too_high'] = state.indicators.RSI14[-1] > safe_get(state.vars, "rsi_dont_buy_above",50)
|
||||
dont_buy_when['slope_too_low'] = slope_too_low()
|
||||
dont_buy_when['open_rush'] = is_open_rush(datetime.fromtimestamp(data['updated']).astimezone(zoneNY), safe_get(state.vars, "open_rush",0))
|
||||
dont_buy_when['close_rush'] = is_close_rush(datetime.fromtimestamp(data['updated']).astimezone(zoneNY), safe_get(state.vars, "close_rush",0))
|
||||
dont_buy_when['rsi_is_zero'] = (state.indicators.RSI14[-1] == 0)
|
||||
dont_buy_when['reverse_position_waiting_amount_not_0'] = (state.vars.reverse_position_waiting_amount != 0)
|
||||
|
||||
#testing preconditions
|
||||
result, cond_met = eval_cond_dict(dont_buy_when)
|
||||
if result:
|
||||
state.ilog(e=f"BUY precondition not met {cond_met} {state.vars.jevylozeno=}")
|
||||
return False
|
||||
|
||||
#conditions - bud samostatne nebo v groupe - ty musi platit dohromady
|
||||
buy_cond = dict(AND=dict(), OR=dict())
|
||||
##add buy conditions here
|
||||
#cond groups ["AND"]
|
||||
#cond groups ["OR"]
|
||||
#no cond group - takes first
|
||||
#TEST BUY SIGNALu z cbartick_price - 3klesave za sebou
|
||||
#buy_cond['tick_price_falling_trend'] = isfalling(state.cbar_indicators.tick_price,state.vars.Trend)
|
||||
|
||||
#slopeMA jde dolu, rsi jde nahoru
|
||||
#buy mame kazdy potvrzeny, tzn. rsi falling muze byt jen 2
|
||||
|
||||
#buy_cond['AND']['slopeMA_falling'] = isfalling(state.indicators.slopeMA,3)
|
||||
#buy_cond['AND']['rsi_is_rising'] = isrising(state.indicators.RSI14,2)
|
||||
#buy_cond["AND"]["rsi_buy_signal_below"] = state.indicators.RSI14[-1] < safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
|
||||
#puvodni buy conditiony RSI pod + EMA klesajici
|
||||
#buy_cond["AND"]["rsi_buy_signal_below"] = state.indicators.RSI14[-1] < safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
#buy_cond["AND"]["ema_trend_is_falling"] = isfalling(state.indicators.ema,state.vars.Trend)
|
||||
|
||||
#pouze RSI nizke a RSI klesa, pripadne k tomu CRSI
|
||||
#TATO KOMBINACE se da konfigurovat pouze hodnotama, aby platila libovolna kombinace podminek (např. Trend = 1 - vypne stredni podminku)
|
||||
buy_cond["AND"]["rsi_buy_signal_below"] = state.indicators.RSI14[-1] < safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
buy_cond["AND"]["rsi_is_falling"] = isfalling(state.indicators.RSI14,state.vars.Trend)
|
||||
buy_cond["AND"]['crsi_below_crsi_buy_limit'] = state.cbar_indicators.CRSI[-1] < safe_get(state.vars, "crsi_buy_signal_below",25)
|
||||
buy_cond["AND"]['slopeMA_is_below_limit'] = state.indicators.slopeMA[-1] < safe_get(state.vars, "slopeMA_buy_signal_below",1)
|
||||
|
||||
#slopME klesa a RSI začalo stoupat
|
||||
# buy_cond["AND"]["rsi_is_rising2"] = isrising(state.indicators.RSI14,2)
|
||||
# buy_cond['AND']['slopeMA_falling_Trend'] = isfalling(state.indicators.slopeMA,state.vars.Trend)
|
||||
# buy_cond["AND"]["rsi_buy_signal_below"] = state.indicators.RSI14[-1] < safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
|
||||
|
||||
#zkusit jako doplnkovy BUY SIGNAL 3 klesavy cbar RSI pripadne TICK PRICE
|
||||
|
||||
result, conditions_met = eval_cond_dict(buy_cond)
|
||||
#if result:
|
||||
state.ilog(e=f"BUY SIGNAL {result} {conditions_met}")
|
||||
return result
|
||||
|
||||
def eval_buy():
|
||||
if buy_conditions_met():
|
||||
vyloz()
|
||||
|
||||
def populate_cbar_tick_price_indicator():
|
||||
try:
|
||||
#pokud v potvrzovacím baru nebyly zmeny, nechavam puvodni hodnoty
|
||||
# if tick_delta_volume == 0:
|
||||
# state.indicators.tick_price[-1] = state.indicators.tick_price[-2]
|
||||
# state.indicators.tick_volume[-1] = state.indicators.tick_volume[-2]
|
||||
# else:
|
||||
|
||||
#tick_price = round2five(data['close'])
|
||||
tick_price = data['close']
|
||||
tick_delta_volume = data['volume'] - state.vars.last_tick_volume
|
||||
|
||||
#docasne dame pryc volume deltu a davame absolutni cislo
|
||||
state.cbar_indicators.tick_price[-1] = tick_price
|
||||
state.cbar_indicators.tick_volume[-1] = tick_delta_volume
|
||||
except:
|
||||
pass
|
||||
|
||||
state.ilog(e=f"TICK PRICE {tick_price} VOLUME {tick_delta_volume} {conf_bar=}", prev_price=state.vars.last_tick_price, prev_volume=state.vars.last_tick_volume)
|
||||
|
||||
state.vars.last_tick_price = tick_price
|
||||
state.vars.last_tick_volume = data['volume']
|
||||
|
||||
def get_last_ind_vals():
|
||||
last_ind_vals = {}
|
||||
#print(state.indicators.items())
|
||||
for key in state.indicators:
|
||||
if key != 'time':
|
||||
last_ind_vals[key] = state.indicators[key][-5:]
|
||||
|
||||
for key in state.cbar_indicators:
|
||||
if key != 'time':
|
||||
last_ind_vals[key] = state.cbar_indicators[key][-5:]
|
||||
|
||||
# for key in state.secondary_indicators:
|
||||
# if key != 'time':
|
||||
# last_ind_vals[key] = state.secondary_indicators[key][-5:]
|
||||
|
||||
return last_ind_vals
|
||||
|
||||
conf_bar = data['confirmed']
|
||||
|
||||
#PROCES DELTAS - to function
|
||||
last_update_delta = round((float(data['updated']) - state.vars.last_update_time),6) if state.vars.last_update_time != 0 else 0
|
||||
state.vars.last_update_time = float(data['updated'])
|
||||
|
||||
if len(state.vars.last_50_deltas) >=50:
|
||||
state.vars.last_50_deltas.pop(0)
|
||||
state.vars.last_50_deltas.append(last_update_delta)
|
||||
avg_delta = Average(state.vars.last_50_deltas)
|
||||
|
||||
state.ilog(e=f"---{data['index']}-{conf_bar}--delta:{last_update_delta}---AVGdelta:{avg_delta}")
|
||||
|
||||
#kroky pro CONFIRMED BAR only
|
||||
if conf_bar == 1:
|
||||
#logika pouze pro potvrzeny bar
|
||||
state.ilog(e="BAR potvrzeny")
|
||||
|
||||
|
||||
#pri potvrzem CBARu nulujeme counter volume pro tick based indicator
|
||||
state.vars.last_tick_volume = 0
|
||||
state.vars.next_new = 1
|
||||
|
||||
#zatim takto na confirm
|
||||
populate_slow_slope_indicator()
|
||||
|
||||
#SRSI
|
||||
#populate_secondary_rsi_indicator()
|
||||
|
||||
#kroky pro CONTINOUS TICKS only
|
||||
else:
|
||||
#CBAR INDICATOR pro tick price a deltu VOLUME
|
||||
populate_cbar_tick_price_indicator()
|
||||
populate_cbar_rsi_indicator()
|
||||
|
||||
|
||||
#SPOLECNA LOGIKA - bar indikatory muzeme populovat kazdy tick (dobre pro RT GUI), ale uklada se stejne az pri confirmu
|
||||
|
||||
|
||||
populate_ema_indicator()
|
||||
populate_slope_indicator()
|
||||
populate_rsi_indicator()
|
||||
eval_sell()
|
||||
consolidation()
|
||||
|
||||
#HLAVNI ITERACNI LOG JESTE PRED AKCI - obsahuje aktualni hodnoty vetsiny parametru
|
||||
#lp = state.interface.get_last_price(symbol=state.symbol)
|
||||
lp = data['close']
|
||||
state.ilog(e="ENTRY", msg=f"LP:{lp} P:{state.positions}/{round(float(state.avgp),3)} profit:{round(float(state.profit),2)} Trades:{len(state.tradeList)} DEF:{str(is_defensive_mode())}", last_price=lp, data=data, stratvars=state.vars)
|
||||
state.ilog(e="Indikatory", msg=str(get_last_ind_vals()))
|
||||
|
||||
eval_buy()
|
||||
pendingbuys_optimalization()
|
||||
|
||||
def init(state: StrategyState):
|
||||
#place to declare new vars
|
||||
print("INIT v main",state.name)
|
||||
|
||||
state.vars['sell_in_progress'] = False
|
||||
state.vars.mode = None
|
||||
state.vars.last_tick_price = 0
|
||||
state.vars.last_50_deltas = []
|
||||
state.vars.last_tick_volume = 0
|
||||
state.vars.next_new = 0
|
||||
state.vars.last_buysignal_index = 0
|
||||
state.vars.last_update_time = 0
|
||||
state.vars.reverse_position_waiting_amount = 0
|
||||
#state.cbar_indicators['ivwap'] = []
|
||||
state.cbar_indicators['tick_price'] = []
|
||||
state.cbar_indicators['tick_volume'] = []
|
||||
state.cbar_indicators['CRSI'] = []
|
||||
#state.secondary_indicators['SRSI'] = []
|
||||
state.indicators['ema'] = []
|
||||
state.indicators['slope'] = []
|
||||
state.indicators['slopeMA'] = []
|
||||
state.indicators['slow_slope'] = []
|
||||
state.indicators['slow_slopeMA'] = []
|
||||
state.indicators['RSI14'] = []
|
||||
#static indicators - those not series based
|
||||
state.statinds['angle'] = dict(minimum_slope=state.vars["minimum_slope"], maximum_slope=safe_get(state.vars, "bigwave_slope_above",0.20))
|
||||
#state.statinds['angle_slow'] = dict(minimum_slope=safe_get(state.vars.indicators.slow_slope, "minimum_slope",-2), maximum_slope=safe_get(state.vars.indicators.slow_slope, "maximum_slope",2))
|
||||
state.statinds['angle_slow'] = dict(minimum_slope=state.vars['indicators']['slow_slope']["minimum_slope"], maximum_slope=state.vars['indicators']['slow_slope']["maximum_slope"])
|
||||
|
||||
|
||||
state.vars["ticks2reset_backup"] = state.vars.ticks2reset
|
||||
|
||||
def main():
|
||||
name = os.path.basename(__file__)
|
||||
se = Event()
|
||||
pe = Event()
|
||||
s = StrategyOrderLimitVykladaciNormalizedMYSELL(name = name, symbol = "BAC", account=Account.ACCOUNT1, next=next, init=init, stratvars=stratvars, open_rush=10, close_rush=0, pe=pe, se=se, ilog_save=True)
|
||||
s.set_mode(mode = Mode.BT,
|
||||
debug = False,
|
||||
start = datetime(2023, 4, 14, 10, 42, 0, 0, tzinfo=zoneNY),
|
||||
end = datetime(2023, 4, 14, 14, 35, 0, 0, tzinfo=zoneNY),
|
||||
cash=100000)
|
||||
|
||||
#na sekundovem baru nezaokrouhlovat MAcko
|
||||
s.add_data(symbol="BAC",rectype=RecordType.BAR,timeframe=2,minsize=100,update_ltp=True,align=StartBarAlign.ROUND,mintick=0, exthours=False)
|
||||
#s.add_data(symbol="C",rectype=RecordType.BAR,timeframe=1,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=0)
|
||||
|
||||
s.start()
|
||||
print("zastavujeme")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
599
v2realbot/archived/ENTRY_Vykladaci_RSI_MYSELL_old.py
Normal file
599
v2realbot/archived/ENTRY_Vykladaci_RSI_MYSELL_old.py
Normal file
@ -0,0 +1,599 @@
|
||||
import os,sys
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
from v2realbot.strategy.base import StrategyState
|
||||
from v2realbot.strategy.StrategyOrderLimitVykladaciNormalizedMYSELL import StrategyOrderLimitVykladaciNormalizedMYSELL
|
||||
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, OrderSide, OrderType
|
||||
from v2realbot.indicators.indicators import ema
|
||||
from v2realbot.indicators.oscillators import rsi
|
||||
from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY, price2dec, print, safe_get, get_tick, round2five, is_open_rush, is_close_rush, eval_cond_dict
|
||||
from datetime import datetime
|
||||
#from icecream import install, ic
|
||||
#from rich import print
|
||||
from threading import Event
|
||||
from msgpack import packb, unpackb
|
||||
import asyncio
|
||||
import os
|
||||
from traceback import format_exc
|
||||
import inspect
|
||||
|
||||
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
""""
|
||||
Využívá: StrategyOrderLimitVykladaciNormalizedMYSELL
|
||||
|
||||
Kopie RSI Normalizovane Vykladaci navíc s řízením prodeje.
|
||||
Nepoužíváme LIMITKU.
|
||||
|
||||
Required CBAR. (pouze se změnou ceny)
|
||||
|
||||
nepotvrzený CBAR bez minticku (pouze se změnou ceny)
|
||||
- se používá pro žízení prodeje
|
||||
|
||||
potvrzený CBAR
|
||||
- se používá pro BUY
|
||||
|
||||
|
||||
"""
|
||||
stratvars = AttributeDict(maxpozic = 400,
|
||||
def_mode_from = 200,
|
||||
chunk = 10,
|
||||
MA = 2,
|
||||
Trend = 2,
|
||||
profit = 0.02,
|
||||
def_profit = 0.01,
|
||||
lastbuyindex=-6,
|
||||
pendingbuys={},
|
||||
limitka = None,
|
||||
limitka_price = None,
|
||||
jevylozeno=0,
|
||||
vykladka=5,
|
||||
curve = [0.01, 0.01, 0.01, 0, 0.02, 0.02, 0.01,0.01, 0.01,0.03, 0.01, 0.01, 0.01,0.04, 0.01,0.01, 0.01,0.05, 0.01,0.01, 0.01,0.01, 0.06,0.01, 0.01,0.01, 0.01],
|
||||
curve_def = [0.02, 0.02, 0.02, 0, 0, 0.02, 0, 0, 0, 0.02],
|
||||
blockbuy = 0,
|
||||
ticks2reset = 0.04,
|
||||
consolidation_bar_count = 10,
|
||||
slope_lookback = 300,
|
||||
lookback_offset = 20,
|
||||
minimum_slope = -0.05,
|
||||
first_buy_market = False
|
||||
)
|
||||
##toto rozparsovat a strategii spustit stejne jako v main
|
||||
toml_string = """
|
||||
[[strategies]]
|
||||
name = "V1 na BAC"
|
||||
symbol = "BAC"
|
||||
script = "ENTRY_backtest_strategyVykladaci"
|
||||
class = "StrategyOrderLimitVykladaci"
|
||||
open_rush = 0
|
||||
close_rush = 0
|
||||
[strategies.stratvars]
|
||||
maxpozic = 200
|
||||
chunk = 10
|
||||
MA = 6
|
||||
Trend = 5
|
||||
profit = 0.02
|
||||
lastbuyindex=-6
|
||||
pendingbuys={}
|
||||
limitka = "None"
|
||||
jevylozeno=0
|
||||
vykladka=5
|
||||
curve = [0.01, 0.01, 0.01,0.01, 0.02, 0.01,0.01, 0.01,0.03, 0.01, 0.01, 0.01,0.04, 0.01,0.01, 0.01,0.05, 0.01,0.01, 0.01,0.01, 0.06,0.01, 0.01,0.01, 0.01]
|
||||
blockbuy = 0
|
||||
ticks2reset = 0.04
|
||||
[[strategies.add_data]]
|
||||
symbol="BAC"
|
||||
rectype="bar"
|
||||
timeframe=5
|
||||
update_ltp=true
|
||||
align="round"
|
||||
mintick=0
|
||||
minsize=100
|
||||
exthours=false
|
||||
"""
|
||||
|
||||
def next(data, state: StrategyState):
|
||||
print(10*"*","NEXT START",10*"*")
|
||||
#ic(state.avgp, state.positions)
|
||||
#ic(state.vars)
|
||||
#ic(data)
|
||||
|
||||
#
|
||||
def is_defensive_mode():
|
||||
akt_pozic = int(state.positions)
|
||||
max_pozic = int(state.vars.maxpozic)
|
||||
def_mode_from = safe_get(state.vars, "def_mode_from",max_pozic/2)
|
||||
if akt_pozic >= int(def_mode_from):
|
||||
#state.ilog(e=f"DEFENSIVE mode ACTIVE {state.vars.def_mode_from=}", msg=state.positions)
|
||||
return True
|
||||
else:
|
||||
#state.ilog(e=f"STANDARD mode ACTIVE {state.vars.def_mode_from=}", msg=state.positions)
|
||||
return False
|
||||
|
||||
def get_limitka_price():
|
||||
def_profit = safe_get(state.vars, "def_profit",state.vars.profit)
|
||||
cena = float(state.avgp)
|
||||
#v MYSELL hrajeme i na 3 desetinna cisla - TBD mozna hrat jen na 5ky (0.125, 0.130, 0.135 atp.)
|
||||
if is_defensive_mode():
|
||||
return price2dec(cena+get_tick(cena,float(def_profit)),3)
|
||||
else:
|
||||
return price2dec(cena+get_tick(cena,float(state.vars.profit)),3)
|
||||
|
||||
def consolidation():
|
||||
##CONSOLIDATION PART - moved here, musí být před nákupem, jinak to dělalo nepořádek v pendingbuys
|
||||
#docasne zkusime konzolidovat i kdyz neni vylozeno (aby se srovnala limitka ve vsech situacich)
|
||||
if state.vars.jevylozeno == 1 or 1==1:
|
||||
##CONSOLIDATION PART kazdy Nty bar dle nastaveni
|
||||
if int(data["index"])%int(state.vars.consolidation_bar_count) == 0:
|
||||
print("***CONSOLIDATION ENTRY***")
|
||||
state.ilog(e="CONSOLIDATION ENTRY ***")
|
||||
|
||||
orderlist = state.interface.get_open_orders(symbol=state.symbol, side=None)
|
||||
#pro jistotu jeste dotahneme aktualni pozice
|
||||
state.avgp, state.positions = state.interface.pos()
|
||||
|
||||
#print(orderlist)
|
||||
pendingbuys_new = {}
|
||||
#zaciname s cistym stitem
|
||||
state.vars.limitka = None
|
||||
state.vars.limitka_price = None
|
||||
for o in orderlist:
|
||||
if o.side == OrderSide.BUY and o.order_type == OrderType.LIMIT:
|
||||
pendingbuys_new[str(o.id)]=float(o.limit_price)
|
||||
|
||||
if pendingbuys_new != state.vars.pendingbuys:
|
||||
state.ilog(e="Rozdilna PB prepsana", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys)
|
||||
print("ROZDILNA PENDINGBUYS přepsána")
|
||||
print("OLD",state.vars.pendingbuys)
|
||||
state.vars.pendingbuys = unpackb(packb(pendingbuys_new))
|
||||
print("NEW", state.vars.pendingbuys)
|
||||
else:
|
||||
print("PENDINGBUYS sedí - necháváme", state.vars.pendingbuys)
|
||||
state.ilog(e="PB sedi nechavame", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys)
|
||||
print("OLD jevylozeno", state.vars.jevylozeno)
|
||||
if len(state.vars.pendingbuys) > 0:
|
||||
state.vars.jevylozeno = 1
|
||||
else:
|
||||
state.vars.jevylozeno = 0
|
||||
print("NEW jevylozeno", state.vars.jevylozeno)
|
||||
state.ilog(e="Nove jevylozeno", msg=state.vars.jevylozeno)
|
||||
|
||||
print("***CONSOLIDATION EXIT***")
|
||||
state.ilog(e="CONSOLIDATION EXIT ***")
|
||||
else:
|
||||
state.ilog(e="No time for consolidation", msg=data["index"])
|
||||
print("no time for consolidation", data["index"])
|
||||
#mozna presunout o level vys
|
||||
def vyloz():
|
||||
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
|
||||
#curve = [0.01, 0.01, 0, 0, 0.01, 0, 0, 0, 0.02, 0, 0, 0, 0.03, 0,0,0,0,0, 0.02, 0,0,0,0,0,0, 0.02]
|
||||
curve = state.vars.curve
|
||||
##defenzivni krivka pro
|
||||
curve_def = state.vars.curve_def
|
||||
#vykladani po 5ti kusech, když zbývají 2 a méně, tak děláme nový výklad
|
||||
vykladka = state.vars.vykladka
|
||||
#kolik muzu max vylozit
|
||||
kolikmuzu = int((int(state.vars.maxpozic) - int(state.positions))/int(state.vars.chunk))
|
||||
akt_pozic = int(state.positions)
|
||||
max_pozic = int(state.vars.maxpozic)
|
||||
|
||||
if akt_pozic >= max_pozic:
|
||||
state.ilog(e="MAX pozic reached, cannot vyklad")
|
||||
return
|
||||
|
||||
#mame polovinu a vic vylozeno, pouzivame defenzicni krivku
|
||||
if is_defensive_mode():
|
||||
state.ilog(e="DEF: Pouzivame defenzivni krivku", akt_pozic=akt_pozic, max_pozic=max_pozic, curve_def=curve_def)
|
||||
curve = curve_def
|
||||
#zaroven docasne menime ticks2reset na defenzivni 0.06
|
||||
state.vars.ticks2reset = 0.06
|
||||
state.ilog(e="DEF: Menime tick2reset na 0.06", ticks2reset=state.vars.ticks2reset, ticks2reset_backup=state.vars.ticks2reset_backup)
|
||||
else:
|
||||
#vracime zpet, pokud bylo zmeneno
|
||||
if state.vars.ticks2reset != state.vars.ticks2reset_backup:
|
||||
state.vars.ticks2reset = state.vars.ticks2reset_backup
|
||||
state.ilog(e="DEF: Menime tick2reset zpet na"+str(state.vars.ticks2reset), ticks2reset=state.vars.ticks2reset, ticks2reset_backup=state.vars.ticks2reset_backup)
|
||||
|
||||
if kolikmuzu < vykladka: vykladka = kolikmuzu
|
||||
|
||||
if len(curve) < vykladka:
|
||||
vykladka = len(curve)
|
||||
qty = int(state.vars.chunk)
|
||||
last_price = price2dec(state.interface.get_last_price(state.symbol))
|
||||
#profit = float(state.vars.profit)
|
||||
price = last_price
|
||||
state.ilog(e="BUY Vykladame", msg=f"first price {price=} {vykladka=}", curve=curve, ema=state.indicators.ema[-1], trend=state.vars.Trend, price=price, vykladka=vykladka)
|
||||
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
|
||||
|
||||
##VAR - na zaklade conf. muzeme jako prvni posilat MARKET order
|
||||
if safe_get(state.vars, "first_buy_market") == True:
|
||||
#pri defenzivnim rezimu pouzivame vzdy LIMIT order
|
||||
if is_defensive_mode():
|
||||
state.ilog(e="DEF mode on, odesilame jako prvni limitku")
|
||||
state.buy_l(price=price, size=qty)
|
||||
else:
|
||||
state.ilog(e="Posilame jako prvni MARKET order")
|
||||
state.buy(size=qty)
|
||||
else:
|
||||
state.buy_l(price=price, size=qty)
|
||||
print("prvni limitka na aktuální cenu. Další podle křivky", price, qty)
|
||||
for i in range(0,vykladka-1):
|
||||
price = price2dec(float(price - get_tick(price, curve[i])))
|
||||
if price == last_price:
|
||||
qty = qty + int(state.vars.chunk)
|
||||
else:
|
||||
state.buy_l(price=price, size=qty)
|
||||
#print(i,"BUY limitka - delta",curve[i]," cena:", price, "mnozstvi:", qty)
|
||||
qty = int(state.vars.chunk)
|
||||
last_price = price
|
||||
state.vars.blockbuy = 1
|
||||
state.vars.jevylozeno = 1
|
||||
state.vars.last_buysignal_index = data['index']
|
||||
|
||||
def eval_sell():
|
||||
""""
|
||||
TBD
|
||||
Když je RSI nahoře tak neprodávat, dokud 1) RSI neprestane stoupat 2)nedosahne to nad im not greedy limit
|
||||
"""
|
||||
##mame pozice
|
||||
##aktualni cena je vetsi nebo rovna cene limitky
|
||||
#muzeme zde jet i na pulcenty
|
||||
curr_price = float(data['close'])
|
||||
state.ilog(e="Eval SELL", price=curr_price, pos=state.positions, avgp=state.avgp, sell_in_progress=state.vars.sell_in_progress)
|
||||
if int(state.positions) > 0 and float(state.avgp)>0 and state.vars.sell_in_progress is False:
|
||||
goal_price = get_limitka_price()
|
||||
state.ilog(e=f"Goal price {goal_price}")
|
||||
if curr_price>=goal_price:
|
||||
|
||||
#TODO cekat az slope prestane intenzivn erust, necekat az na klesani
|
||||
#TODO mozna cekat na nejaky signal RSI
|
||||
#TODO pripadne pokud dosahne TGTBB prodat ihned
|
||||
|
||||
#OPTIMALIZACE pri stoupajícím angle
|
||||
if sell_protection_enabled() is False:
|
||||
state.interface.sell(size=state.positions)
|
||||
state.vars.sell_in_progress = True
|
||||
state.ilog(e=f"market SELL was sent {curr_price=}", positions=state.positions, avgp=state.avgp, sellinprogress=state.vars.sell_in_progress)
|
||||
|
||||
def populate_ema_indicator():
|
||||
#BAR EMA INDICATOR -
|
||||
#plnime MAcko - nyni posilame jen N poslednich hodnot
|
||||
#zaroven osetrujeme pripady, kdy je malo dat a ukladame nulu
|
||||
try:
|
||||
ma = int(state.vars.MA)
|
||||
#poslednich ma hodnot
|
||||
source = state.bars.close[-ma:] #state.bars.vwap
|
||||
ema_value = ema(source, ma)
|
||||
|
||||
##pokus MACKO zakrouhlit na tri desetina a petku
|
||||
state.indicators.ema[-1]=round2five(ema_value[-1])
|
||||
##state.indicators.ema[-1]=trunc(ema_value[-1],3)
|
||||
#state.ilog(e=f"EMA {state.indicators.ema[-1]}", ema_last=state.indicators.ema[-6:])
|
||||
except Exception as e:
|
||||
state.ilog(e="EMA nechavame 0", message=str(e)+format_exc())
|
||||
#state.indicators.ema[-1]=(0)
|
||||
#evaluate buy signal
|
||||
#consolidation
|
||||
|
||||
def populate_slope_indicator():
|
||||
#SLOPE INDICATOR
|
||||
#úhel stoupání a klesání vyjádřený mezi -1 až 1
|
||||
#pravý bod přímky je aktuální cena, levý je průměr X(lookback offset) starších hodnot od slope_lookback.
|
||||
#obsahuje statický indikátor (angle) pro vizualizaci
|
||||
try:
|
||||
slope = 99
|
||||
slope_lookback = int(state.vars.slope_lookback)
|
||||
minimum_slope = float(state.vars.minimum_slope)
|
||||
lookback_offset = int(state.vars.lookback_offset)
|
||||
|
||||
if len(state.bars.close) > (slope_lookback + lookback_offset):
|
||||
array_od = slope_lookback + lookback_offset
|
||||
array_do = slope_lookback
|
||||
lookbackprice_array = state.bars.vwap[-array_od:-array_do]
|
||||
#obycejný prumer hodnot
|
||||
lookbackprice = round(sum(lookbackprice_array)/lookback_offset,3)
|
||||
|
||||
#výpočet úhlu - a jeho normalizace
|
||||
slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100
|
||||
slope = round(slope, 4)
|
||||
state.indicators.slope[-1]=slope
|
||||
|
||||
#angle je ze slope
|
||||
state.statinds.angle = dict(time=state.bars.time[-1], price=state.bars.close[-1], lookbacktime=state.bars.time[-slope_lookback], lookbackprice=lookbackprice, minimum_slope=minimum_slope, maximum_slope=safe_get(state.vars, "bigwave_slope_above",0.20))
|
||||
|
||||
#slope MA vyrovna vykyvy ve slope, dále pracujeme se slopeMA
|
||||
slope_MA_length = 5
|
||||
source = state.indicators.slope[-slope_MA_length:]
|
||||
slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap
|
||||
slopeMA = slopeMAseries[-1]
|
||||
state.indicators.slopeMA[-1]=slopeMA
|
||||
|
||||
state.ilog(e=f"{slope=} {slopeMA=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:], last_slopesMA=state.indicators.slopeMA[-10:])
|
||||
|
||||
#dale pracujeme s timto MAckovanym slope
|
||||
slope = slopeMA
|
||||
else:
|
||||
#pokud plnime historii musime ji plnit od zacatku, vsehcny idenitifkatory maji spolecny time
|
||||
#kvuli spravnemu zobrazovani na gui
|
||||
#state.indicators.slopeMA[-1]=0
|
||||
#state.indicators.slopeMA.append(0)
|
||||
state.ilog(e="Slope - not enough data", slope_lookback=slope_lookback, slope=state.indicators.slope, slopeMA=state.indicators.slopeMA)
|
||||
except Exception as e:
|
||||
print("Exception in NEXT Slope Indicator section", str(e))
|
||||
state.ilog(e="EXCEPTION", msg="Exception in Slope Indicator section" + str(e) + format_exc())
|
||||
|
||||
def populate_rsi_indicator():
|
||||
#RSI14 INDICATOR
|
||||
try:
|
||||
rsi_length = int(safe_get(state.vars, "rsi_length",14))
|
||||
source = state.bars.close #[-rsi_length:] #state.bars.vwap
|
||||
rsi_res = rsi(source, rsi_length)
|
||||
rsi_value = trunc(rsi_res[-1],3)
|
||||
state.indicators.RSI14[-1]=rsi_value
|
||||
#state.ilog(e=f"RSI {rsi_length=} {rsi_value=} {rsi_dont_buy=} {rsi_buy_signal=}", rsi_indicator=state.indicators.RSI14[-5:])
|
||||
except Exception as e:
|
||||
state.ilog(e=f"RSI {rsi_length=} necháváme 0", message=str(e)+format_exc())
|
||||
#state.indicators.RSI14[-1]=0
|
||||
|
||||
def populate_cbar_rsi_indicator():
|
||||
#CBAR RSI indicator
|
||||
try:
|
||||
crsi_length = int(safe_get(state.vars, "crsi_length",14))
|
||||
source = state.cbar_indicators.tick_price #[-rsi_length:] #state.bars.vwap
|
||||
crsi_res = rsi(source, crsi_length)
|
||||
crsi_value = trunc(crsi_res[-1],3)
|
||||
state.cbar_indicators.CRSI[-1]=crsi_value
|
||||
#state.ilog(e=f"RSI {rsi_length=} {rsi_value=} {rsi_dont_buy=} {rsi_buy_signal=}", rsi_indicator=state.indicators.RSI14[-5:])
|
||||
except Exception as e:
|
||||
state.ilog(e=f"CRSI {crsi_length=} necháváme 0", message=str(e)+format_exc())
|
||||
#state.indicators.RSI14[-1]=0
|
||||
|
||||
def slope_too_low():
|
||||
return state.indicators.slopeMA[-1] < float(state.vars.minimum_slope)
|
||||
|
||||
def slope_too_high():
|
||||
return state.indicators.slopeMA[-1] > float(safe_get(state.vars, "bigwave_slope_above",0.20))
|
||||
|
||||
#resetujeme, kdyz 1) je aktivni buy protection 2) kdyz to ujede
|
||||
#TODO mozna tick2reset spoustet jednou za X opakovani
|
||||
def pendingbuys_optimalization():
|
||||
if len(state.vars.pendingbuys)>0:
|
||||
if buy_protection_enabled():
|
||||
#state.ilog(e="PENDINGBUYS reset", message=inspect.currentframe().f_code.co_name)
|
||||
res = asyncio.run(state.cancel_pending_buys())
|
||||
state.ilog(e="CANCEL pendingbuyes", pb=state.vars.pendingbuys, res=res)
|
||||
else:
|
||||
#pokud mame vylozeno a cena je vetsi nez tick2reset
|
||||
maxprice = max(state.vars.pendingbuys.values())
|
||||
if state.interface.get_last_price(state.symbol) > float(maxprice) + get_tick(maxprice, float(state.vars.ticks2reset)):
|
||||
res = asyncio.run(state.cancel_pending_buys())
|
||||
state.ilog(e=f"UJELO to. Rusime PB", msg=f"{state.vars.ticks2reset=}", pb=state.vars.pendingbuys)
|
||||
|
||||
#PENDING BUYS SPENT - PART
|
||||
#pokud mame vylozeno a pendingbuys se vyklepou a
|
||||
# 1 vykladame idned znovu
|
||||
# vyloz()
|
||||
# 2 nebo - počkat zase na signál a pokračovat dál
|
||||
# state.vars.blockbuy = 0
|
||||
# state.vars.jevylozeno = 0
|
||||
# 3 nebo - počkat na signál s enablovaným lastbuy indexem (tzn. počká nutně ještě pár barů)
|
||||
#podle BT vyhodnejsi vylozit ihned
|
||||
if len(state.vars.pendingbuys) == 0:
|
||||
state.vars.blockbuy = 0
|
||||
state.vars.jevylozeno = 0
|
||||
state.ilog(e="PB prazdne nastavujeme: neni vylozeno", jevylozeno=state.vars.jevylozeno)
|
||||
|
||||
##kdy nesmí být žádné nákupní objednávky - zruší se
|
||||
def buy_protection_enabled():
|
||||
dont_buy_when = dict(AND=dict(), OR=dict())
|
||||
##add conditions here
|
||||
dont_buy_when['rsi_too_high'] = state.indicators.RSI14[-1] > safe_get(state.vars, "rsi_dont_buy_above",50)
|
||||
dont_buy_when['slope_too_low'] = slope_too_low()
|
||||
|
||||
result, cond_met = eval_cond_dict(dont_buy_when)
|
||||
if result:
|
||||
state.ilog(e=f"BUY_PROTECTION {cond_met}")
|
||||
return result
|
||||
|
||||
def sell_protection_enabled():
|
||||
dont_sell_when = dict(AND=dict(), OR=dict())
|
||||
##add conditions here
|
||||
|
||||
#IDENTIFIKOVAce rustoveho MOMENTA - pokud je momentum, tak prodávat později
|
||||
|
||||
#pokud je slope too high, pak prodavame jakmile slopeMA zacne klesat, napr. 4MA (TODO 3)
|
||||
|
||||
#toto docasne pryc dont_sell_when['slope_too_high'] = slope_too_high() and not isfalling(state.indicators.slopeMA,4)
|
||||
dont_sell_when['AND']['slopeMA_rising'] = isrising(state.indicators.slopeMA,2)
|
||||
dont_sell_when['AND']['rsi_not_falling'] = not isfalling(state.indicators.RSI14,3)
|
||||
#dont_sell_when['rsi_dont_buy'] = state.indicators.RSI14[-1] > safe_get(state.vars, "rsi_dont_buy_above",50)
|
||||
|
||||
result, conditions_met = eval_cond_dict(dont_sell_when)
|
||||
if result:
|
||||
state.ilog(e=f"SELL_PROTECTION {conditions_met} enabled")
|
||||
return result
|
||||
|
||||
#preconditions and conditions of BUY SIGNAL
|
||||
def buy_conditions_met():
|
||||
#preconditions
|
||||
dont_buy_when = dict(AND=dict(), OR=dict())
|
||||
|
||||
|
||||
if safe_get(state.vars, "buy_only_on_confirmed",True):
|
||||
dont_buy_when['bar_not_confirmed'] = (data['confirmed'] == 0)
|
||||
#od posledniho vylozeni musi ubehnout N baru
|
||||
dont_buy_when['last_buy_offset_too_soon'] = data['index'] < (state.vars.last_buysignal_index + safe_get(state.vars, "lastbuy_offset",3))
|
||||
dont_buy_when['blockbuy_active'] = (state.vars.blockbuy == 1)
|
||||
dont_buy_when['jevylozeno_active'] = (state.vars.jevylozeno == 1)
|
||||
dont_buy_when['rsi_too_high'] = state.indicators.RSI14[-1] > safe_get(state.vars, "rsi_dont_buy_above",50)
|
||||
dont_buy_when['slope_too_low'] = slope_too_low()
|
||||
dont_buy_when['open_rush'] = is_open_rush(datetime.fromtimestamp(data['updated']).astimezone(zoneNY), safe_get(state.vars, "open_rush",0))
|
||||
dont_buy_when['close_rush'] = is_close_rush(datetime.fromtimestamp(data['updated']).astimezone(zoneNY), safe_get(state.vars, "close_rush",0))
|
||||
dont_buy_when['rsi_is_zero'] = (state.indicators.RSI14[-1] == 0)
|
||||
|
||||
#testing preconditions
|
||||
result, cond_met = eval_cond_dict(dont_buy_when)
|
||||
if result:
|
||||
state.ilog(e=f"BUY precondition not met {cond_met}")
|
||||
return False
|
||||
|
||||
#conditions - bud samostatne nebo v groupe - ty musi platit dohromady
|
||||
buy_cond = dict(AND=dict(), OR=dict())
|
||||
##add buy conditions here
|
||||
#cond groups ["AND"]
|
||||
#cond groups ["OR"]
|
||||
#no cond group - takes first
|
||||
#TEST BUY SIGNALu z cbartick_price - 3klesave za sebou
|
||||
#buy_cond['tick_price_falling_trend'] = isfalling(state.cbar_indicators.tick_price,state.vars.Trend)
|
||||
|
||||
#slopeMA jde dolu, rsi jde nahoru
|
||||
#buy mame kazdy potvrzeny, tzn. rsi falling muze byt jen 2
|
||||
|
||||
#buy_cond['AND']['slopeMA_falling'] = isfalling(state.indicators.slopeMA,3)
|
||||
#buy_cond['AND']['rsi_is_rising'] = isrising(state.indicators.RSI14,2)
|
||||
#buy_cond["AND"]["rsi_buy_signal_below"] = state.indicators.RSI14[-1] < safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
|
||||
#puvodni buy conditiony RSI pod + EMA klesajici
|
||||
#buy_cond["AND"]["rsi_buy_signal_below"] = state.indicators.RSI14[-1] < safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
#buy_cond["AND"]["ema_trend_is_falling"] = isfalling(state.indicators.ema,state.vars.Trend)
|
||||
|
||||
#pouze RSI nizke a RSI klesa
|
||||
buy_cond["AND"]["rsi_buy_signal_below"] = state.indicators.RSI14[-1] < safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
buy_cond["AND"]["rsi_is_falling"] = isfalling(state.indicators.RSI14,state.vars.Trend)
|
||||
|
||||
#buy_cond['crsi_below_crsi_buy_limit'] = state.cbar_indicators.CRSI[-1] < safe_get(state.vars, "crsi_buy_signal_below",30)
|
||||
|
||||
#slopME klesa a RSI začalo stoupat
|
||||
# buy_cond["AND"]["rsi_is_rising2"] = isrising(state.indicators.RSI14,2)
|
||||
# buy_cond['AND']['slopeMA_falling_Trend'] = isfalling(state.indicators.slopeMA,state.vars.Trend)
|
||||
# buy_cond["AND"]["rsi_buy_signal_below"] = state.indicators.RSI14[-1] < safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
|
||||
|
||||
#zkusit jako doplnkovy BUY SIGNAL 3 klesavy cbar RSI pripadne TICK PRICE
|
||||
|
||||
result, conditions_met = eval_cond_dict(buy_cond)
|
||||
if result:
|
||||
state.ilog(e=f"BUY SIGNAL {conditions_met}")
|
||||
return result
|
||||
|
||||
def eval_buy():
|
||||
if buy_conditions_met():
|
||||
vyloz()
|
||||
|
||||
def populate_cbar_tick_price_indicator():
|
||||
try:
|
||||
#pokud v potvrzovacím baru nebyly zmeny, nechavam puvodni hodnoty
|
||||
# if tick_delta_volume == 0:
|
||||
# state.indicators.tick_price[-1] = state.indicators.tick_price[-2]
|
||||
# state.indicators.tick_volume[-1] = state.indicators.tick_volume[-2]
|
||||
# else:
|
||||
|
||||
tick_price = round2five(data['close'])
|
||||
tick_delta_volume = data['volume'] - state.vars.last_tick_volume
|
||||
|
||||
#docasne dame pryc volume deltu a davame absolutni cislo
|
||||
state.cbar_indicators.tick_price[-1] = tick_price
|
||||
state.cbar_indicators.tick_volume[-1] = tick_delta_volume
|
||||
except:
|
||||
pass
|
||||
|
||||
state.ilog(e=f"TICK PRICE {tick_price} VOLUME {tick_delta_volume} {conf_bar=}", prev_price=state.vars.last_tick_price, prev_volume=state.vars.last_tick_volume)
|
||||
|
||||
state.vars.last_tick_price = tick_price
|
||||
state.vars.last_tick_volume = data['volume']
|
||||
|
||||
def get_last_ind_vals():
|
||||
last_ind_vals = {}
|
||||
#print(state.indicators.items())
|
||||
for key in state.indicators:
|
||||
if key != 'time':
|
||||
last_ind_vals[key] = state.indicators[key][-5:]
|
||||
|
||||
for key in state.cbar_indicators:
|
||||
if key != 'time':
|
||||
last_ind_vals[key] = state.cbar_indicators[key][-5:]
|
||||
return last_ind_vals
|
||||
|
||||
conf_bar = data['confirmed']
|
||||
last_update_delta = round((float(data['updated']) - state.vars.last_update_time),6) if state.vars.last_update_time != 0 else 0
|
||||
state.vars.last_update_time = float(data['updated'])
|
||||
state.ilog(e=f"---{data['index']}-{conf_bar}--delta:{last_update_delta}")
|
||||
|
||||
#kroky pro CONFIRMED BAR only
|
||||
if conf_bar == 1:
|
||||
#logika pouze pro potvrzeny bar
|
||||
state.ilog(e="BAR potvrzeny")
|
||||
|
||||
|
||||
#pri potvrzem CBARu nulujeme counter volume pro tick based indicator
|
||||
state.vars.last_tick_volume = 0
|
||||
state.vars.next_new = 1
|
||||
|
||||
#kroky pro CONTINOUS TICKS only
|
||||
else:
|
||||
#CBAR INDICATOR pro tick price a deltu VOLUME
|
||||
populate_cbar_tick_price_indicator()
|
||||
populate_cbar_rsi_indicator()
|
||||
|
||||
#SPOLECNA LOGIKA - bar indikatory muzeme populovat kazdy tick (dobre pro RT GUI), ale uklada se stejne az pri confirmu
|
||||
|
||||
|
||||
populate_ema_indicator()
|
||||
populate_slope_indicator()
|
||||
populate_rsi_indicator()
|
||||
eval_sell()
|
||||
consolidation()
|
||||
|
||||
#HLAVNI ITERACNI LOG JESTE PRED AKCI - obsahuje aktualni hodnoty vetsiny parametru
|
||||
lp = state.interface.get_last_price(symbol=state.symbol)
|
||||
state.ilog(e="ENTRY", msg=f"LP:{lp} P:{state.positions}/{round(float(state.avgp),3)} profit:{round(float(state.profit),2)} Trades:{len(state.tradeList)} DEF:{str(is_defensive_mode())}", last_price=lp, data=data, stratvars=state.vars)
|
||||
state.ilog(e="Indikatory", msg=str(get_last_ind_vals()))
|
||||
|
||||
eval_buy()
|
||||
pendingbuys_optimalization()
|
||||
|
||||
def init(state: StrategyState):
|
||||
#place to declare new vars
|
||||
print("INIT v main",state.name)
|
||||
|
||||
state.vars['sell_in_progress'] = False
|
||||
state.vars.last_tick_price = 0
|
||||
state.vars.last_tick_volume = 0
|
||||
state.vars.next_new = 0
|
||||
state.vars.last_buysignal_index = 0
|
||||
state.vars.last_update_time = 0
|
||||
#state.cbar_indicators['ivwap'] = []
|
||||
state.cbar_indicators['tick_price'] = []
|
||||
state.cbar_indicators['tick_volume'] = []
|
||||
state.cbar_indicators['CRSI'] = []
|
||||
state.indicators['ema'] = []
|
||||
state.indicators['slope'] = []
|
||||
state.indicators['slopeMA'] = []
|
||||
state.indicators['RSI14'] = []
|
||||
#static indicators - those not series based
|
||||
state.statinds['angle'] = dict(minimum_slope=state.vars["minimum_slope"], maximum_slope=safe_get(state.vars, "bigwave_slope_above",0.20))
|
||||
state.vars["ticks2reset_backup"] = state.vars.ticks2reset
|
||||
|
||||
def main():
|
||||
name = os.path.basename(__file__)
|
||||
se = Event()
|
||||
pe = Event()
|
||||
s = StrategyOrderLimitVykladaciNormalizedMYSELL(name = name, symbol = "BAC", account=Account.ACCOUNT1, next=next, init=init, stratvars=stratvars, open_rush=10, close_rush=0, pe=pe, se=se, ilog_save=True)
|
||||
s.set_mode(mode = Mode.BT,
|
||||
debug = False,
|
||||
start = datetime(2023, 4, 14, 10, 42, 0, 0, tzinfo=zoneNY),
|
||||
end = datetime(2023, 4, 14, 14, 35, 0, 0, tzinfo=zoneNY),
|
||||
cash=100000)
|
||||
|
||||
#na sekundovem baru nezaokrouhlovat MAcko
|
||||
s.add_data(symbol="BAC",rectype=RecordType.BAR,timeframe=2,minsize=100,update_ltp=True,align=StartBarAlign.ROUND,mintick=0, exthours=False)
|
||||
#s.add_data(symbol="C",rectype=RecordType.BAR,timeframe=1,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=0)
|
||||
|
||||
s.start()
|
||||
print("zastavujeme")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
519
v2realbot/archived/ENTRY_Vykladaci_RSI_Normalized.py
Normal file
519
v2realbot/archived/ENTRY_Vykladaci_RSI_Normalized.py
Normal file
@ -0,0 +1,519 @@
|
||||
import os,sys
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
from v2realbot.strategy.base import StrategyState
|
||||
from v2realbot.strategy.StrategyOrderLimitVykladaciNormalized import StrategyOrderLimitVykladaciNormalized
|
||||
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, OrderSide, OrderType
|
||||
from v2realbot.indicators.indicators import ema
|
||||
from v2realbot.indicators.oscillators import rsi
|
||||
from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY, price2dec, print, safe_get, get_tick
|
||||
from datetime import datetime
|
||||
#from icecream import install, ic
|
||||
#from rich import print
|
||||
from threading import Event
|
||||
from msgpack import packb, unpackb
|
||||
import asyncio
|
||||
import os
|
||||
from traceback import format_exc
|
||||
|
||||
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
""""
|
||||
Kope Vykladaci strategie s navic pridanym RSI a normalizovaným tickem.
|
||||
|
||||
- pokud RSI > 50
|
||||
- rusime pendingbuye
|
||||
- netriggerujeme buy
|
||||
|
||||
"""
|
||||
stratvars = AttributeDict(maxpozic = 400,
|
||||
def_mode_from = 200,
|
||||
chunk = 10,
|
||||
MA = 2,
|
||||
Trend = 2,
|
||||
profit = 0.02,
|
||||
def_profit = 0.01,
|
||||
lastbuyindex=-6,
|
||||
pendingbuys={},
|
||||
limitka = None,
|
||||
limitka_price = None,
|
||||
jevylozeno=0,
|
||||
vykladka=5,
|
||||
curve = [0.01, 0.01, 0.01, 0, 0.02, 0.02, 0.01,0.01, 0.01,0.03, 0.01, 0.01, 0.01,0.04, 0.01,0.01, 0.01,0.05, 0.01,0.01, 0.01,0.01, 0.06,0.01, 0.01,0.01, 0.01],
|
||||
curve_def = [0.02, 0.02, 0.02, 0, 0, 0.02, 0, 0, 0, 0.02],
|
||||
blockbuy = 0,
|
||||
ticks2reset = 0.04,
|
||||
consolidation_bar_count = 10,
|
||||
slope_lookback = 300,
|
||||
lookback_offset = 20,
|
||||
minimum_slope = -0.05,
|
||||
first_buy_market = False
|
||||
)
|
||||
##toto rozparsovat a strategii spustit stejne jako v main
|
||||
toml_string = """
|
||||
[[strategies]]
|
||||
name = "V1 na BAC"
|
||||
symbol = "BAC"
|
||||
script = "ENTRY_backtest_strategyVykladaci"
|
||||
class = "StrategyOrderLimitVykladaci"
|
||||
open_rush = 0
|
||||
close_rush = 0
|
||||
[strategies.stratvars]
|
||||
maxpozic = 200
|
||||
chunk = 10
|
||||
MA = 6
|
||||
Trend = 5
|
||||
profit = 0.02
|
||||
lastbuyindex=-6
|
||||
pendingbuys={}
|
||||
limitka = "None"
|
||||
jevylozeno=0
|
||||
vykladka=5
|
||||
curve = [0.01, 0.01, 0.01,0.01, 0.02, 0.01,0.01, 0.01,0.03, 0.01, 0.01, 0.01,0.04, 0.01,0.01, 0.01,0.05, 0.01,0.01, 0.01,0.01, 0.06,0.01, 0.01,0.01, 0.01]
|
||||
blockbuy = 0
|
||||
ticks2reset = 0.04
|
||||
[[strategies.add_data]]
|
||||
symbol="BAC"
|
||||
rectype="bar"
|
||||
timeframe=5
|
||||
update_ltp=true
|
||||
align="round"
|
||||
mintick=0
|
||||
minsize=100
|
||||
exthours=false
|
||||
"""
|
||||
|
||||
def next(data, state: StrategyState):
|
||||
print(10*"*","NEXT START",10*"*")
|
||||
#ic(state.avgp, state.positions)
|
||||
#ic(state.vars)
|
||||
#ic(data)
|
||||
|
||||
#
|
||||
def is_defensive_mode():
|
||||
akt_pozic = int(state.positions)
|
||||
max_pozic = int(state.vars.maxpozic)
|
||||
def_mode_from = safe_get(state.vars, "def_mode_from",max_pozic/2)
|
||||
if akt_pozic >= int(def_mode_from):
|
||||
state.ilog(e=f"DEFENSIVE mode ACTIVE {state.vars.def_mode_from=}", msg=state.positions)
|
||||
return True
|
||||
else:
|
||||
state.ilog(e=f"STANDARD mode ACTIVE {state.vars.def_mode_from=}", msg=state.positions)
|
||||
return False
|
||||
|
||||
def get_limitka_price():
|
||||
def_profit = safe_get(state.vars, "def_profit",state.vars.profit)
|
||||
cena = float(state.avgp)
|
||||
if is_defensive_mode():
|
||||
return price2dec(cena+get_tick(cena,float(def_profit)))
|
||||
else:
|
||||
return price2dec(cena+get_tick(cena,float(state.vars.profit)))
|
||||
|
||||
def consolidation():
|
||||
##CONSOLIDATION PART - moved here, musí být před nákupem, jinak to dělalo nepořádek v pendingbuys
|
||||
#docasne zkusime konzolidovat i kdyz neni vylozeno (aby se srovnala limitka ve vsech situacich)
|
||||
if state.vars.jevylozeno == 1 or 1==1:
|
||||
##CONSOLIDATION PART kazdy Nty bar dle nastaveni
|
||||
if int(data["index"])%int(state.vars.consolidation_bar_count) == 0:
|
||||
print("***CONSOLIDATION ENTRY***")
|
||||
state.ilog(e="CONSOLIDATION ENTRY ***")
|
||||
|
||||
orderlist = state.interface.get_open_orders(symbol=state.symbol, side=None)
|
||||
#pro jistotu jeste dotahneme aktualni pozice
|
||||
state.avgp, state.positions = state.interface.pos()
|
||||
|
||||
#print(orderlist)
|
||||
pendingbuys_new = {}
|
||||
limitka_old = state.vars.limitka
|
||||
#print("Puvodni LIMITKA", limitka_old)
|
||||
#zaciname s cistym stitem
|
||||
state.vars.limitka = None
|
||||
state.vars.limitka_price = None
|
||||
limitka_found = False
|
||||
limitka_qty = 0
|
||||
limitka_filled_qty = 0
|
||||
for o in orderlist:
|
||||
if o.side == OrderSide.SELL:
|
||||
|
||||
if limitka_found:
|
||||
state.ilog(e="nalezeno vicero sell objednavek, bereme prvni, ostatni - rusime")
|
||||
result=state.interface.cancel(o.id)
|
||||
state.ilog(e="zrusena objednavka"+str(o.id), message=result)
|
||||
continue
|
||||
|
||||
#print("Nalezena LIMITKA")
|
||||
limitka_found = True
|
||||
state.vars.limitka = o.id
|
||||
state.vars.limitka_price = o.limit_price
|
||||
limitka_qty = int(o.qty)
|
||||
limitka_filled_qty = int(o.filled_qty)
|
||||
|
||||
#aktualni mnozstvi = puvodni minus filled
|
||||
if limitka_filled_qty is not None:
|
||||
print("prepocitavam filledmnozstvi od limitka_qty a filled_qty", limitka_qty, limitka_filled_qty)
|
||||
limitka_qty = int(limitka_qty) - int(limitka_filled_qty)
|
||||
##TODO sem pridat upravu ceny
|
||||
if o.side == OrderSide.BUY and o.order_type == OrderType.LIMIT:
|
||||
pendingbuys_new[str(o.id)]=float(o.limit_price)
|
||||
|
||||
state.ilog(e="Konzolidace limitky", msg=f"stejna:{(str(limitka_old)==str(state.vars.limitka))}", limitka_old=str(limitka_old), limitka_new=str(state.vars.limitka), limitka_new_price=state.vars.limitka_price, limitka_qty=limitka_qty, limitka_filled_qty=limitka_filled_qty)
|
||||
|
||||
#pokud mame
|
||||
|
||||
#neni limitka, ale mela by byt - vytváříme ji
|
||||
if int(state.positions) > 0 and state.vars.limitka is None:
|
||||
state.ilog(e="Limitka neni, ale mela by být.", msg=f"{state.positions=}")
|
||||
price=get_limitka_price()
|
||||
state.vars.limitka = asyncio.run(state.interface.sell_l(price=price, size=int(state.positions)))
|
||||
state.vars.limitka_price = price
|
||||
if state.vars.limitka == -1:
|
||||
state.ilog(e="Vytvoreni limitky neprobehlo, vracime None", msg=f"{state.vars.limitka=}")
|
||||
state.vars.limitka = None
|
||||
state.vars.limitka_price = None
|
||||
else:
|
||||
state.ilog(e="Vytvořena nová limitka", limitka=str(state.vars.limitka), limtka_price=state.vars.limitka_price, qty=state.positions)
|
||||
|
||||
#existuje a nesedi mnozstvi nebo cena
|
||||
elif state.vars.limitka is not None and int(state.positions) > 0 and ((int(state.positions) != int(limitka_qty)) or float(state.vars.limitka_price) != float(get_limitka_price())):
|
||||
#limitka existuje, ale spatne mnostvi - updatujeme
|
||||
state.ilog(e=f"Limitka existuje, ale spatne mnozstvi nebo CENA - updatujeme", msg=f"{state.positions=} {limitka_qty=} {state.vars.limitka_price=}", nastavenacena=state.vars.limitka_price, spravna_cena=get_limitka_price(), pos=state.positions, limitka_qty=limitka_qty)
|
||||
#snad to nespadne, kdyztak pridat exception handling
|
||||
puvodni = state.vars.limitka
|
||||
#TBD zde odchytit nejak result
|
||||
state.vars.limitka = asyncio.run(state.interface.repl(price=get_limitka_price(), orderid=state.vars.limitka, size=int(state.positions)))
|
||||
|
||||
if state.vars.limitka == -1:
|
||||
state.ilog(e="Replace limitky neprobehl, vracime puvodni", msg=f"{state.vars.limitka=}", puvodni=puvodni)
|
||||
state.vars.limitka = puvodni
|
||||
else:
|
||||
limitka_qty = int(state.positions)
|
||||
state.ilog(e="Změněna limitka", limitka=str(state.vars.limitka), limitka_price=state.vars.limitka_price, limitka_qty=limitka_qty)
|
||||
|
||||
#tbd pokud se bude vyskytovat pak pridat ještě konzolidaci ceny limitky
|
||||
|
||||
if pendingbuys_new != state.vars.pendingbuys:
|
||||
state.ilog(e="Rozdilna PB prepsana", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys)
|
||||
print("ROZDILNA PENDINGBUYS přepsána")
|
||||
print("OLD",state.vars.pendingbuys)
|
||||
state.vars.pendingbuys = unpackb(packb(pendingbuys_new))
|
||||
print("NEW", state.vars.pendingbuys)
|
||||
else:
|
||||
print("PENDINGBUYS sedí - necháváme", state.vars.pendingbuys)
|
||||
state.ilog(e="PB sedi nechavame", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys)
|
||||
print("OLD jevylozeno", state.vars.jevylozeno)
|
||||
if len(state.vars.pendingbuys) > 0:
|
||||
state.vars.jevylozeno = 1
|
||||
else:
|
||||
state.vars.jevylozeno = 0
|
||||
print("NEW jevylozeno", state.vars.jevylozeno)
|
||||
state.ilog(e="Nove jevylozeno", msg=state.vars.jevylozeno)
|
||||
|
||||
#print(limitka)
|
||||
#print(pendingbuys_new)
|
||||
#print(pendingbuys)
|
||||
#print(len(pendingbuys))
|
||||
#print(len(pendingbuys_new))
|
||||
#print(jevylozeno)
|
||||
print("***CONSOLIDATION EXIT***")
|
||||
state.ilog(e="CONSOLIDATION EXIT ***")
|
||||
else:
|
||||
state.ilog(e="No time for consolidation", msg=data["index"])
|
||||
print("no time for consolidation", data["index"])
|
||||
|
||||
#mozna presunout o level vys
|
||||
def vyloz():
|
||||
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
|
||||
#curve = [0.01, 0.01, 0, 0, 0.01, 0, 0, 0, 0.02, 0, 0, 0, 0.03, 0,0,0,0,0, 0.02, 0,0,0,0,0,0, 0.02]
|
||||
curve = state.vars.curve
|
||||
##defenzivni krivka pro
|
||||
curve_def = state.vars.curve_def
|
||||
#vykladani po 5ti kusech, když zbývají 2 a méně, tak děláme nový výklad
|
||||
vykladka = state.vars.vykladka
|
||||
#kolik muzu max vylozit
|
||||
kolikmuzu = int((int(state.vars.maxpozic) - int(state.positions))/int(state.vars.chunk))
|
||||
akt_pozic = int(state.positions)
|
||||
max_pozic = int(state.vars.maxpozic)
|
||||
|
||||
#mame polovinu a vic vylozeno, pouzivame defenzicni krivku
|
||||
if is_defensive_mode():
|
||||
state.ilog(e="DEF: Pouzivame defenzivni krivku", akt_pozic=akt_pozic, max_pozic=max_pozic, curve_def=curve_def)
|
||||
curve = curve_def
|
||||
#zaroven docasne menime ticks2reset na defenzivni 0.06
|
||||
state.vars.ticks2reset = 0.06
|
||||
state.ilog(e="DEF: Menime tick2reset na 0.06", ticks2reset=state.vars.ticks2reset, ticks2reset_backup=state.vars.ticks2reset_backup)
|
||||
else:
|
||||
#vracime zpet, pokud bylo zmeneno
|
||||
if state.vars.ticks2reset != state.vars.ticks2reset_backup:
|
||||
state.vars.ticks2reset = state.vars.ticks2reset_backup
|
||||
state.ilog(e="DEF: Menime tick2reset zpet na"+str(state.vars.ticks2reset), ticks2reset=state.vars.ticks2reset, ticks2reset_backup=state.vars.ticks2reset_backup)
|
||||
|
||||
if kolikmuzu < vykladka: vykladka = kolikmuzu
|
||||
|
||||
if len(curve) < vykladka:
|
||||
vykladka = len(curve)
|
||||
qty = int(state.vars.chunk)
|
||||
last_price = price2dec(state.interface.get_last_price(state.symbol))
|
||||
#profit = float(state.vars.profit)
|
||||
price = last_price
|
||||
state.ilog(e="BUY Vykladame", msg=f"first price {price=} {vykladka=}", curve=curve, ema=state.indicators.ema[-1], trend=state.vars.Trend, price=price, vykladka=vykladka)
|
||||
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
|
||||
|
||||
##VAR - na zaklade conf. muzeme jako prvni posilat MARKET order
|
||||
if safe_get(state.vars, "first_buy_market") == True:
|
||||
#pri defenzivnim rezimu pouzivame vzdy LIMIT order
|
||||
if is_defensive_mode():
|
||||
state.ilog(e="DEF mode on, odesilame jako prvni limitku")
|
||||
state.buy_l(price=price, size=qty)
|
||||
else:
|
||||
state.ilog(e="Posilame jako prvni MARKET order")
|
||||
state.buy(size=qty)
|
||||
else:
|
||||
state.buy_l(price=price, size=qty)
|
||||
print("prvni limitka na aktuální cenu. Další podle křivky", price, qty)
|
||||
for i in range(0,vykladka-1):
|
||||
price = price2dec(float(price - get_tick(price, curve[i])))
|
||||
if price == last_price:
|
||||
qty = qty + int(state.vars.chunk)
|
||||
else:
|
||||
state.buy_l(price=price, size=qty)
|
||||
#print(i,"BUY limitka - delta",curve[i]," cena:", price, "mnozstvi:", qty)
|
||||
qty = int(state.vars.chunk)
|
||||
last_price = price
|
||||
state.vars.blockbuy = 1
|
||||
state.vars.jevylozeno = 1
|
||||
|
||||
#CBAR protection, only 1x order per CBAR - then wait until another confirmed bar
|
||||
if state.vars.blockbuy == 1 and state.rectype == RecordType.CBAR:
|
||||
if state.bars.confirmed[-1] == 0:
|
||||
print("OCHR: multibuy protection. waiting for next bar")
|
||||
return 0
|
||||
# pop potvrzeni jeste jednou vratime (aby se nekoupilo znova, je stale ten stejny bar)
|
||||
# a pak dalsi vejde az po minticku
|
||||
else:
|
||||
# pro vykladaci
|
||||
state.vars.blockbuy = 0
|
||||
return 0
|
||||
|
||||
state.ilog(e="-----")
|
||||
|
||||
#EMA INDICATOR -
|
||||
#plnime MAcko - nyni posilame jen N poslednich hodnot
|
||||
#zaroven osetrujeme pripady, kdy je malo dat a ukladame nulu
|
||||
try:
|
||||
ma = int(state.vars.MA)
|
||||
#poslednich ma hodnot
|
||||
source = state.bars.close[-ma:] #state.bars.vwap
|
||||
ema_value = ema(source, ma)
|
||||
state.indicators.ema[-1]=trunc(ema_value[-1],3)
|
||||
except Exception as e:
|
||||
state.ilog(e="EMA ukladame 0", message=str(e)+format_exc())
|
||||
#state.indicators.ema[-1]=0
|
||||
|
||||
#RSI14 INDICATOR
|
||||
try:
|
||||
##mame v atributech nastaveni?
|
||||
rsi_dont_buy_above = safe_get(state.vars, "rsi_dont_buy_above",50)
|
||||
rsi_buy_signal_conf = safe_get(state.vars, "rsi_buy_signal_below",40)
|
||||
rsi_buy_signal = False
|
||||
rsi_dont_buy = False
|
||||
rsi_length = 14
|
||||
source = state.bars.close #[-rsi_length:] #state.bars.vwap
|
||||
rsi_res = rsi(source, rsi_length)
|
||||
rsi_value = trunc(rsi_res[-1],3)
|
||||
state.indicators.RSI14[-1]=rsi_value
|
||||
rsi_dont_buy = rsi_value > rsi_dont_buy_above
|
||||
rsi_buy_signal = rsi_value < rsi_buy_signal_conf
|
||||
state.ilog(e=f"RSI {rsi_length=} {rsi_value=} {rsi_dont_buy=} {rsi_buy_signal=}", rsi_indicator=state.indicators.RSI14[-5:])
|
||||
except Exception as e:
|
||||
state.ilog(e=f"RSI {rsi_length=} ukladame 0", message=str(e)+format_exc())
|
||||
#state.indicators.RSI14[-1]=0
|
||||
|
||||
|
||||
#SLOPE INDICATOR
|
||||
#úhel stoupání a klesání vyjádřený mezi -1 až 1
|
||||
#pravý bod přímky je aktuální cena, levý je průměr X(lookback offset) starších hodnot od slope_lookback.
|
||||
#obsahuje statický indikátor (angle) pro vizualizaci
|
||||
try:
|
||||
slope = 99
|
||||
slope_lookback = int(state.vars.slope_lookback)
|
||||
minimum_slope = float(state.vars.minimum_slope)
|
||||
lookback_offset = int(state.vars.lookback_offset)
|
||||
|
||||
if len(state.bars.close) > (slope_lookback + lookback_offset):
|
||||
array_od = slope_lookback + lookback_offset
|
||||
array_do = slope_lookback
|
||||
lookbackprice_array = state.bars.vwap[-array_od:-array_do]
|
||||
#obycejný prumer hodnot
|
||||
lookbackprice = round(sum(lookbackprice_array)/lookback_offset,3)
|
||||
|
||||
#výpočet úhlu
|
||||
slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100
|
||||
slope = round(slope, 4)
|
||||
state.indicators.slope[-1]=slope
|
||||
|
||||
#angle je ze slope
|
||||
state.statinds.angle = dict(time=state.bars.time[-1], price=state.bars.close[-1], lookbacktime=state.bars.time[-slope_lookback], lookbackprice=lookbackprice, minimum_slope=minimum_slope)
|
||||
|
||||
#slope MA vyrovna vykyvy ve slope, dále pracujeme se slopeMA
|
||||
slope_MA_length = 5
|
||||
source = state.indicators.slope[-slope_MA_length:]
|
||||
slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap
|
||||
slopeMA = slopeMAseries[-1]
|
||||
state.indicators.slopeMA[-1]=slopeMA
|
||||
|
||||
state.ilog(e=f"{slope=} {slopeMA=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:], last_slopesMA=state.indicators.slopeMA[-10:])
|
||||
|
||||
#dale pracujeme s timto MAckovanym slope
|
||||
slope = slopeMA
|
||||
else:
|
||||
#pokud plnime historii musime ji plnit od zacatku, vsehcny idenitifkatory maji spolecny time
|
||||
#kvuli spravnemu zobrazovani na gui
|
||||
state.indicators.slopeMA[-1]=0
|
||||
#state.indicators.slopeMA.append(0)
|
||||
state.ilog(e="Slope - not enough data", slope_lookback=slope_lookback, slope=state.indicators.slope, slopeMA=state.indicators.slopeMA)
|
||||
except Exception as e:
|
||||
print("Exception in NEXT Slope Indicator section", str(e))
|
||||
state.ilog(e="EXCEPTION", msg="Exception in Slope Indicator section" + str(e) + format_exc())
|
||||
|
||||
print("is falling",isfalling(state.indicators.ema,state.vars.Trend))
|
||||
print("is rising",isrising(state.indicators.ema,state.vars.Trend))
|
||||
|
||||
consolidation()
|
||||
|
||||
#HLAVNI ITERACNI LOG JESTE PRED AKCI - obsahuje aktualni hodnoty vetsiny parametru
|
||||
#TODO sem pridat aktualni hodnoty vsech indikatoru
|
||||
lp = state.interface.get_last_price(symbol=state.symbol)
|
||||
state.ilog(e="ENTRY", msg=f"LP:{lp} P:{state.positions}/{round(float(state.avgp),3)} profit:{round(float(state.profit),2)} Trades:{len(state.tradeList)} DEF:{str(is_defensive_mode())}", last_price=lp, data=data, stratvars=state.vars)
|
||||
|
||||
#SLOPE ANGLE PROTECTIONs
|
||||
#slope zachycuje rychle sestupy, pripadne zrusi nakupni objednavky
|
||||
if slope < minimum_slope or rsi_dont_buy: # or slopeMA<maxSlopeMA:
|
||||
print("OCHRANA SLOPE or RSI TOO HIGH")
|
||||
# if slopeMA<maxSlopeMA:
|
||||
# state.ilog(e="Slope MA too high "+str(slopeMA)+" max:"+str(maxSlopeMA))
|
||||
state.ilog(e=f"Slope or RSI too high {slope=} {rsi_value=}")
|
||||
if len(state.vars.pendingbuys)>0:
|
||||
print("CANCEL PENDINGBUYS")
|
||||
#ic(state.vars.pendingbuys)
|
||||
res = asyncio.run(state.cancel_pending_buys())
|
||||
#ic(state.vars.pendingbuys)
|
||||
state.ilog(e="Rusime pendingbuyes", pb=state.vars.pendingbuys, res=res)
|
||||
print("slope", slope)
|
||||
print("min slope", minimum_slope)
|
||||
|
||||
if state.vars.jevylozeno == 0:
|
||||
print("Neni vylozeno, muzeme testovat nakup")
|
||||
|
||||
#pokud je defenziva, buy triggeruje defenzivni def_trend
|
||||
#TBD
|
||||
|
||||
#NOVY BUY SIGNAL z RSI < 35
|
||||
#buy_signal = isfalling(state.indicators.ema,state.vars.Trend)
|
||||
buy_signal = rsi_buy_signal
|
||||
|
||||
if buy_signal and slope > minimum_slope and not rsi_dont_buy:
|
||||
vyloz()
|
||||
|
||||
## testuje aktualni cenu od nejvyssi visici limitky
|
||||
##toto spoustet jednou za X iterací - ted to jede pokazdé
|
||||
#pokud to ujede o vic, rusime limitky
|
||||
#TODO: zvazit jestli nechat i pri otevrenych pozicich, zatim nechavame
|
||||
#TODO int(int(state.oa.poz)/int(state.variables.chunk)) > X
|
||||
|
||||
#TODO predelat mechanismus ticků (zrelativizovat), aby byl pouzitelny na tituly s ruznou cenou
|
||||
#TODO spoustet 1x za X iteraci nebo cas
|
||||
if state.vars.jevylozeno == 1:
|
||||
#pokud mame vylozeno a cena je vetsi nez tick2reset
|
||||
if len(state.vars.pendingbuys)>0:
|
||||
maxprice = max(state.vars.pendingbuys.values())
|
||||
print("max cena v orderbuys", maxprice)
|
||||
if state.interface.get_last_price(state.symbol) > float(maxprice) + get_tick(maxprice, float(state.vars.ticks2reset)):
|
||||
##TODO toto nejak vymyslet - duplikovat?
|
||||
res = asyncio.run(state.cancel_pending_buys())
|
||||
state.ilog(e=f"UJELO to. Rusime PB", msg=f"{state.vars.ticks2reset=}", pb=state.vars.pendingbuys)
|
||||
|
||||
#PENDING BUYS SPENT - PART
|
||||
#pokud mame vylozeno a pendingbuys se vyklepou a
|
||||
# 1 vykladame idned znovu
|
||||
# vyloz()
|
||||
# 2 nebo - počkat zase na signál a pokračovat dál
|
||||
# state.vars.blockbuy = 0
|
||||
# state.vars.jevylozeno = 0
|
||||
# 3 nebo - počkat na signál s enablovaným lastbuy indexem (tzn. počká nutně ještě pár barů)
|
||||
#podle BT vyhodnejsi vylozit ihned
|
||||
if len(state.vars.pendingbuys) == 0:
|
||||
state.vars.blockbuy = 0
|
||||
state.vars.jevylozeno = 0
|
||||
state.ilog(e="PB se vyklepaly nastavujeme: neni vylozeno", jevylozeno=state.vars.jevylozeno)
|
||||
|
||||
#TODO toto dodelat konzolidaci a mozna lock na limitku a pendingbuys a jevylozeno ??
|
||||
|
||||
#kdykoliv se muze notifikace ztratit
|
||||
# - pendingbuys - vsechny open orders buy
|
||||
# - limitka - open order sell
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pokud je vylozeno a mame pozice a neexistuje limitka - pak ji vytvorim
|
||||
# if int(state.oe.poz)>0 and state.oe.limitka == 0:
|
||||
# #pro jistotu updatujeme pozice
|
||||
# state.oe.avgp, state.oe.poz = state.oe.pos()
|
||||
# if int(state.oe.poz) > 0:
|
||||
# cena = round(float(state.oe.avgp) + float(state.oe.stratvars["profit"]),2)
|
||||
# print("BUGF: limitka neni vytvarime, a to za cenu",cena,"mnozstvi",state.oe.poz)
|
||||
# print("aktuzalni ltp",ltp.price[state.oe.symbol])
|
||||
|
||||
# try:
|
||||
# state.oe.limitka = state.oe.sell_noasync(cena, state.oe.poz)
|
||||
# print("vytvorena limitka", state.oe.limitka)
|
||||
# except Exception as e:
|
||||
# print("Neslo vytvorit profitku. Problem,ale jedeme dal",str(e))
|
||||
# pass
|
||||
# ##raise Exception(e)
|
||||
|
||||
print(10*"*","NEXT STOP",10*"*")
|
||||
|
||||
def init(state: StrategyState):
|
||||
#place to declare new vars
|
||||
print("INIT v main",state.name)
|
||||
state.indicators['ema'] = []
|
||||
state.indicators['slope'] = []
|
||||
state.indicators['slopeMA'] = []
|
||||
state.indicators['RSI14'] = []
|
||||
#static indicators - those not series based
|
||||
state.statinds['angle'] = dict(minimum_slope=state.vars["minimum_slope"])
|
||||
state.vars["ticks2reset_backup"] = state.vars.ticks2reset
|
||||
|
||||
def main():
|
||||
# try:
|
||||
# strat_settings = tomli.loads("]] this is invalid TOML [[")
|
||||
# except tomli.TOMLDecodeError:
|
||||
# print("Yep, definitely not valid.")
|
||||
|
||||
#strat_settings = dict_replace_value(strat_settings, "None", None)
|
||||
|
||||
name = os.path.basename(__file__)
|
||||
se = Event()
|
||||
pe = Event()
|
||||
s = StrategyOrderLimitVykladaciNormalized(name = name, symbol = "BAC", account=Account.ACCOUNT1, next=next, init=init, stratvars=stratvars, open_rush=10, close_rush=0, pe=pe, se=se, ilog_save=True)
|
||||
s.set_mode(mode = Mode.BT,
|
||||
debug = False,
|
||||
start = datetime(2023, 4, 14, 10, 42, 0, 0, tzinfo=zoneNY),
|
||||
end = datetime(2023, 4, 14, 14, 35, 0, 0, tzinfo=zoneNY),
|
||||
cash=100000)
|
||||
|
||||
#na sekundovem baru nezaokrouhlovat MAcko
|
||||
s.add_data(symbol="BAC",rectype=RecordType.BAR,timeframe=2,minsize=100,update_ltp=True,align=StartBarAlign.ROUND,mintick=0, exthours=False)
|
||||
#s.add_data(symbol="C",rectype=RecordType.BAR,timeframe=1,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=0)
|
||||
|
||||
s.start()
|
||||
print("zastavujeme")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
90
v2realbot/archived/ENTRY_backtest_strategy.py
Normal file
90
v2realbot/archived/ENTRY_backtest_strategy.py
Normal file
@ -0,0 +1,90 @@
|
||||
from strategy.base import Strategy, StrategyState
|
||||
from strategy.strategyOrderLimit import StrategyOrderLimit
|
||||
from enums import RecordType, StartBarAlign, Mode
|
||||
from config import API_KEY, SECRET_KEY, MAX_BATCH_SIZE, PAPER
|
||||
from indicators import ema
|
||||
from rich import print
|
||||
from utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY
|
||||
from datetime import datetime
|
||||
from icecream import install, ic
|
||||
install()
|
||||
ic.configureOutput(includeContext=True)
|
||||
#ic.disable()
|
||||
""""
|
||||
Simple strategie pro test backtesting
|
||||
"""
|
||||
|
||||
def next(data, state: StrategyState):
|
||||
print(10*"*","NEXT START",10*"*")
|
||||
#ic(state.avgp, state.positions)
|
||||
#ic(state.vars.limitka)
|
||||
#ic(state.vars.lastbuyindex)
|
||||
#ic(data)
|
||||
#print("last trade price")
|
||||
#print(state.interface.get_last_price("BAC"))
|
||||
#print(state.vars.novaprom)
|
||||
#print("trades history", state.trades)
|
||||
#print("bar history", state.bars)
|
||||
#print("ltp", ltp.price["BAC"], ltp.time["BAC"])
|
||||
|
||||
#TODO indikátory ukládat do vlastní historie - tu pak automaticky zobrazuje backtester graf
|
||||
|
||||
#TODO ema = state.indicators.ema a pouzivat nize ema, zjistit jestli bude fungovat
|
||||
|
||||
try:
|
||||
state.indicators.ema = ema(state.bars.hlcc4, state.vars.MA) #state.bars.vwap
|
||||
#trochu prasarna, EMAcko trunc na 3 mista - kdyz se osvedci, tak udelat efektivne
|
||||
state.indicators.ema = [trunc(i,3) for i in state.indicators.ema]
|
||||
#ic(state.vars.MA, state.vars.Trend, state.indicators.ema[-5:])
|
||||
except Exception as e:
|
||||
print("No data for MA yet", str(e))
|
||||
|
||||
print("is falling",isfalling(state.indicators.ema,state.vars.Trend))
|
||||
print("is rising",isrising(state.indicators.ema,state.vars.Trend))
|
||||
|
||||
#ZDE JSEM SKONCIL
|
||||
#nejprve zacit s BARy
|
||||
|
||||
#TODO vyzkoušet limit buy - vetsina z nakupu by se dala koupit o cent dva mene
|
||||
#proto dodělat LTP pro BT, neco jako get_last_price(self.state.time)
|
||||
|
||||
|
||||
##TODO vyzkouset hlidat si sell objednavku sam na zaklade tradu
|
||||
# v pripade ze to jde nahoru(is rising - nebo jiny indikator) tak neprodavat
|
||||
#vyuzit CBARy k tomuto .....
|
||||
#triggerovat buy treba po polovine CBARu, kdyz se cena bude rovnat nebo bude nizsi nez low
|
||||
#a hned na to (po potvrzeni) hlidat sell +0.01 nebo kdyz roste nechat rust.vyzkouset na LIVE
|
||||
|
||||
if isfalling(state.indicators.ema,state.vars.Trend) and data['index'] > state.vars.lastbuyindex+state.vars.Trend: #and state.blockbuy == 0
|
||||
print("BUY MARKET")
|
||||
#ic(data['updated'])
|
||||
#ic(state.time)
|
||||
state.buy_l()
|
||||
|
||||
|
||||
print(10*"*","NEXT STOP",10*"*")
|
||||
|
||||
def init(state: StrategyState):
|
||||
#place to declare new vars
|
||||
print("INIT v main",state.name)
|
||||
state.vars['novaprom'] = 4
|
||||
state.indicators['ema'] = []
|
||||
|
||||
def main():
|
||||
stratvars = AttributeDict(maxpozic = 2400, chunk = 400, MA = 6, Trend = 7, profit = 0.03, lastbuyindex=-6, pendingbuys={},limitka = None)
|
||||
|
||||
s = StrategyOrderLimit(name = "BackTEST", symbol = "KO", next=next, init=init, stratvars=stratvars, debug=False)
|
||||
s.set_mode(mode = Mode.BT,
|
||||
start = datetime(2023, 2, 23, 9, 30, 0, 0, tzinfo=zoneNY),
|
||||
end = datetime(2023, 2, 23, 16, 00, 0, 0, tzinfo=zoneNY),
|
||||
cash=100000)
|
||||
|
||||
#na sekundovem baru nezaokrouhlovat MAcko
|
||||
s.add_data(symbol="KO",rectype=RecordType.BAR,timeframe=30,filters=None,update_ltp=True,align=StartBarAlign.RANDOM,mintick=0)
|
||||
#s.add_data(symbol="C",rectype=RecordType.BAR,timeframe=1,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=0)
|
||||
|
||||
s.start()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
99
v2realbot/archived/ENTRY_backtest_strategyKOKA-ok.py
Normal file
99
v2realbot/archived/ENTRY_backtest_strategyKOKA-ok.py
Normal file
@ -0,0 +1,99 @@
|
||||
# import os,sys
|
||||
# sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
from v2realbot.strategy.base import Strategy, StrategyState
|
||||
from v2realbot.strategy.StrategyOrderLimitKOKA import StrategyOrderLimitKOKA
|
||||
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode
|
||||
from v2realbot.indicators.indicators import ema
|
||||
from rich import print
|
||||
from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY
|
||||
from datetime import datetime
|
||||
from icecream import install, ic
|
||||
import os
|
||||
install()
|
||||
ic.configureOutput(includeContext=True)
|
||||
#ic.disable()
|
||||
""""
|
||||
Simple strategie LIMIT buy a lIMIT SELL working ok
|
||||
|
||||
DOkupovaci strategie, nakupuje dalsi pozice až po dalším signálu.
|
||||
|
||||
POZOR nekontroluje se maximální pozice - tzn. nejvic se vycerpalo 290, ale prezila kazdy den.
|
||||
Dobrá defenzivní pri nastaveni
|
||||
30s maxpozic = 290,chunk = 10,MA = 6,Trend = 6,profit = 0.02,
|
||||
"""
|
||||
stratvars = AttributeDict(maxpozic = 250,
|
||||
chunk = 10,
|
||||
MA = 6,
|
||||
Trend = 6,
|
||||
profit = 0.02,
|
||||
lastbuyindex=-6,
|
||||
pendingbuys={},
|
||||
limitka = None)
|
||||
|
||||
def next(data, state: StrategyState):
|
||||
print(10*"*","NEXT START",10*"*")
|
||||
#ic(state.avgp, state.positions)
|
||||
#ic(state.vars.limitka)
|
||||
#ic(state.vars.lastbuyindex)
|
||||
#ic(data)
|
||||
#print("last trade price")
|
||||
#print(state.interface.get_last_price("BAC"))
|
||||
#print(state.vars.novaprom)
|
||||
#print("trades history", state.trades)
|
||||
#print("bar history", state.bars)
|
||||
#print("ltp", ltp.price["BAC"], ltp.time["BAC"])
|
||||
|
||||
#TODO indikátory ukládat do vlastní historie - tu pak automaticky zobrazuje backtester graf
|
||||
|
||||
#TODO ema = state.indicators.ema a pouzivat nize ema, zjistit jestli bude fungovat
|
||||
|
||||
try:
|
||||
state.indicators.ema = ema(state.bars.hlcc4, state.vars.MA) #state.bars.vwap
|
||||
#trochu prasarna, EMAcko trunc na 3 mista - kdyz se osvedci, tak udelat efektivne
|
||||
state.indicators.ema = [trunc(i,3) for i in state.indicators.ema]
|
||||
#ic(state.vars.MA, state.vars.Trend, state.indicators.ema[-5:])
|
||||
except Exception as e:
|
||||
print("No data for MA yet", str(e))
|
||||
|
||||
print("is falling",isfalling(state.indicators.ema,state.vars.Trend))
|
||||
print("is rising",isrising(state.indicators.ema,state.vars.Trend))
|
||||
|
||||
#ZDE JSEM SKONCIL
|
||||
#nejprve zacit s BARy
|
||||
|
||||
#TODO vyzkoušet limit buy - vetsina z nakupu by se dala koupit o cent dva mene
|
||||
#proto dodělat LTP pro BT, neco jako get_last_price(self.state.time)
|
||||
if isfalling(state.indicators.ema,state.vars.Trend) and data['index'] > state.vars.lastbuyindex+state.vars.Trend: #and state.blockbuy == 0
|
||||
print("BUY MARKET")
|
||||
#ic(data['updated'])
|
||||
#ic(state.time)
|
||||
state.buy_l()
|
||||
|
||||
|
||||
print(10*"*","NEXT STOP",10*"*")
|
||||
|
||||
def init(state: StrategyState):
|
||||
#place to declare new vars
|
||||
print("INIT v main",state.name)
|
||||
state.vars['novaprom'] = 4
|
||||
state.indicators['ema'] = []
|
||||
|
||||
def main():
|
||||
name = os.path.basename(__file__)
|
||||
s = StrategyOrderLimitKOKA(name = name, symbol = "BAC", next=next, init=init, stratvars=stratvars, open_rush=30, close_rush=0)
|
||||
s.set_mode(mode = Mode.PAPER,
|
||||
debug = False,
|
||||
start = datetime(2023, 3, 6, 9, 30, 0, 0, tzinfo=zoneNY),
|
||||
end = datetime(2023, 3, 9, 16, 0, 0, 0, tzinfo=zoneNY),
|
||||
cash=100000)
|
||||
|
||||
#na sekundovem baru nezaokrouhlovat MAcko
|
||||
s.add_data(symbol="BAC",rectype=RecordType.BAR,timeframe=30,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=0)
|
||||
#s.add_data(symbol="C",rectype=RecordType.BAR,timeframe=1,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=0)
|
||||
|
||||
s.start()
|
||||
print("zastavujeme")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
502
v2realbot/archived/ENTRY_backtest_strategyVykladaci.py
Normal file
502
v2realbot/archived/ENTRY_backtest_strategyVykladaci.py
Normal file
@ -0,0 +1,502 @@
|
||||
import os,sys
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
from v2realbot.strategy.base import StrategyState
|
||||
from v2realbot.strategy.StrategyOrderLimitVykladaci import StrategyOrderLimitVykladaci
|
||||
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, OrderSide, OrderType
|
||||
from v2realbot.indicators.indicators import ema
|
||||
from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY, price2dec, print, safe_get
|
||||
from datetime import datetime
|
||||
#from icecream import install, ic
|
||||
#from rich import print
|
||||
from threading import Event
|
||||
from msgpack import packb, unpackb
|
||||
import asyncio
|
||||
import os
|
||||
from traceback import format_exc
|
||||
|
||||
# install()
|
||||
# ic.configureOutput(includeContext=True)
|
||||
#ic.disable()
|
||||
|
||||
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
""""
|
||||
Vykladaci strategie refactored z původního engine
|
||||
Params:
|
||||
(maxpozic = 200, chunk = 50, MA = 6, Trend = 6, profit = 0.02, lastbuyindex=-6, pendingbuys={},limitka = None, jevylozeno=0, ticks2reset = 0.04, blockbuy=0)
|
||||
|
||||
Pozor na symbolu nesmi byt dalsi cizí otevrene objednavky:
|
||||
Pravidelny konzolidacni process da SELL order da do limitka, BUY - do pole pendingbuys
|
||||
|
||||
consolidation_bar_count - pocet baru po kterych se triggeruje konzolidační proces
|
||||
|
||||
Více nakupuje oproti Dokupovaci. Tady vylozime a nakupujeme 5 pozic hned. Pri dokupovaci se dokupuje, az na zaklade dalsich triggeru.
|
||||
Do budoucna vice ridit nakupy pri klesani - napr. vyložení jen 2-3 pozic a další dokupy až po triggeru.
|
||||
#
|
||||
"""
|
||||
stratvars = AttributeDict(maxpozic = 400,
|
||||
def_mode_from = 200,
|
||||
chunk = 10,
|
||||
MA = 2,
|
||||
Trend = 2,
|
||||
profit = 0.02,
|
||||
def_profit = 0.01,
|
||||
lastbuyindex=-6,
|
||||
pendingbuys={},
|
||||
limitka = None,
|
||||
limitka_price = None,
|
||||
jevylozeno=0,
|
||||
vykladka=5,
|
||||
curve = [0.01, 0.01, 0.01, 0, 0.02, 0.02, 0.01,0.01, 0.01,0.03, 0.01, 0.01, 0.01,0.04, 0.01,0.01, 0.01,0.05, 0.01,0.01, 0.01,0.01, 0.06,0.01, 0.01,0.01, 0.01],
|
||||
curve_def = [0.02, 0.02, 0.02, 0, 0, 0.02, 0, 0, 0, 0.02],
|
||||
blockbuy = 0,
|
||||
ticks2reset = 0.04,
|
||||
consolidation_bar_count = 10,
|
||||
slope_lookback = 300,
|
||||
lookback_offset = 20,
|
||||
minimum_slope = -0.05,
|
||||
first_buy_market = False
|
||||
)
|
||||
##toto rozparsovat a strategii spustit stejne jako v main
|
||||
toml_string = """
|
||||
[[strategies]]
|
||||
name = "V1 na BAC"
|
||||
symbol = "BAC"
|
||||
script = "ENTRY_backtest_strategyVykladaci"
|
||||
class = "StrategyOrderLimitVykladaci"
|
||||
open_rush = 0
|
||||
close_rush = 0
|
||||
[strategies.stratvars]
|
||||
maxpozic = 200
|
||||
chunk = 10
|
||||
MA = 6
|
||||
Trend = 5
|
||||
profit = 0.02
|
||||
lastbuyindex=-6
|
||||
pendingbuys={}
|
||||
limitka = "None"
|
||||
jevylozeno=0
|
||||
vykladka=5
|
||||
curve = [0.01, 0.01, 0.01,0.01, 0.02, 0.01,0.01, 0.01,0.03, 0.01, 0.01, 0.01,0.04, 0.01,0.01, 0.01,0.05, 0.01,0.01, 0.01,0.01, 0.06,0.01, 0.01,0.01, 0.01]
|
||||
blockbuy = 0
|
||||
ticks2reset = 0.04
|
||||
[[strategies.add_data]]
|
||||
symbol="BAC"
|
||||
rectype="bar"
|
||||
timeframe=5
|
||||
update_ltp=true
|
||||
align="round"
|
||||
mintick=0
|
||||
minsize=100
|
||||
exthours=false
|
||||
"""
|
||||
|
||||
def next(data, state: StrategyState):
|
||||
print(10*"*","NEXT START",10*"*")
|
||||
#ic(state.avgp, state.positions)
|
||||
#ic(state.vars)
|
||||
#ic(data)
|
||||
|
||||
#
|
||||
def is_defensive_mode():
|
||||
akt_pozic = int(state.positions)
|
||||
max_pozic = int(state.vars.maxpozic)
|
||||
def_mode_from = safe_get(state.vars, "def_mode_from",max_pozic/2)
|
||||
if akt_pozic >= int(def_mode_from):
|
||||
state.ilog(e=f"DEFENSIVE mode ACTIVE {state.vars.def_mode_from=}", msg=state.positions)
|
||||
return True
|
||||
else:
|
||||
state.ilog(e=f"STANDARD mode ACTIVE {state.vars.def_mode_from=}", msg=state.positions)
|
||||
return False
|
||||
|
||||
def get_limitka_price():
|
||||
def_profit = safe_get(state.vars, "def_profit",state.vars.profit)
|
||||
if is_defensive_mode():
|
||||
return price2dec(float(state.avgp)+float(def_profit))
|
||||
else:
|
||||
return price2dec(float(state.avgp)+float(state.vars.profit))
|
||||
|
||||
def consolidation():
|
||||
##CONSOLIDATION PART - moved here, musí být před nákupem, jinak to dělalo nepořádek v pendingbuys
|
||||
#docasne zkusime konzolidovat i kdyz neni vylozeno (aby se srovnala limitka ve vsech situacich)
|
||||
if state.vars.jevylozeno == 1 or 1==1:
|
||||
##CONSOLIDATION PART kazdy Nty bar dle nastaveni
|
||||
if int(data["index"])%int(state.vars.consolidation_bar_count) == 0:
|
||||
print("***CONSOLIDATION ENTRY***")
|
||||
state.ilog(e="CONSOLIDATION ENTRY ***")
|
||||
|
||||
orderlist = state.interface.get_open_orders(symbol=state.symbol, side=None)
|
||||
#pro jistotu jeste dotahneme aktualni pozice
|
||||
state.avgp, state.positions = state.interface.pos()
|
||||
|
||||
#print(orderlist)
|
||||
pendingbuys_new = {}
|
||||
limitka_old = state.vars.limitka
|
||||
#print("Puvodni LIMITKA", limitka_old)
|
||||
#zaciname s cistym stitem
|
||||
state.vars.limitka = None
|
||||
state.vars.limitka_price = None
|
||||
limitka_found = False
|
||||
limitka_qty = 0
|
||||
limitka_filled_qty = 0
|
||||
for o in orderlist:
|
||||
if o.side == OrderSide.SELL:
|
||||
|
||||
if limitka_found:
|
||||
state.ilog(e="nalezeno vicero sell objednavek, bereme prvni, ostatni - rusime")
|
||||
result=state.interface.cancel(o.id)
|
||||
state.ilog(e="zrusena objednavka"+str(o.id), message=result)
|
||||
continue
|
||||
|
||||
#print("Nalezena LIMITKA")
|
||||
limitka_found = True
|
||||
state.vars.limitka = o.id
|
||||
state.vars.limitka_price = o.limit_price
|
||||
limitka_qty = int(o.qty)
|
||||
limitka_filled_qty = int(o.filled_qty)
|
||||
|
||||
#aktualni mnozstvi = puvodni minus filled
|
||||
if limitka_filled_qty is not None:
|
||||
print("prepocitavam filledmnozstvi od limitka_qty a filled_qty", limitka_qty, limitka_filled_qty)
|
||||
limitka_qty = int(limitka_qty) - int(limitka_filled_qty)
|
||||
##TODO sem pridat upravu ceny
|
||||
if o.side == OrderSide.BUY and o.order_type == OrderType.LIMIT:
|
||||
pendingbuys_new[str(o.id)]=float(o.limit_price)
|
||||
|
||||
state.ilog(e="Konzolidace limitky", msg=f"stejna:{(str(limitka_old)==str(state.vars.limitka))}", limitka_old=str(limitka_old), limitka_new=str(state.vars.limitka), limitka_new_price=state.vars.limitka_price, limitka_qty=limitka_qty, limitka_filled_qty=limitka_filled_qty)
|
||||
|
||||
#pokud mame
|
||||
|
||||
#neni limitka, ale mela by byt - vytváříme ji
|
||||
if int(state.positions) > 0 and state.vars.limitka is None:
|
||||
state.ilog(e="Limitka neni, ale mela by být.", msg=f"{state.positions=}")
|
||||
price=get_limitka_price()
|
||||
state.vars.limitka = asyncio.run(state.interface.sell_l(price=price, size=int(state.positions)))
|
||||
state.vars.limitka_price = price
|
||||
if state.vars.limitka == -1:
|
||||
state.ilog(e="Vytvoreni limitky neprobehlo, vracime None", msg=f"{state.vars.limitka=}")
|
||||
state.vars.limitka = None
|
||||
state.vars.limitka_price = None
|
||||
else:
|
||||
state.ilog(e="Vytvořena nová limitka", limitka=str(state.vars.limitka), limtka_price=state.vars.limitka_price, qty=state.positions)
|
||||
|
||||
#existuje a nesedi mnozstvi nebo cena
|
||||
elif state.vars.limitka is not None and int(state.positions) > 0 and ((int(state.positions) != int(limitka_qty)) or float(state.vars.limitka_price) != float(get_limitka_price())):
|
||||
#limitka existuje, ale spatne mnostvi - updatujeme
|
||||
state.ilog(e=f"Limitka existuje, ale spatne mnozstvi nebo CENA - updatujeme", msg=f"{state.positions=} {limitka_qty=} {state.vars.limitka_price=}", nastavenacena=state.vars.limitka_price, spravna_cena=get_limitka_price(), pos=state.positions, limitka_qty=limitka_qty)
|
||||
#snad to nespadne, kdyztak pridat exception handling
|
||||
puvodni = state.vars.limitka
|
||||
#TBD zde odchytit nejak result
|
||||
state.vars.limitka = asyncio.run(state.interface.repl(price=get_limitka_price(), orderid=state.vars.limitka, size=int(state.positions)))
|
||||
|
||||
if state.vars.limitka == -1:
|
||||
state.ilog(e="Replace limitky neprobehl, vracime puvodni", msg=f"{state.vars.limitka=}", puvodni=puvodni)
|
||||
state.vars.limitka = puvodni
|
||||
else:
|
||||
limitka_qty = int(state.positions)
|
||||
state.ilog(e="Změněna limitka", limitka=str(state.vars.limitka), limitka_price=state.vars.limitka_price, limitka_qty=limitka_qty)
|
||||
|
||||
#tbd pokud se bude vyskytovat pak pridat ještě konzolidaci ceny limitky
|
||||
|
||||
if pendingbuys_new != state.vars.pendingbuys:
|
||||
state.ilog(e="Rozdilna PB prepsana", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys)
|
||||
print("ROZDILNA PENDINGBUYS přepsána")
|
||||
print("OLD",state.vars.pendingbuys)
|
||||
state.vars.pendingbuys = unpackb(packb(pendingbuys_new))
|
||||
print("NEW", state.vars.pendingbuys)
|
||||
else:
|
||||
print("PENDINGBUYS sedí - necháváme", state.vars.pendingbuys)
|
||||
state.ilog(e="PB sedi nechavame", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys)
|
||||
print("OLD jevylozeno", state.vars.jevylozeno)
|
||||
if len(state.vars.pendingbuys) > 0:
|
||||
state.vars.jevylozeno = 1
|
||||
else:
|
||||
state.vars.jevylozeno = 0
|
||||
print("NEW jevylozeno", state.vars.jevylozeno)
|
||||
state.ilog(e="Nove jevylozeno", msg=state.vars.jevylozeno)
|
||||
|
||||
#print(limitka)
|
||||
#print(pendingbuys_new)
|
||||
#print(pendingbuys)
|
||||
#print(len(pendingbuys))
|
||||
#print(len(pendingbuys_new))
|
||||
#print(jevylozeno)
|
||||
print("***CONSOLIDATION EXIT***")
|
||||
state.ilog(e="CONSOLIDATION EXIT ***")
|
||||
else:
|
||||
state.ilog(e="No time for consolidation", msg=data["index"])
|
||||
print("no time for consolidation", data["index"])
|
||||
|
||||
#mozna presunout o level vys
|
||||
def vyloz():
|
||||
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
|
||||
#curve = [0.01, 0.01, 0, 0, 0.01, 0, 0, 0, 0.02, 0, 0, 0, 0.03, 0,0,0,0,0, 0.02, 0,0,0,0,0,0, 0.02]
|
||||
curve = state.vars.curve
|
||||
##defenzivni krivka pro
|
||||
curve_def = state.vars.curve_def
|
||||
#vykladani po 5ti kusech, když zbývají 2 a méně, tak děláme nový výklad
|
||||
vykladka = state.vars.vykladka
|
||||
#kolik muzu max vylozit
|
||||
kolikmuzu = int((int(state.vars.maxpozic) - int(state.positions))/int(state.vars.chunk))
|
||||
akt_pozic = int(state.positions)
|
||||
max_pozic = int(state.vars.maxpozic)
|
||||
|
||||
#mame polovinu a vic vylozeno, pouzivame defenzicni krivku
|
||||
if is_defensive_mode():
|
||||
state.ilog(e="DEF: Pouzivame defenzivni krivku", akt_pozic=akt_pozic, max_pozic=max_pozic, curve_def=curve_def)
|
||||
curve = curve_def
|
||||
#zaroven docasne menime ticks2reset na defenzivni 0.06
|
||||
state.vars.ticks2reset = 0.06
|
||||
state.ilog(e="DEF: Menime tick2reset na 0.06", ticks2reset=state.vars.ticks2reset, ticks2reset_backup=state.vars.ticks2reset_backup)
|
||||
else:
|
||||
#vracime zpet, pokud bylo zmeneno
|
||||
if state.vars.ticks2reset != state.vars.ticks2reset_backup:
|
||||
state.vars.ticks2reset = state.vars.ticks2reset_backup
|
||||
state.ilog(e="DEF: Menime tick2reset zpet na"+str(state.vars.ticks2reset), ticks2reset=state.vars.ticks2reset, ticks2reset_backup=state.vars.ticks2reset_backup)
|
||||
|
||||
if kolikmuzu < vykladka: vykladka = kolikmuzu
|
||||
|
||||
if len(curve) < vykladka:
|
||||
vykladka = len(curve)
|
||||
qty = int(state.vars.chunk)
|
||||
last_price = price2dec(state.interface.get_last_price(state.symbol))
|
||||
#profit = float(state.vars.profit)
|
||||
price = last_price
|
||||
state.ilog(e="BUY Vykladame", msg=f"first price {price=} {vykladka=}", curve=curve, ema=state.indicators.ema[-1], trend=state.vars.Trend, price=price, vykladka=vykladka)
|
||||
##prvni se vyklada na aktualni cenu, další jdou podle krivky, nula v krivce zvyšuje množství pro následující iteraci
|
||||
|
||||
##VAR - na zaklade conf. muzeme jako prvni posilat MARKET order
|
||||
if safe_get(state.vars, "first_buy_market", False) == True:
|
||||
#pri defenzivnim rezimu pouzivame vzdy LIMIT order
|
||||
if is_defensive_mode():
|
||||
state.ilog(e="DEF mode on, odesilame jako prvni limitku")
|
||||
state.buy_l(price=price, size=qty)
|
||||
else:
|
||||
state.ilog(e="Posilame jako prvni MARKET order")
|
||||
state.buy(size=qty)
|
||||
else:
|
||||
state.buy_l(price=price, size=qty)
|
||||
print("prvni limitka na aktuální cenu. Další podle křivky", price, qty)
|
||||
for i in range(0,vykladka-1):
|
||||
price = price2dec(float(price - curve[i]))
|
||||
if price == last_price:
|
||||
qty = qty + int(state.vars.chunk)
|
||||
else:
|
||||
state.buy_l(price=price, size=qty)
|
||||
#print(i,"BUY limitka - delta",curve[i]," cena:", price, "mnozstvi:", qty)
|
||||
qty = int(state.vars.chunk)
|
||||
last_price = price
|
||||
state.vars.blockbuy = 1
|
||||
state.vars.jevylozeno = 1
|
||||
|
||||
#CBAR protection, only 1x order per CBAR - then wait until another confirmed bar
|
||||
if state.vars.blockbuy == 1 and state.rectype == RecordType.CBAR:
|
||||
if state.bars.confirmed[-1] == 0:
|
||||
print("OCHR: multibuy protection. waiting for next bar")
|
||||
return 0
|
||||
# pop potvrzeni jeste jednou vratime (aby se nekoupilo znova, je stale ten stejny bar)
|
||||
# a pak dalsi vejde az po minticku
|
||||
else:
|
||||
# pro vykladaci
|
||||
state.vars.blockbuy = 0
|
||||
return 0
|
||||
|
||||
state.ilog(e="-----")
|
||||
|
||||
#EMA INDICATOR -
|
||||
#plnime MAcko - nyni posilame jen N poslednich hodnot
|
||||
#zaroven osetrujeme pripady, kdy je malo dat a ukladame nulu
|
||||
try:
|
||||
ma = int(state.vars.MA)
|
||||
#poslednich ma hodnot
|
||||
source = state.bars.close[-ma:] #state.bars.vwap
|
||||
ema_value = ema(source, ma)
|
||||
state.indicators.ema[-1]=trunc(ema_value[-1],3)
|
||||
except Exception as e:
|
||||
state.ilog(e="EMA ukladame 0", message=str(e)+format_exc())
|
||||
state.indicators.ema[-1]=0
|
||||
|
||||
#SLOPE INDICATOR
|
||||
#úhel stoupání a klesání vyjádřený mezi -1 až 1
|
||||
#pravý bod přímky je aktuální cena, levý je průměr X(lookback offset) starších hodnot od slope_lookback.
|
||||
#obsahuje statický indikátor (angle) pro vizualizaci
|
||||
try:
|
||||
slope = 99
|
||||
slope_lookback = int(state.vars.slope_lookback)
|
||||
minimum_slope = float(state.vars.minimum_slope)
|
||||
lookback_offset = int(state.vars.lookback_offset)
|
||||
|
||||
if len(state.bars.close) > (slope_lookback + lookback_offset):
|
||||
array_od = slope_lookback + lookback_offset
|
||||
array_do = slope_lookback
|
||||
lookbackprice_array = state.bars.vwap[-array_od:-array_do]
|
||||
#obycejný prumer hodnot
|
||||
lookbackprice = round(sum(lookbackprice_array)/lookback_offset,3)
|
||||
|
||||
#výpočet úhlu
|
||||
slope = ((state.bars.close[-1] - lookbackprice)/lookbackprice)*100
|
||||
slope = round(slope, 4)
|
||||
state.indicators.slope[-1]=slope
|
||||
|
||||
#angle je ze slope
|
||||
state.statinds.angle = dict(time=state.bars.time[-1], price=state.bars.close[-1], lookbacktime=state.bars.time[-slope_lookback], lookbackprice=lookbackprice, minimum_slope=minimum_slope)
|
||||
|
||||
#slope MA vyrovna vykyvy ve slope, dále pracujeme se slopeMA
|
||||
slope_MA_length = 5
|
||||
source = state.indicators.slope[-slope_MA_length:]
|
||||
slopeMAseries = ema(source, slope_MA_length) #state.bars.vwap
|
||||
slopeMA = slopeMAseries[-1]
|
||||
state.indicators.slopeMA[-1]=slopeMA
|
||||
|
||||
state.ilog(e=f"{slope=} {slopeMA=}", msg=f"{lookbackprice=}", lookbackoffset=lookback_offset, minimum_slope=minimum_slope, last_slopes=state.indicators.slope[-10:])
|
||||
|
||||
#dale pracujeme s timto MAckovanym slope
|
||||
slope = slopeMA
|
||||
else:
|
||||
#pokud plnime historii musime ji plnit od zacatku, vsehcny idenitifkatory maji spolecny time
|
||||
#kvuli spravnemu zobrazovani na gui
|
||||
#state.indicators.slopeMA[-1]=0
|
||||
#state.indicators.slopeMA.append(0)
|
||||
state.ilog(e="Slope - not enough data", slope_lookback=slope_lookback, slope=state.indicators.slope, slopeMA=state.indicators.slopeMA)
|
||||
except Exception as e:
|
||||
print("Exception in NEXT Slope Indicator section", str(e))
|
||||
state.ilog(e="EXCEPTION", msg="Exception in Slope Indicator section" + str(e) + format_exc())
|
||||
|
||||
print("is falling",isfalling(state.indicators.ema,state.vars.Trend))
|
||||
print("is rising",isrising(state.indicators.ema,state.vars.Trend))
|
||||
|
||||
consolidation()
|
||||
|
||||
#HLAVNI ITERACNI LOG JESTE PRED AKCI - obsahuje aktualni hodnoty vetsiny parametru
|
||||
lp = state.interface.get_last_price(symbol=state.symbol)
|
||||
state.ilog(e="ENTRY", msg=f"LP:{lp} P:{state.positions}/{round(float(state.avgp),3)} profit:{round(float(state.profit),2)} Trades:{len(state.tradeList)} DEF:{str(is_defensive_mode())}", last_price=lp, data=data, stratvars=state.vars)
|
||||
|
||||
#SLOPE ANGLE PROTECTIONs
|
||||
#slope zachycuje rychle sestupy, pripadne zrusi nakupni objednavky
|
||||
if slope < minimum_slope: # or slopeMA<maxSlopeMA:
|
||||
print("OCHRANA SLOPE TOO HIGH")
|
||||
# if slopeMA<maxSlopeMA:
|
||||
# state.ilog(e="Slope MA too high "+str(slopeMA)+" max:"+str(maxSlopeMA))
|
||||
state.ilog(e=f"Slope too high {slope}")
|
||||
if len(state.vars.pendingbuys)>0:
|
||||
print("CANCEL PENDINGBUYS")
|
||||
#ic(state.vars.pendingbuys)
|
||||
res = asyncio.run(state.cancel_pending_buys())
|
||||
#ic(state.vars.pendingbuys)
|
||||
state.ilog(e="Rusime pendingbuyes", pb=state.vars.pendingbuys, res=res)
|
||||
print("slope", slope)
|
||||
print("min slope", minimum_slope)
|
||||
|
||||
if state.vars.jevylozeno == 0:
|
||||
print("Neni vylozeno, muzeme testovat nakup")
|
||||
|
||||
#pokud je defenziva, buy triggeruje defenzivni def_trend
|
||||
#TBD
|
||||
|
||||
|
||||
if isfalling(state.indicators.ema,state.vars.Trend) and slope > minimum_slope:
|
||||
vyloz()
|
||||
|
||||
## testuje aktualni cenu od nejvyssi visici limitky
|
||||
##toto spoustet jednou za X iterací - ted to jede pokazdé
|
||||
#pokud to ujede o vic, rusime limitky
|
||||
#TODO: zvazit jestli nechat i pri otevrenych pozicich, zatim nechavame
|
||||
#TODO int(int(state.oa.poz)/int(state.variables.chunk)) > X
|
||||
|
||||
#TODO predelat mechanismus ticků (zrelativizovat), aby byl pouzitelny na tituly s ruznou cenou
|
||||
#TODO spoustet 1x za X iteraci nebo cas
|
||||
if state.vars.jevylozeno == 1:
|
||||
#pokud mame vylozeno a cena je vetsi nez tick2reset
|
||||
if len(state.vars.pendingbuys)>0:
|
||||
maxprice = max(state.vars.pendingbuys.values())
|
||||
print("max cena v orderbuys", maxprice)
|
||||
if state.interface.get_last_price(state.symbol) > float(maxprice) + float(state.vars.ticks2reset):
|
||||
##TODO toto nejak vymyslet - duplikovat?
|
||||
res = asyncio.run(state.cancel_pending_buys())
|
||||
state.ilog(e=f"UJELO to. Rusime PB", msg=f"{state.vars.ticks2reset=}", pb=state.vars.pendingbuys)
|
||||
|
||||
#PENDING BUYS SPENT - PART
|
||||
#pokud mame vylozeno a pendingbuys se vyklepou a
|
||||
# 1 vykladame idned znovu
|
||||
# vyloz()
|
||||
# 2 nebo - počkat zase na signál a pokračovat dál
|
||||
# state.vars.blockbuy = 0
|
||||
# state.vars.jevylozeno = 0
|
||||
# 3 nebo - počkat na signál s enablovaným lastbuy indexem (tzn. počká nutně ještě pár barů)
|
||||
#podle BT vyhodnejsi vylozit ihned
|
||||
if len(state.vars.pendingbuys) == 0:
|
||||
state.vars.blockbuy = 0
|
||||
state.vars.jevylozeno = 0
|
||||
state.ilog(e="PB se vyklepaly nastavujeme: neni vylozeno", jevylozeno=state.vars.jevylozeno)
|
||||
|
||||
#TODO toto dodelat konzolidaci a mozna lock na limitku a pendingbuys a jevylozeno ??
|
||||
|
||||
#kdykoliv se muze notifikace ztratit
|
||||
# - pendingbuys - vsechny open orders buy
|
||||
# - limitka - open order sell
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pokud je vylozeno a mame pozice a neexistuje limitka - pak ji vytvorim
|
||||
# if int(state.oe.poz)>0 and state.oe.limitka == 0:
|
||||
# #pro jistotu updatujeme pozice
|
||||
# state.oe.avgp, state.oe.poz = state.oe.pos()
|
||||
# if int(state.oe.poz) > 0:
|
||||
# cena = round(float(state.oe.avgp) + float(state.oe.stratvars["profit"]),2)
|
||||
# print("BUGF: limitka neni vytvarime, a to za cenu",cena,"mnozstvi",state.oe.poz)
|
||||
# print("aktuzalni ltp",ltp.price[state.oe.symbol])
|
||||
|
||||
# try:
|
||||
# state.oe.limitka = state.oe.sell_noasync(cena, state.oe.poz)
|
||||
# print("vytvorena limitka", state.oe.limitka)
|
||||
# except Exception as e:
|
||||
# print("Neslo vytvorit profitku. Problem,ale jedeme dal",str(e))
|
||||
# pass
|
||||
# ##raise Exception(e)
|
||||
|
||||
print(10*"*","NEXT STOP",10*"*")
|
||||
|
||||
def init(state: StrategyState):
|
||||
#place to declare new vars
|
||||
print("INIT v main",state.name)
|
||||
state.indicators['ema'] = []
|
||||
state.indicators['slope'] = []
|
||||
state.indicators['slopeMA'] = []
|
||||
#static indicators - those not series based
|
||||
state.statinds['angle'] = dict(minimum_slope=state.vars["minimum_slope"])
|
||||
state.vars["ticks2reset_backup"] = state.vars.ticks2reset
|
||||
|
||||
def main():
|
||||
# try:
|
||||
# strat_settings = tomli.loads("]] this is invalid TOML [[")
|
||||
# except tomli.TOMLDecodeError:
|
||||
# print("Yep, definitely not valid.")
|
||||
|
||||
#strat_settings = dict_replace_value(strat_settings, "None", None)
|
||||
|
||||
name = os.path.basename(__file__)
|
||||
se = Event()
|
||||
pe = Event()
|
||||
s = StrategyOrderLimitVykladaci(name = name, symbol = "BAC", account=Account.ACCOUNT1, next=next, init=init, stratvars=stratvars, open_rush=10, close_rush=0, pe=pe, se=se, ilog_save=True)
|
||||
s.set_mode(mode = Mode.BT,
|
||||
debug = False,
|
||||
start = datetime(2023, 4, 14, 10, 42, 0, 0, tzinfo=zoneNY),
|
||||
end = datetime(2023, 4, 14, 14, 35, 0, 0, tzinfo=zoneNY),
|
||||
cash=100000)
|
||||
|
||||
#na sekundovem baru nezaokrouhlovat MAcko
|
||||
s.add_data(symbol="BAC",rectype=RecordType.BAR,timeframe=2,minsize=100,update_ltp=True,align=StartBarAlign.ROUND,mintick=0, exthours=False)
|
||||
#s.add_data(symbol="C",rectype=RecordType.BAR,timeframe=1,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=0)
|
||||
|
||||
s.start()
|
||||
print("zastavujeme")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
103
v2realbot/archived/ENTRY_backtest_strategyWatched.py
Normal file
103
v2realbot/archived/ENTRY_backtest_strategyWatched.py
Normal file
@ -0,0 +1,103 @@
|
||||
from strategy.base import Strategy, StrategyState
|
||||
from strategy.strategyOrderLimitWatched import StrategyOrderLimitWatched
|
||||
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode
|
||||
from indicators import ema
|
||||
from rich import print
|
||||
from utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY
|
||||
from datetime import datetime
|
||||
from icecream import install, ic
|
||||
install()
|
||||
ic.configureOutput(includeContext=True)
|
||||
#ic.disable()
|
||||
""""
|
||||
Simple strategie pro test backtesting
|
||||
"""
|
||||
|
||||
def next(data, state: StrategyState):
|
||||
print(10*"*","NEXT START",10*"*")
|
||||
#ic(state.avgp, state.positions)
|
||||
#ic(state.vars.lastbuyindex)
|
||||
#ic(data)
|
||||
#ic(state.positions)
|
||||
#ic(state.vars.watched)
|
||||
#ic(state.vars.wait)
|
||||
|
||||
try:
|
||||
state.indicators.ema = ema(state.bars.hlcc4, state.vars.MA) #state.bars.vwap
|
||||
#trochu prasarna, EMAcko trunc na 3 mista - kdyz se osvedci, tak udelat efektivne
|
||||
state.indicators.ema = [trunc(i,3) for i in state.indicators.ema]
|
||||
#ic(state.vars.MA, state.vars.Trend, state.indicators.ema[-5:])
|
||||
except Exception as e:
|
||||
print("No data for MA yet", str(e))
|
||||
|
||||
print("is falling",isfalling(state.indicators.ema,state.vars.Trend))
|
||||
print("is rising",isrising(state.indicators.ema,state.vars.Trend))
|
||||
|
||||
#ZDE JSEM SKONCIL
|
||||
#nejprve zacit s BARy
|
||||
|
||||
#TODO vyzkoušet limit buy - vetsina z nakupu by se dala koupit o cent dva mene
|
||||
#proto dodělat LTP pro BT, neco jako get_last_price(self.state.time)
|
||||
|
||||
|
||||
##TODO vyzkouset hlidat si sell objednavku sam na zaklade tradu
|
||||
# v pripade ze to jde nahoru(is rising - nebo jiny indikator) tak neprodavat
|
||||
#vyuzit CBARy k tomuto .....
|
||||
#triggerovat buy treba po polovine CBARu, kdyz se cena bude rovnat nebo bude nizsi nez low
|
||||
#a hned na to (po potvrzeni) hlidat sell +0.01 nebo kdyz roste nechat rust.vyzkouset na LIVE
|
||||
|
||||
datetime.fromtimestamp(state.last_trade_time)
|
||||
casbaru = datetime.fromtimestamp(state.last_trade_time)-data['time']
|
||||
kupuj = casbaru.seconds > int(int(data['resolution']) * 0.4)
|
||||
#ic(kupuj)
|
||||
#ic(casbaru.seconds)
|
||||
|
||||
#kupujeme kdyz v druhe polovine baru je aktualni cena=low (nejnizsi)
|
||||
#isrising(state.indicators.ema,state.vars.Trend)
|
||||
#kdyz se v jednom baru pohneme o 2
|
||||
if kupuj and data['confirmed'] != 1 and data['close'] == data['low'] and float(data['close']) + 0.01 < data['open'] and state.vars.wait is False and state.vars.watched is None:
|
||||
print("BUY MARKET")
|
||||
#ic(data['updated'])
|
||||
#ic(state.time)
|
||||
##updatneme realnou cenou po fillu
|
||||
state.buy()
|
||||
state.vars.wait = True
|
||||
|
||||
if state.vars.watched and state.vars.wait is False:
|
||||
currprice = state.interface.get_last_price(symbol = state.symbol)
|
||||
#ic(currprice)
|
||||
if float(currprice) > (float(state.vars.watched) + float(state.vars.profit)):
|
||||
#ic(state.time)
|
||||
#ic("prodavame", currprice)
|
||||
print("PRODAVAME")
|
||||
##vymyslet jak odchytavat obecne chyby a vracet cislo objednavky
|
||||
state.interface.sell(size=1)
|
||||
state.vars.wait = True
|
||||
|
||||
|
||||
print(10*"*","NEXT STOP",10*"*")
|
||||
|
||||
def init(state: StrategyState):
|
||||
#place to declare new vars
|
||||
print("INIT v main",state.name)
|
||||
state.vars['novaprom'] = 4
|
||||
state.indicators['ema'] = []
|
||||
|
||||
def main():
|
||||
stratvars = AttributeDict(maxpozic = 1, chunk = 1, MA = 2, Trend = 2, profit = 0.005, lastbuyindex=-6, pendingbuys={},watched = None, wait = False)
|
||||
|
||||
s = StrategyOrderLimitWatched(name = "BackTEST", symbol = "BAC", next=next, init=init, stratvars=stratvars, debug=False)
|
||||
s.set_mode(mode = Mode.PAPER,
|
||||
start = datetime(2023, 3, 24, 11, 30, 0, 0, tzinfo=zoneNY),
|
||||
end = datetime(2023, 3, 24, 11, 45, 0, 0, tzinfo=zoneNY),
|
||||
cash=100000)
|
||||
|
||||
#na sekundovem baru nezaokrouhlovat MAcko
|
||||
s.add_data(symbol="BAC",rectype=RecordType.CBAR,timeframe=5,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=0)
|
||||
#s.add_data(symbol="C",rectype=RecordType.BAR,timeframe=1,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=0)
|
||||
|
||||
s.start()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
70
v2realbot/archived/ENTRY_latency_roundtrip.py
Normal file
70
v2realbot/archived/ENTRY_latency_roundtrip.py
Normal file
@ -0,0 +1,70 @@
|
||||
from strategy.base import Strategy
|
||||
from strategy.base import StrategyState
|
||||
from enums import RecordType, StartBarAlign, Mode
|
||||
from config import API_KEY, SECRET_KEY, MAX_BATCH_SIZE, PAPER
|
||||
from indicators import ema
|
||||
from rich import print
|
||||
from utils import ltp, isrising, isfalling,trunc,AttributeDict
|
||||
from datetime import datetime
|
||||
|
||||
""""
|
||||
Simple strategie pro měření roundtripu na konkrétním prostředí
|
||||
|
||||
- koupí 1 akcii a vypíše časy
|
||||
- tradu který triggeroval
|
||||
- čas triggeru buy
|
||||
- příchod zpětné notifikace NEW
|
||||
- příchod zpětné notifikace FILL
|
||||
- vypíše trade, když přijde do agregátoru (vyžaduje do agregátoru na řádek 79: if int(data['s']) == 1: print(data))
|
||||
- vyžaduje ve strategy base v orderupdate
|
||||
- print("NOTIFICATION ARRIVED AT:", datetime.now().timestamp(), datetime.now())
|
||||
- print(data)
|
||||
|
||||
výsledek latencyroudntrip.log
|
||||
|
||||
"""
|
||||
|
||||
def next(data, state: StrategyState):
|
||||
print("avgp:", state.avgp)
|
||||
print("positions", state.positions)
|
||||
print("přišly tyto data", data)
|
||||
print("bar updated time:", data['updated'], datetime.fromtimestamp(data['updated']))
|
||||
print("state time(now):", state.time, datetime.fromtimestamp(state.time))
|
||||
#print("trades history", state.trades)
|
||||
#print("bar history", state.bars)
|
||||
print("ltp", ltp.price["BAC"], ltp.time["BAC"])
|
||||
|
||||
try:
|
||||
ema_output = ema(state.bars.hlcc4, state.vars.MA) #state.bars.vwap
|
||||
ema_output = [trunc(i,3) for i in ema_output]
|
||||
print("emacko na wvap",state.vars.MA,":", ema_output[-5:])
|
||||
except:
|
||||
print("No data for MA yet")
|
||||
|
||||
print("MA is falling",state.vars.Trend,"value:",isfalling(ema_output,state.vars.Trend))
|
||||
print("MA is rising",state.vars.Trend,"value:",isrising(ema_output,state.vars.Trend))
|
||||
|
||||
if isfalling(ema_output,state.vars.Trend) and state.vars.blockbuy == 0:
|
||||
print("kupujeme MARKET")
|
||||
print("v baru mame cas posledniho tradu", data['updated'])
|
||||
print("na LIVE je skutecny cas - tento ", state.time)
|
||||
print("v nem odesilame")
|
||||
state.interface.buy(time=state.time)
|
||||
state.vars.blockbuy = 1
|
||||
|
||||
def init(state: StrategyState):
|
||||
print("INIT strategie", state.name, "symbol", state.symbol)
|
||||
|
||||
def main():
|
||||
stratvars = AttributeDict(maxpozic = 200, chunk = 10, MA = 3, Trend = 3, profit = 0.01, blockbuy=0, lastbuyindex=0, pendingbuys={})
|
||||
s = Strategy(name = "BackTEST", symbol = "BAC", next=next, init=init, stratvars=stratvars)
|
||||
|
||||
#s.set_mode(mode = Mode.BT, start= datetime(2023, 3, 16, 15, 54, 30, 0), end=datetime(2023, 3, 16, 15, 54, 40, 999999))
|
||||
|
||||
s.add_data(symbol="BAC",rectype=RecordType.BAR,timeframe=5,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=0)
|
||||
#s.add_data(symbol="C",rectype=RecordType.BAR,timeframe=1,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=0)
|
||||
|
||||
s.start()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
5
v2realbot/archived/ENTRY_strategy_vykladaci_REFACTOR.py
Normal file
5
v2realbot/archived/ENTRY_strategy_vykladaci_REFACTOR.py
Normal file
@ -0,0 +1,5 @@
|
||||
##pro refactor vykladaci strategie: tipy:
|
||||
|
||||
##pri CANCEL pendindbuys - lokalni pending buys zrušit hnedka po synchronním odeslání, nemusim cekat na potvrzeni
|
||||
##ve zpetne notifikaci FILLU - je uvedena aktuální počet pozice - tzn. nemusím volat POS, ale jen si je dotahnu odsud. Pozor avgp tu neni.
|
||||
|
||||
200
v2realbot/archived/FINAL_MA_VYK_10s_AGGR_mastrategyvykladaci.py
Normal file
200
v2realbot/archived/FINAL_MA_VYK_10s_AGGR_mastrategyvykladaci.py
Normal file
@ -0,0 +1,200 @@
|
||||
from strategy import MyStrategy, StrategyState, Strategy
|
||||
from enums import RecordType, StartBarAlign
|
||||
from config import API_KEY, SECRET_KEY, MAX_BATCH_SIZE, PAPER
|
||||
from indicators import ema
|
||||
from rich import print
|
||||
from utils import ltp, isrising, isfalling,trunc
|
||||
|
||||
|
||||
|
||||
""""
|
||||
TBD - zpomalit - nekupovat okamzite nechat dychat
|
||||
|
||||
|
||||
MA Vykládcí Strategie s LIMIT BUY
|
||||
# aktualni nastaveni - VELMI AGRESIVNI, STALE KUPUJE, IDEALNI NA POTVRZENE RUSTOVE DNY
|
||||
- jede na 10s
|
||||
- BUY and HOLD alternative
|
||||
- dat do seznamu hotovych strategii
|
||||
|
||||
atributy:
|
||||
ticks2reset - počet ticků po kterých se resetnou prikazy pokud neni plneni
|
||||
|
||||
TODO:
|
||||
- pridat reconciliaci po kazdem X tem potvrzenem baru - konzolidace otevrenych pozic a limitek
|
||||
- do kazde asynchronni notifkace orderupdate dat ochranu, kdyz uz ten stav neplati (tzn. napr. pro potvrzeni buye se uz prodalo)
|
||||
- podchytit: kdykoliv limitka neexistuje, ale mam pozice, tak ji vytvorit (podchytit situace v rush hours)
|
||||
- cancel pendign buys - dictionary changed size during iteration podychytit. lock
|
||||
"""
|
||||
ticks2reset = 0.03
|
||||
#TODO pokud bar klesne o jeden nebo vice - tak signál - DEFENZIVNI MOD
|
||||
#TODO pouzivat tu objekt ochrana (ktery jen vlozim do kodu a kdyz vrati exceptionu tak jdeme do dalsi iterace)
|
||||
# tak zustane strategie cista
|
||||
#TODO rušit (pending buys) když oe.poz = 0 a od nejvetsi pending buys je
|
||||
# ltp.price vice nez 5 ticků
|
||||
|
||||
def next(data, state: StrategyState):
|
||||
|
||||
def vyloz(pozic: int):
|
||||
print("vykladame na pocet pozic", pozic)
|
||||
# defenzivni krivka
|
||||
curve = [0.01, 0.01, 0.01, 0.02, 0.02, 0.02, 0.02,0.03,0.03,0.03,0.03, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04]
|
||||
#cent curve = [0.01, 0.01, 0.01,0.01, 0.01, 0.01,0.01, 0.01,0.01, 0.01, 0.01, 0.01,0.01, 0.01,0.01, 0.01,0.01, 0.01,0.01, 0.01,0.01, 0.01,0.01, 0.01,0.01, 0.01]
|
||||
#defenzivnejsi s vetsimi mezerami v druhe tretine a vetsi vahou pro dokupy
|
||||
|
||||
# krivka pro AVG, tzn. exponencialne pridavame 0.00
|
||||
curve = [0.01, 0, 0.01, 0, 0, 0.01, 0, 0, 0, 0.01, 0, 0, 0, 0, 0.01, 0, 0, 0, 0, 0, 0.01, 0,0,0,0,0,0, 0.01, 0,0,0,0,0,0,0,0,0.01,0,0,0,0,0,0,0,0,0, 0.01,0,0,0,0,0,0,0,0,0,0.01, 0,0,0,0,0,00,0,0,0, 0.5, 0,0,0,0,0.5,0,0,0]
|
||||
|
||||
# 10ty clen je o 0.05 tzn.triggeruje nam to tick2reset
|
||||
#curve = [0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.02, 0.02, 0.05, 0.01, 0.04, 0.01, 0.01, 0.04, 0.05, 0.03, 0.05, 0.01, 0.03, 0.01,0.01, 0.04, 0.01, 0.05,0.01, 0.01,0.01, 0.01]
|
||||
|
||||
#defenzivni krivku nastavime vetsimi mezerami a v nich 0.01 - tim se prida vetsi mnostvi a vic se naredi
|
||||
# 0.04, 0.01,
|
||||
|
||||
#curve = [0.01,0.01, 0.01, 0.02, 0.02, 0.02, 0.02]
|
||||
#cena pro prvni objednavky
|
||||
price = trunc(float(ltp.price[state.oe.symbol]),2)
|
||||
print("aktualni cena pri vykladu - pro prvni", price)
|
||||
qty = int(state.variables.chunk)
|
||||
last_price = price
|
||||
if len(curve) < pozic:
|
||||
pozic = len(curve)
|
||||
#stejné ceny posilame jako jednu objednávku
|
||||
for i in range(0,pozic):
|
||||
price = round(float(price - curve[i]),2)
|
||||
if price == last_price:
|
||||
qty = qty + int(state.variables.chunk)
|
||||
else:
|
||||
#flush last_price and stored qty
|
||||
# OPT: pokud bude kupovat prilis brzy, osvedcila se prvni cena -0.01 (tzn. stavi prehodit last_price za price)
|
||||
state.oe.buy_l(price=last_price, size=qty, force=1)
|
||||
print(i,"BUY limitka - delta",curve[i]," cena:", price, "mnozstvi:", qty)
|
||||
qty = int(state.variables.chunk)
|
||||
|
||||
last_price = price
|
||||
|
||||
#TODO pokud cena stejna jako predchozi, tak navys predchozi - abychom nemeli vice objednavek na stejne cene (zbytecne)
|
||||
|
||||
|
||||
|
||||
|
||||
print("pending buys", state.oe.stratvars['pendingbuys'])
|
||||
print("je vylozeno",state.oe.stratvars['jevylozeno'])
|
||||
print("avg,poz,limitka",state.oe.avgp, state.oe.poz, state.oe.limitka)
|
||||
print("last buy price", state.oe.lastbuy)
|
||||
#CBAR protection, only 1x order per CBAR - then wait until another confirmed bar
|
||||
if state.variables.blockbuy == 1:
|
||||
if state.bars.confirmed[-1] == 0:
|
||||
print("OCHR: multibuy protection. waiting for next bar")
|
||||
return 0
|
||||
# pop potvrzeni jeste jednou vratime (aby se nekoupilo znova, je stale ten stejny bar)
|
||||
# a pak dalsi vejde az po minticku
|
||||
else:
|
||||
# pro vykladaci
|
||||
state.variables.blockbuy = 0
|
||||
return 0
|
||||
|
||||
|
||||
#print(state.bars) .
|
||||
# print("next")
|
||||
# print(data)
|
||||
|
||||
#TODO zkusit hlcc4
|
||||
try:
|
||||
ema_output = ema(state.bars.vwap, state.variables.MA)
|
||||
#trochu prasarna, EMAcko trunc na 3 mista - kdyz se osvedci, tak udelat efektivne
|
||||
ema_output = [trunc(i,3) for i in ema_output]
|
||||
print("emacko na wvap",state.variables.MA,":", ema_output[-5:])
|
||||
except:
|
||||
print("No data for MA yet")
|
||||
|
||||
print("MA is falling",state.variables.Trend,"value:",isfalling(ema_output,state.variables.Trend))
|
||||
print("MA is rising",state.variables.Trend,"value:",isrising(ema_output,state.variables.Trend))
|
||||
|
||||
## testuje aktualni cenu od nejvyssi visici limitky
|
||||
##toto spoustet jednou za X iterací - ted to jede pokazdé
|
||||
#pokud to ujede o vic, rusime limitky
|
||||
#TODO: zvazit jestli nechat i pri otevrenych pozicich, zatim nechavame
|
||||
#TODO int(int(state.oa.poz)/int(state.variables.chunk)) > X
|
||||
if state.oe.stratvars['jevylozeno'] == 1: # and int(state.oe.poz) == 0:
|
||||
#pokud mame vylozeno a cena je vetsi nez 0.04
|
||||
if len(state.oe.stratvars['pendingbuys'])>0:
|
||||
a = max(state.oe.stratvars['pendingbuys'].values())
|
||||
print("max cena v orderbuys", a)
|
||||
if float(ltp.price[state.oe.symbol]) > float(a) + ticks2reset:
|
||||
print("ujelo to vice nez o 4, rusime limit buye")
|
||||
state.oe.cancel_pending_buys()
|
||||
state.oe.stratvars['jevylozeno'] = 0
|
||||
|
||||
#pokud je vylozeno a mame pozice a neexistuje limitka - pak ji vytvorim
|
||||
if int(state.oe.poz)>0 and state.oe.limitka == 0:
|
||||
#pro jistotu updatujeme pozice
|
||||
state.oe.avgp, state.oe.poz = state.oe.pos()
|
||||
if int(state.oe.poz) > 0:
|
||||
cena = round(float(state.oe.avgp) + float(state.oe.stratvars["profit"]),2)
|
||||
print("BUGF: limitka neni vytvarime, a to za cenu",cena,"mnozstvi",state.oe.poz)
|
||||
print("aktuzalni ltp",ltp.price[state.oe.symbol])
|
||||
|
||||
try:
|
||||
state.oe.limitka = state.oe.sell_noasync(cena, state.oe.poz)
|
||||
print("vytvorena limitka", state.oe.limitka)
|
||||
except Exception as e:
|
||||
print("Neslo vytvorit profitku. Problem,ale jedeme dal",str(e))
|
||||
pass
|
||||
##raise Exception(e)
|
||||
|
||||
if state.oe.stratvars['jevylozeno'] == 0:
|
||||
print("neni vylozeno. Muzeme nakupovat")
|
||||
# testuji variantu, ze kupuji okamzite, nehlede na vyvoj
|
||||
if isfalling(ema_output,state.variables.Trend): # or 1==1:
|
||||
## vyloz pro pocet pozic (maximalni minus aktualni)
|
||||
#kolik nam zbyva pozic
|
||||
|
||||
#HOKUS: vykladame pouze polovinu pozic - dalsi polovinu davame v dalsimrunu
|
||||
# a = available pozice a/2
|
||||
a = int(int(state.variables.maxpozic)/int(state.variables.chunk)-(int(state.oe.poz)/int(state.variables.chunk)))
|
||||
a = int(a)
|
||||
print("Vykladame na pocet pozic", a)
|
||||
|
||||
|
||||
vyloz(pozic=a)
|
||||
#blokneme nakupy na dalsi bar
|
||||
state.variables.blockbuy = 1
|
||||
state.oe.stratvars['jevylozeno'] = 1
|
||||
|
||||
|
||||
#ulozime id baru
|
||||
# state.variables.lastbuyindex = state.bars.index[-1]
|
||||
|
||||
# je vylozeno
|
||||
else:
|
||||
## po kazde 4te pozici delame revykladani na aktualni zbytek pozic
|
||||
if (int(state.oe.poz)/(int(state.variables.chunk)) % 4 == 0):
|
||||
print("ctvrta pozice - v budoucnu realignujeme")
|
||||
# state.oe.cancel_pending_buys()
|
||||
# ##smazeme ihned pole - necekame na notifiaci
|
||||
# vyloz((int(state.variables.maxpozic)-int(state.oe.poz)/state.variables.chunk))
|
||||
|
||||
|
||||
#kazdy potvrzeny bar dotahneme pro jistotu otevřené objednávky a nahradíme si stav aktuálním
|
||||
|
||||
#pro jistotu update pozic - kdyz se nic nedeje nedeje
|
||||
#pripadne dat pryc
|
||||
#print("upatujeme pozice")
|
||||
#state.oe.avgp, state.oe.poz = state.oe.pos()
|
||||
|
||||
def init(state: StrategyState):
|
||||
print("init - zatim bez data")
|
||||
print(state.oe.symbol)
|
||||
print(state.oe.pos())
|
||||
print()
|
||||
|
||||
def main():
|
||||
stratvars = dict(maxpozic = 2000, chunk = 20, MA = 3, Trend = 4, profit = 0.01, blockbuy=0, lastbuyindex=0, pendingbuys={}, jevylozeno=0)
|
||||
s = MyStrategy("BAC",paper=PAPER, next=next, init=init, stratvars=stratvars)
|
||||
s.add_data(symbol="BAC",rectype=RecordType.CBAR,timeframe=12,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=4)
|
||||
|
||||
s.start()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
27
v2realbot/archived/emptystrategy.py
Normal file
27
v2realbot/archived/emptystrategy.py
Normal file
@ -0,0 +1,27 @@
|
||||
from strategy import MyStrategy, StrategyState
|
||||
from enums import RecordType, StartBarAlign
|
||||
from config import API_KEY, SECRET_KEY, MAX_BATCH_SIZE, PAPER
|
||||
from indicators import ema
|
||||
from rich import print
|
||||
|
||||
def next(data, state: StrategyState):
|
||||
print("next")
|
||||
print(state.variables.MA)
|
||||
print(state.variables.maxpozic)
|
||||
print(data)
|
||||
print(state.oe.pos())
|
||||
|
||||
def init(state: StrategyState):
|
||||
print("init - zatim bez data")
|
||||
print(state.oe.symbol)
|
||||
print(state.oe.pos())
|
||||
print()
|
||||
|
||||
def main():
|
||||
stratvars = dict(maxpozic = 10, chunk = 1, MA = 3, Trend = 4,profit = 0.01)
|
||||
s = MyStrategy("TSLA",paper=PAPER, next=next, init=init, stratvars=stratvars)
|
||||
s.add_data(symbol="TSLA",rectype=RecordType.TRADE,timeframe=5,filters=None,update_ltp=True,align=StartBarAlign.ROUND,mintick=0)
|
||||
s.start()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user