diff --git a/testy/moduleTests/backtestInterfaceTest.py b/testy/moduleTests/backtestInterfaceTest.py new file mode 100644 index 0000000..1909d27 --- /dev/null +++ b/testy/moduleTests/backtestInterfaceTest.py @@ -0,0 +1,46 @@ +from v2realbot.config import Keys, get_key +from v2realbot.enums.enums import Mode, Account, OrderSide +from alpaca.trading.enums import OrderSide, OrderStatus, TradeEvent, OrderType +from v2realbot.common.model import TradeUpdate, Order +from v2realbot.interfaces.live_interface import LiveInterface +from v2realbot.interfaces.backtest_interface import BacktestInterface +from v2realbot.backtesting.backtester import Backtester +from datetime import datetime +from v2realbot.utils.utils import zoneNY +from uuid import UUID, uuid4 + +def callback(): + print("callback entry") + + +start = datetime(2023, 4, 10, 9, 30, 0, 0, tzinfo=zoneNY) +end = datetime(2023, 4, 10, 9, 35, 0, 0, tzinfo=zoneNY) +btdata: list = [] +cash=10000 +#key = get_key(mode=Mode.PAPER, account=Account.ACCOUNT1) +symbol = "BAC" + +bt = Backtester(symbol = symbol, order_fill_callback= callback, btdata=btdata, cash=cash, bp_from=start, bp_to=end) + +bt.open_orders = [Order(id=uuid4(), + submitted_at = datetime(2023, 3, 17, 9, 30, 0, 0, tzinfo=zoneNY), + symbol = "BAC", + qty = 1, + status = OrderStatus.ACCEPTED, + order_type = OrderType.LIMIT, + side = OrderSide.SELL, + limit_price=22.4), + Order(id=uuid4(), + submitted_at = datetime(2023, 3, 17, 9, 30, 00, 0, tzinfo=zoneNY), + symbol = "BAC", + qty = 1, + order_type = OrderType.MARKET, + status = OrderStatus.ACCEPTED, + side = OrderSide.BUY)] + +bt_interface = BacktestInterface(symbol=symbol, bt=bt) + +orderlist = bt.get_open_orders(symbol=symbol, side=None) + +print(orderlist) +print(len(orderlist)) \ No newline at end of file diff --git a/testy/moduleTests/liveInterfaceTest.py b/testy/moduleTests/liveInterfaceTest.py new file mode 100644 index 0000000..49af66a --- /dev/null +++ b/testy/moduleTests/liveInterfaceTest.py @@ -0,0 +1,57 @@ +from v2realbot.config import Keys, get_key +from v2realbot.enums.enums import Mode, Account, OrderSide +from v2realbot.interfaces.live_interface import LiveInterface +from msgpack import packb, unpackb +key = get_key(mode=Mode.PAPER, account=Account.ACCOUNT1) +symbol = "BAC" +li = LiveInterface(symbol=symbol, key=key) + + +##tady jsem skoncil - otestovat tento kod na variantach +# pendinbuys na PAPER +#pak dat do Vykladaci ENTRY a otestovat i na BT +data = {} +data["index"] = 30 +consolidation_bar_count = 10 +pendingbuys = {'22dd3fe21-2c61-4ddd-b7df-cbdb3c1f7b79': '29.63', 'fe7b4baa-ef61-4867-b111-b1c3fc016dce': '29.59', '40253d42-bc00-4476-8f7a-28449fc00080': '29.57'} + +##konzolidace kazdy Nty bar dle nastaveni +if int(data["index"])%int(consolidation_bar_count) == 0: + print("***Consolidation ENTRY***") + + orderlist = li.get_open_orders(symbol=symbol, side=None) + #print(orderlist) + pendingbuys_new = {} + limitka = None + jevylozeno = 1 + for o in orderlist: + if o.side == OrderSide.SELL: + print("Puvodni LIMITKA", limitka) + limitka = o.id + print("Přepsaná LIMITKA", limitka) + if o.side == OrderSide.BUY: + pendingbuys_new[str(o.id)]=o.limit_price + + if pendingbuys_new != pendingbuys: + print("ROZDILNA PENDINGBUYS přepsána") + print("OLD",pendingbuys) + pendingbuys = unpackb(packb(pendingbuys_new)) + print("NEW", pendingbuys) + print("OLD jevylozeno",jevylozeno) + if len(pendingbuys) > 0: + jevylozeno = 1 + else: + jevylozeno = 0 + print("NEW jevylozeno",jevylozeno) + + #print(limitka) + #print(pendingbuys_new) + #print(pendingbuys) + #print(len(pendingbuys)) + #print(len(pendingbuys_new)) + #print(jevylozeno) + print("***CONSOLIDATION EXIT***") + +else: + print("no time for consolidation", data["index"]) + diff --git a/testy/testStore b/testy/testStore.py similarity index 100% rename from testy/testStore rename to testy/testStore.py diff --git a/v2realbot/ENTRY_backtest_strategyVykladaci.py b/v2realbot/ENTRY_backtest_strategyVykladaci.py index 7f1caaa..49dfe44 100644 --- a/v2realbot/ENTRY_backtest_strategyVykladaci.py +++ b/v2realbot/ENTRY_backtest_strategyVykladaci.py @@ -2,13 +2,14 @@ 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 +from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account, OrderSide from v2realbot.indicators.indicators import ema from v2realbot.utils.utils import ltp, isrising, isfalling,trunc,AttributeDict, zoneNY, price2dec, dict_replace_value 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 import tomli @@ -22,6 +23,10 @@ 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. @@ -39,7 +44,8 @@ stratvars = AttributeDict(maxpozic = 250, 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], blockbuy = 0, - ticks2reset = 0.04) + ticks2reset = 0.04, + consolidation_bar_count = 10) ##toto rozparsovat a strategii spustit stejne jako v main toml_string = """ [[strategies]] @@ -171,6 +177,7 @@ def next(data, state: StrategyState): res = asyncio.run(state.cancel_pending_buys()) + #PENDING BUYS SPENT - PART #pokud mame vylozeno a pendingbuys se vyklepou a # 1 vykladame idned znovu # vyloz() @@ -183,7 +190,57 @@ def next(data, state: StrategyState): state.vars.blockbuy = 0 state.vars.jevylozeno = 0 - #TODO toto dodelat + #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 + + ##CONSOLIDATION PART kazdy Nty bar dle nastaveni + if int(data["index"])%int(state.vars.consolidation_bar_count) == 0: + print("***Consolidation ENTRY***") + + orderlist = state.interface.get_open_orders(symbol=state.symbol, side=None) + #print(orderlist) + pendingbuys_new = {} + limitka_old = state.vars.limitka + print("Puvodni LIMITKA", limitka_old) + state.vars.limitka = None + for o in orderlist: + if o.side == OrderSide.SELL: + state.vars.limitka = o.id + if o.side == OrderSide.BUY: + pendingbuys_new[str(o.id)]=o.limit_price + + print("Nová LIMITKA", state.vars.limitka) + if pendingbuys_new != 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) + 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) + + #print(limitka) + #print(pendingbuys_new) + #print(pendingbuys) + #print(len(pendingbuys)) + #print(len(pendingbuys_new)) + #print(jevylozeno) + print("***CONSOLIDATION EXIT***") + + else: + print("no time for consolidation", data["index"]) + + + + #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 diff --git a/v2realbot/__pycache__/config.cpython-310.pyc b/v2realbot/__pycache__/config.cpython-310.pyc index 7a5c5de..0f906ea 100644 Binary files a/v2realbot/__pycache__/config.cpython-310.pyc and b/v2realbot/__pycache__/config.cpython-310.pyc differ diff --git a/v2realbot/backtesting/__pycache__/backtester.cpython-310.pyc b/v2realbot/backtesting/__pycache__/backtester.cpython-310.pyc index 965fe2d..3a47187 100644 Binary files a/v2realbot/backtesting/__pycache__/backtester.cpython-310.pyc and b/v2realbot/backtesting/__pycache__/backtester.cpython-310.pyc differ diff --git a/v2realbot/backtesting/backtester.py b/v2realbot/backtesting/backtester.py index 19b7770..d914b45 100644 --- a/v2realbot/backtesting/backtester.py +++ b/v2realbot/backtesting/backtester.py @@ -516,8 +516,10 @@ class Backtester: res = [] #with lock: for o in self.open_orders: - if str(o.side) == side and o.symbol == symbol: - res.append(o) + #print(o) + if o.symbol == symbol: + if side is None or o.side == side: + res.append(o) return res def display_backtest_result(self, state): diff --git a/v2realbot/interfaces/__pycache__/backtest_interface.cpython-310.pyc b/v2realbot/interfaces/__pycache__/backtest_interface.cpython-310.pyc index 4857509..bdb1d86 100644 Binary files a/v2realbot/interfaces/__pycache__/backtest_interface.cpython-310.pyc and b/v2realbot/interfaces/__pycache__/backtest_interface.cpython-310.pyc differ diff --git a/v2realbot/interfaces/__pycache__/live_interface.cpython-310.pyc b/v2realbot/interfaces/__pycache__/live_interface.cpython-310.pyc index 2e4a1dd..f50c098 100644 Binary files a/v2realbot/interfaces/__pycache__/live_interface.cpython-310.pyc and b/v2realbot/interfaces/__pycache__/live_interface.cpython-310.pyc differ diff --git a/v2realbot/interfaces/live_interface.py b/v2realbot/interfaces/live_interface.py index 46e29d3..b877635 100644 --- a/v2realbot/interfaces/live_interface.py +++ b/v2realbot/interfaces/live_interface.py @@ -7,7 +7,7 @@ from alpaca.trading.enums import OrderSide, TimeInForce, OrderClass, OrderStatus from alpaca.trading.models import Order, Position from alpaca.common.exceptions import APIError from v2realbot.config import Keys -from interfaces.general_interface import GeneralInterface +from v2realbot.interfaces.general_interface import GeneralInterface """"" Live interface with Alpaca for LIVE and PAPER trading. """"" @@ -149,7 +149,7 @@ class LiveInterface(GeneralInterface): #order doesnt exist if e.code == 40410000: return 0,0 else: - print("nepovedlo se zrusit objednavku") + print("nepovedlo se zrusit objednavku", str(e)) #raise Exception(e) return -1 diff --git a/v2realbot/main.py b/v2realbot/main.py index 5ecc708..0cf90d0 100644 --- a/v2realbot/main.py +++ b/v2realbot/main.py @@ -31,7 +31,7 @@ ic.configureOutput(includeContext=True) def threadName(): return '%s |> ' % str(current_thread().name) ic.configureOutput(prefix=threadName) -ic.disable() +#ic.disable() """"" Main entry point of the bot. Starts strategies according to config file, each in separate thread.