ready2live test
This commit is contained in:
@ -33,10 +33,12 @@ Do budoucna vice ridit nakupy pri klesani - napr. vyložení jen 2-3 pozic a dal
|
||||
#
|
||||
"""
|
||||
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,
|
||||
@ -93,6 +95,27 @@ def next(data, state: StrategyState):
|
||||
#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))
|
||||
|
||||
#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
|
||||
@ -104,25 +127,22 @@ def next(data, state: StrategyState):
|
||||
vykladka = state.vars.vykladka
|
||||
#kolik muzu max vylozit
|
||||
kolikmuzu = int((int(state.vars.maxpozic) - int(state.positions))/int(state.vars.chunk))
|
||||
akt_pozic = int((int(state.positions))/int(state.vars.chunk)) #20
|
||||
max_pozic = int((int(state.vars.maxpozic))/int(state.vars.chunk)) #40
|
||||
akt_pozic = int(state.positions)
|
||||
max_pozic = int(state.vars.maxpozic)
|
||||
|
||||
#mame polovinu a vic vylozeno, pouzivame defenzicni krivku
|
||||
if (akt_pozic >= max_pozic/2):
|
||||
state.ilog(e="DEF: Mame pul a vic vylozeno, pouzivame defenzivni krivku", akt_pozic=akt_pozic, max_pozic=max_pozic, curve_def=curve_def)
|
||||
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)
|
||||
defense = True
|
||||
else:
|
||||
defense = False
|
||||
#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:
|
||||
@ -137,9 +157,11 @@ def next(data, state: StrategyState):
|
||||
##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 defense:
|
||||
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)
|
||||
@ -277,7 +299,7 @@ def next(data, state: StrategyState):
|
||||
#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=price2dec(float(state.avgp)+state.vars.profit)
|
||||
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:
|
||||
@ -287,12 +309,13 @@ def next(data, state: StrategyState):
|
||||
else:
|
||||
state.ilog(e="Vytvořena nová limitka", limitka=str(state.vars.limitka), limtka_price=state.vars.limitka_price, qty=state.positions)
|
||||
|
||||
elif state.vars.limitka is not None and int(state.positions) > 0 and (int(state.positions) != int(limitka_qty)):
|
||||
#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 - updatujeme", msg=f"{state.positions=} {limitka_qty=}", pos=state.positions, limitka_qty=limitka_qty)
|
||||
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
|
||||
state.vars.limitka = asyncio.run(state.interface.repl(price=state.vars.limitka_price, orderid=state.vars.limitka, size=int(state.positions)))
|
||||
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)
|
||||
@ -334,7 +357,7 @@ def next(data, state: StrategyState):
|
||||
|
||||
#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),2)} profit:{round(float(state.profit),2)} Trades:{len(state.tradeList)}", last_price=lp, stratvars=state.vars)
|
||||
state.ilog(e="ENTRY", msg=f"LP:{lp} P:{state.positions}/{round(float(state.avgp),2)} profit:{round(float(state.profit),2)} Trades:{len(state.tradeList)} DEF:{str(is_defensive_mode())}", last_price=lp, stratvars=state.vars)
|
||||
|
||||
#maxSlopeMA = -0.03
|
||||
#SLOPE ANGLE PROTECTIONs
|
||||
@ -362,10 +385,11 @@ def next(data, state: StrategyState):
|
||||
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:
|
||||
print("BUY MARKET")
|
||||
#zatim vykladame full
|
||||
#positions = int(int(state.vars.maxpozic)/int(state.vars.chunk))
|
||||
vyloz()
|
||||
|
||||
## testuje aktualni cenu od nejvyssi visici limitky
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -251,7 +251,11 @@ class Backtester:
|
||||
#(1679081919.381649, 27.88)
|
||||
#ic(i)
|
||||
fill_time = i[0]
|
||||
fill_price = i[1]
|
||||
|
||||
#v BT nikdy nekoupime za lepsi cenu nez LIMIT price (TBD mozna zmenit na parametr)
|
||||
fill_price = o.limit_price
|
||||
#fill_price = i[1]
|
||||
|
||||
print("FILL LIMIT BUY at", fill_time, datetime.fromtimestamp(fill_time).astimezone(zoneNY), "at",i[1])
|
||||
if BT_FILL_LOG_SURROUNDING_TRADES != 0:
|
||||
#TODO loguru
|
||||
@ -281,7 +285,13 @@ class Backtester:
|
||||
#(1679081919.381649, 27.88)
|
||||
#ic(i)
|
||||
fill_time = i[0]
|
||||
fill_price = i[1]
|
||||
|
||||
#support pomaleho plneni
|
||||
#v BT nikdy neprodame za lepsi cenu nez LIMIT price (TBD mozna zmenit na parametr)
|
||||
fill_price = o.limit_price
|
||||
|
||||
|
||||
#fill_price = i[1]
|
||||
print("FILL LIMIT SELL at", fill_time, datetime.fromtimestamp(fill_time).astimezone(zoneNY), "at",i[1])
|
||||
if BT_FILL_LOG_SURROUNDING_TRADES != 0:
|
||||
#TODO loguru
|
||||
@ -572,6 +582,7 @@ class Backtester:
|
||||
res.append(o)
|
||||
return res
|
||||
|
||||
##toto bude predelano na display_results(ve variantach) umozni zobrazit result jak BT tak LIVE
|
||||
def display_backtest_result(self, state):
|
||||
"""
|
||||
Displays backtest results chart, trades and orders with option to save the result as static HTML.
|
||||
@ -755,6 +766,13 @@ class Backtester:
|
||||
Open orders:''' + str(len(self.open_orders)))
|
||||
textik7 = html.Div('''
|
||||
Trades:''' + str(len(self.trades)))
|
||||
textik8 = html.Div('''
|
||||
Profit:''' + str(state.profit))
|
||||
textik9 = html.Div(f"{BT_FILL_CONS_TRADES_REQUIRED=}")
|
||||
textik10 = html.Div(f"{BT_FILL_LOG_SURROUNDING_TRADES=}")
|
||||
textik11 = html.Div(f"{BT_FILL_CONDITION_BUY_LIMIT=}")
|
||||
textik12 = html.Div(f"{BT_FILL_CONDITION_SELL_LIMIT=}")
|
||||
|
||||
orders_title = dcc.Markdown('## Open orders')
|
||||
trades_title = dcc.Markdown('## Trades')
|
||||
## Define the graph
|
||||
@ -867,7 +885,7 @@ class Backtester:
|
||||
return 'saved'
|
||||
|
||||
## Customize your layout
|
||||
app.layout = dbc.Container([mytitle,button,saved, textik1, textik2, textik3, textik35, textik4, textik5, textik55, textik6,textik7, mygraph, trades_title, trades_table, orders_title, open_orders_table])
|
||||
app.layout = dbc.Container([mytitle,button,saved, textik1, textik2, textik3, textik35, textik4, textik5, textik55, textik6,textik7, textik8, textik9, textik10, textik11, textik12, mygraph, trades_title, trades_table, orders_title, open_orders_table])
|
||||
|
||||
port = 9050
|
||||
print("Backtest FINSIHED"+str(self.backtest_end-self.backtest_start))
|
||||
|
||||
@ -9,14 +9,14 @@ QUIET_MODE = False
|
||||
#N - N consecutive trades required
|
||||
#not impl.yet
|
||||
#minimum is 1, na alpace live to vetsinou vychazi 7-8 u BAC, je to hodne podobne tomu, nez je cena překonaná pul centu. tzn. 7-8 a nebo FillCondition.SLOW
|
||||
BT_FILL_CONS_TRADES_REQUIRED = 3
|
||||
BT_FILL_CONS_TRADES_REQUIRED = 2
|
||||
#during bt trade execution logs X-surrounding trades of the one that triggers the fill
|
||||
BT_FILL_LOG_SURROUNDING_TRADES = 10
|
||||
#fill condition for limit order in bt
|
||||
# fast - price has to be equal or bigger <=
|
||||
# slow - price has to be bigger <
|
||||
BT_FILL_CONDITION_BUY_LIMIT = FillCondition.FAST
|
||||
BT_FILL_CONDITION_SELL_LIMIT = FillCondition.FAST
|
||||
BT_FILL_CONDITION_BUY_LIMIT = FillCondition.SLOW
|
||||
BT_FILL_CONDITION_SELL_LIMIT = FillCondition.SLOW
|
||||
#backend counter of api requests
|
||||
COUNT_API_REQUESTS = False
|
||||
#stratvars that cannot be changed in gui
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
from v2realbot.strategy.base import Strategy
|
||||
from v2realbot.utils.utils import parse_alpaca_timestamp, ltp, AttributeDict,trunc,price2dec, zoneNY, print, json_serial
|
||||
from v2realbot.utils.utils import parse_alpaca_timestamp, ltp, AttributeDict,trunc,price2dec, zoneNY, print, json_serial, safe_get
|
||||
from v2realbot.utils.tlog import tlog, tlog_exception
|
||||
from v2realbot.enums.enums import Mode, Order, Account
|
||||
from alpaca.trading.models import TradeUpdate
|
||||
@ -37,7 +37,8 @@ class StrategyOrderLimitVykladaci(Strategy):
|
||||
self.state.positions = data.position_qty
|
||||
if self.state.vars.limitka is None:
|
||||
self.state.avgp = float(data.price)
|
||||
price=price2dec(float(o.filled_avg_price)+self.state.vars.profit)
|
||||
#price=price2dec(float(o.filled_avg_price)+self.state.vars.profit)
|
||||
price = await self.get_limitka_price()
|
||||
self.state.vars.limitka = await self.interface.sell_l(price=price, size=o.filled_qty)
|
||||
#obcas live vrati "held for orders", odchytime chybu a limitku nevytvarime - spravi to dalsi notifikace nebo konzolidace
|
||||
if self.state.vars.limitka == -1:
|
||||
@ -49,7 +50,8 @@ class StrategyOrderLimitVykladaci(Strategy):
|
||||
else:
|
||||
#avgp, pos
|
||||
self.state.avgp, self.state.positions = self.state.interface.pos()
|
||||
cena = price2dec(float(self.state.avgp) + float(self.state.vars.profit))
|
||||
#cena = price2dec(float(self.state.avgp) + float(self.state.vars.profit))
|
||||
cena = await self.get_limitka_price()
|
||||
try:
|
||||
puvodni = self.state.vars.limitka
|
||||
self.state.vars.limitka = await self.interface.repl(price=cena,orderid=self.state.vars.limitka,size=int(self.state.positions))
|
||||
@ -175,3 +177,24 @@ class StrategyOrderLimitVykladaci(Strategy):
|
||||
self.state.vars.jevylozeno = 0
|
||||
print("cancel pending buys end")
|
||||
self.state.ilog(e="Dokončeno zruseni vsech pb", pb=self.state.vars.pendingbuys)
|
||||
|
||||
#kopie funkci co jsou v next jen async, nejak vymyslet, aby byly jen jedny
|
||||
async def is_defensive_mode(self):
|
||||
akt_pozic = int(self.state.positions)
|
||||
max_pozic = int(self.state.vars.maxpozic)
|
||||
def_mode_from = safe_get(self.state.vars, "def_mode_from")
|
||||
if def_mode_from == None: def_mode_from = max_pozic/2
|
||||
if akt_pozic >= int(def_mode_from):
|
||||
self.state.ilog(e=f"DEFENSIVE MODE active {self.state.vars.def_mode_from=}", msg=self.state.positions)
|
||||
return True
|
||||
else:
|
||||
self.state.ilog(e=f"STANDARD MODE active {self.state.vars.def_mode_from=}", msg=self.state.positions)
|
||||
return False
|
||||
|
||||
async def get_limitka_price(self):
|
||||
def_profit = safe_get(self.state.vars, "def_profit")
|
||||
if def_profit == None: def_profit = self.state.vars.profit
|
||||
if await self.is_defensive_mode():
|
||||
return price2dec(float(self.state.avgp)+float(def_profit))
|
||||
else:
|
||||
return price2dec(float(self.state.avgp)+float(self.state.vars.profit))
|
||||
Binary file not shown.
Reference in New Issue
Block a user