#168 #166 and additional fixes (#169)

This commit is contained in:
David Brazda
2024-03-13 12:31:06 +01:00
committed by GitHub
parent 801ce61c9d
commit 878092fe93
11 changed files with 130 additions and 71 deletions

View File

@ -23,12 +23,12 @@ clientTrading = TradingClient(ACCOUNT1_PAPER_API_KEY, ACCOUNT1_PAPER_SECRET_KEY,
#get previous days bar #get previous days bar
datetime_object_from = datetime.datetime(2023, 10, 11, 4, 0, 00, tzinfo=datetime.timezone.utc) datetime_object_from = datetime.datetime(2024, 3, 9, 13, 29, 00, tzinfo=datetime.timezone.utc)
datetime_object_to = datetime.datetime(2023, 10, 16, 16, 1, 00, tzinfo=datetime.timezone.utc) datetime_object_to = datetime.datetime(2024, 3, 11, 20, 1, 00, tzinfo=datetime.timezone.utc)
calendar_request = GetCalendarRequest(start=datetime_object_from,end=datetime_object_to) # calendar_request = GetCalendarRequest(start=datetime_object_from,end=datetime_object_to)
cal_dates = clientTrading.get_calendar(calendar_request) # cal_dates = clientTrading.get_calendar(calendar_request)
print(cal_dates) # print(cal_dates)
bar_request = StockBarsRequest(symbol_or_symbols="BAC",timeframe=TimeFrame.Day, start=datetime_object_from, end=datetime_object_to, feed=DataFeed.SIP) bar_request = StockBarsRequest(symbol_or_symbols="BAC",timeframe=TimeFrame.Minute, start=datetime_object_from, end=datetime_object_to, feed=DataFeed.SIP)
# bars = client.get_stock_bars(bar_request).df # bars = client.get_stock_bars(bar_request).df

View File

@ -115,6 +115,9 @@ def init(state: StrategyState):
#models #models
state.vars.loaded_models = {} state.vars.loaded_models = {}
#state attributes for martingale sizing mngmt
state.vars["martingale"] = dict(cont_loss_series_cnt=0)
#INITIALIZE CBAR INDICATORS - do vlastni funkce #INITIALIZE CBAR INDICATORS - do vlastni funkce
#state.cbar_indicators['ivwap'] = [] #state.cbar_indicators['ivwap'] = []
state.vars.last_tick_price = 0 state.vars.last_tick_price = 0

View File

@ -40,7 +40,7 @@
from uuid import UUID, uuid4 from uuid import UUID, uuid4
from alpaca.trading.enums import OrderSide, OrderStatus, TradeEvent, OrderType from alpaca.trading.enums import OrderSide, OrderStatus, TradeEvent, OrderType
from v2realbot.common.model import TradeUpdate, Order from v2realbot.common.model import TradeUpdate, Order
#from rich import print from rich import print as printanyway
import threading import threading
import asyncio import asyncio
from v2realbot.config import DATA_DIR from v2realbot.config import DATA_DIR
@ -479,11 +479,11 @@ class Backtester:
print("BT: submit order entry") print("BT: submit order entry")
if not time or time < 0: if not time or time < 0:
print("time musi byt vyplneny") printanyway("time musi byt vyplneny")
return -1 return -1
if not size or int(size) < 0: if not size or int(size) < 0:
print("size musi byt vetsi nez 0") printanyway("size musi byt vetsi nez 0")
return -1 return -1
if (order_type != OrderType.MARKET) and (order_type != OrderType.LIMIT): if (order_type != OrderType.MARKET) and (order_type != OrderType.LIMIT):
@ -491,11 +491,11 @@ class Backtester:
return -1 return -1
if not side == OrderSide.BUY and not side == OrderSide.SELL: if not side == OrderSide.BUY and not side == OrderSide.SELL:
print("side buy/sell required") printanyway("side buy/sell required")
return -1 return -1
if order_type == OrderType.LIMIT and count_decimals(price) > 2: if order_type == OrderType.LIMIT and count_decimals(price) > 2:
print("only 2 decimals supported", price) printanyway("only 2 decimals supported", price)
return -1 return -1
#pokud neexistuje klic v accountu vytvorime si ho #pokud neexistuje klic v accountu vytvorime si ho
@ -517,14 +517,14 @@ class Backtester:
actual_minus_reserved = int(self.account[symbol][0]) - reserved actual_minus_reserved = int(self.account[symbol][0]) - reserved
if actual_minus_reserved > 0 and actual_minus_reserved - int(size) < 0: if actual_minus_reserved > 0 and actual_minus_reserved - int(size) < 0:
print("not enough shares available to sell or shorting while long position",self.account[symbol][0],"reserved",reserved,"available",int(self.account[symbol][0]) - reserved,"selling",size) printanyway("not enough shares available to sell or shorting while long position",self.account[symbol][0],"reserved",reserved,"available",int(self.account[symbol][0]) - reserved,"selling",size)
return -1 return -1
#if is shorting - check available cash to short #if is shorting - check available cash to short
if actual_minus_reserved <= 0: if actual_minus_reserved <= 0:
cena = price if price else self.get_last_price(time, self.symbol) cena = price if price else self.get_last_price(time, self.symbol)
if (self.cash - reserved_price - float(int(size)*float(cena))) < 0: if (self.cash - reserved_price - float(int(size)*float(cena))) < 0:
print("not enough cash for shorting. cash",self.cash,"reserved",reserved,"available",self.cash-reserved,"needed",float(int(size)*float(cena))) printanyway("not enough cash for shorting. cash",self.cash,"reserved",reserved,"available",self.cash-reserved,"needed",float(int(size)*float(cena)))
return -1 return -1
#check for available cash #check for available cash
@ -543,14 +543,14 @@ class Backtester:
#jde o uzavreni shortu #jde o uzavreni shortu
if actual_plus_reserved_qty < 0 and (actual_plus_reserved_qty + int(size)) > 0: if actual_plus_reserved_qty < 0 and (actual_plus_reserved_qty + int(size)) > 0:
print("nejprve je treba uzavrit short pozici pro buy res_qty, size", actual_plus_reserved_qty, size) printanyway("nejprve je treba uzavrit short pozici pro buy res_qty, size", actual_plus_reserved_qty, size)
return -1 return -1
#jde o standardni long, kontroluju cash #jde o standardni long, kontroluju cash
if actual_plus_reserved_qty >= 0: if actual_plus_reserved_qty >= 0:
cena = price if price else self.get_last_price(time, self.symbol) cena = price if price else self.get_last_price(time, self.symbol)
if (self.cash - reserved_price - float(int(size)*float(cena))) < 0: if (self.cash - reserved_price - float(int(size)*float(cena))) < 0:
print("not enough cash to buy long. cash",self.cash,"reserved_qty",reserved_qty,"reserved_price",reserved_price, "available",self.cash-reserved_price,"needed",float(int(size)*float(cena))) printanyway("not enough cash to buy long. cash",self.cash,"reserved_qty",reserved_qty,"reserved_price",reserved_price, "available",self.cash-reserved_price,"needed",float(int(size)*float(cena)))
return -1 return -1
id = str(uuid4()) id = str(uuid4())
@ -577,11 +577,11 @@ class Backtester:
print("BT: replace order entry",id,size,price) print("BT: replace order entry",id,size,price)
if not price and not size: if not price and not size:
print("size or price required") printanyway("size or price required")
return -1 return -1
if len(self.open_orders) == 0: if len(self.open_orders) == 0:
print("BT: order doesnt exist") printanyway("BT: order doesnt exist")
return 0 return 0
#with lock: #with lock:
for o in self.open_orders: for o in self.open_orders:
@ -609,7 +609,7 @@ class Backtester:
""" """
print("BT: cancel order entry",id) print("BT: cancel order entry",id)
if len(self.open_orders) == 0: if len(self.open_orders) == 0:
print("BTC: order doesnt exist") printanyway("BTC: order doesnt exist")
return 0 return 0
#with lock: #with lock:
for o in self.open_orders: for o in self.open_orders:

View File

@ -94,12 +94,12 @@ class TestList(BaseModel):
class Trade(BaseModel): class Trade(BaseModel):
symbol: str symbol: str
timestamp: datetime timestamp: datetime
exchange: Optional[Union[Exchange, str]] exchange: Optional[Union[Exchange, str]] = None
price: float price: float
size: float size: float
id: int id: int
conditions: Optional[List[str]] conditions: Optional[List[str]] = None
tape: Optional[str] tape: Optional[str] = None
#persisted object in pickle #persisted object in pickle
@ -114,8 +114,20 @@ class StrategyInstance(BaseModel):
close_rush: int = 0 close_rush: int = 0
stratvars_conf: str stratvars_conf: str
add_data_conf: str add_data_conf: str
note: Optional[str] note: Optional[str] = None
history: Optional[str] history: Optional[str] = None
def __setstate__(self, state: dict[Any, Any]) -> None:
"""
Hack to allow unpickling models stored from pydantic V1
"""
state.setdefault("__pydantic_extra__", {})
state.setdefault("__pydantic_private__", {})
if "__pydantic_fields_set__" not in state:
state["__pydantic_fields_set__"] = state.get("__fields_set__")
super().__setstate__(state)
class RunRequest(BaseModel): class RunRequest(BaseModel):
id: UUID id: UUID
@ -125,8 +137,8 @@ class RunRequest(BaseModel):
debug: bool = False debug: bool = False
strat_json: Optional[str] = None strat_json: Optional[str] = None
ilog_save: bool = False ilog_save: bool = False
bt_from: datetime = None bt_from: Optional[datetime] = None
bt_to: datetime = None bt_to: Optional[datetime] = None
#weekdays filter #weekdays filter
#pokud je uvedeny filtrujeme tyto dny #pokud je uvedeny filtrujeme tyto dny
weekdays_filter: Optional[list] = None weekdays_filter: Optional[list] = None
@ -147,8 +159,8 @@ class RunManagerRecord(BaseModel):
mode: Mode mode: Mode
note: Optional[str] = None note: Optional[str] = None
ilog_save: bool = False ilog_save: bool = False
bt_from: datetime = None bt_from: Optional[datetime] = None
bt_to: datetime = None bt_to: Optional[datetime] = None
#weekdays filter #weekdays filter
#pokud je uvedeny filtrujeme tyto dny #pokud je uvedeny filtrujeme tyto dny
weekdays_filter: Optional[list] = None #list of strings 0-6 representing days to run weekdays_filter: Optional[list] = None #list of strings 0-6 representing days to run
@ -156,9 +168,9 @@ class RunManagerRecord(BaseModel):
batch_id: Optional[str] = None batch_id: Optional[str] = None
testlist_id: Optional[str] = None testlist_id: Optional[str] = None
start_time: str #time (HH:MM) that start function is called start_time: str #time (HH:MM) that start function is called
stop_time: Optional[str] #time (HH:MM) that stop function is called stop_time: Optional[str] = None #time (HH:MM) that stop function is called
status: SchedulerStatus status: SchedulerStatus
last_processed: Optional[datetime] last_processed: Optional[datetime] = None
history: Optional[str] = None history: Optional[str] = None
valid_from: Optional[datetime] = None # US East time zone daetime valid_from: Optional[datetime] = None # US East time zone daetime
valid_to: Optional[datetime] = None # US East time zone daetime valid_to: Optional[datetime] = None # US East time zone daetime
@ -193,10 +205,10 @@ class Runner(BaseModel):
run_name: Optional[str] = None run_name: Optional[str] = None
run_note: Optional[str] = None run_note: Optional[str] = None
run_ilog_save: Optional[bool] = False run_ilog_save: Optional[bool] = False
run_trade_count: Optional[int] run_trade_count: Optional[int] = None
run_profit: Optional[float] run_profit: Optional[float] = None
run_positions: Optional[int] run_positions: Optional[int] = None
run_avgp: Optional[float] run_avgp: Optional[float] = None
run_strat_json: Optional[str] = None run_strat_json: Optional[str] = None
run_stopped: Optional[datetime] = None run_stopped: Optional[datetime] = None
run_paused: Optional[datetime] = None run_paused: Optional[datetime] = None
@ -230,41 +242,41 @@ class Bar(BaseModel):
low: float low: float
close: float close: float
volume: float volume: float
trade_count: Optional[float] trade_count: Optional[float] = 0
vwap: Optional[float] vwap: Optional[float] = 0
class Order(BaseModel): class Order(BaseModel):
id: UUID id: UUID
submitted_at: datetime submitted_at: datetime
filled_at: Optional[datetime] filled_at: Optional[datetime] = None
canceled_at: Optional[datetime] canceled_at: Optional[datetime] = None
symbol: str symbol: str
qty: int qty: int
status: OrderStatus status: OrderStatus
order_type: OrderType order_type: OrderType
filled_qty: Optional[int] filled_qty: Optional[int] = None
filled_avg_price: Optional[float] filled_avg_price: Optional[float] = None
side: OrderSide side: OrderSide
limit_price: Optional[float] limit_price: Optional[float] = None
#entita pro kazdy kompletni FILL, je navazana na prescribed_trade #entita pro kazdy kompletni FILL, je navazana na prescribed_trade
class TradeUpdate(BaseModel): class TradeUpdate(BaseModel):
event: Union[TradeEvent, str] event: Union[TradeEvent, str]
execution_id: Optional[UUID] execution_id: Optional[UUID] = None
order: Order order: Order
timestamp: datetime timestamp: datetime
position_qty: Optional[float] position_qty: Optional[float] = None
price: Optional[float] price: Optional[float] = None
qty: Optional[float] qty: Optional[float] = None
value: Optional[float] value: Optional[float] = None
cash: Optional[float] cash: Optional[float] = None
pos_avg_price: Optional[float] pos_avg_price: Optional[float] = None
profit: Optional[float] profit: Optional[float] = None
profit_sum: Optional[float] profit_sum: Optional[float] = None
rel_profit: Optional[float] rel_profit: Optional[float] = None
rel_profit_cum: Optional[float] rel_profit_cum: Optional[float] = None
signal_name: Optional[str] signal_name: Optional[str] = None
prescribed_trade_id: Optional[str] prescribed_trade_id: Optional[str] = None
class RunArchiveChange(BaseModel): class RunArchiveChange(BaseModel):
@ -332,7 +344,7 @@ class RunArchiveViewPagination(BaseModel):
#trida pro ukladani historie stoplossy do ext_data #trida pro ukladani historie stoplossy do ext_data
class SLHistory(BaseModel): class SLHistory(BaseModel):
id: Optional[UUID] id: Optional[UUID] = None
time: datetime time: datetime
sl_val: float sl_val: float
@ -345,7 +357,7 @@ class RunArchiveDetail(BaseModel):
indicators: List[dict] indicators: List[dict]
statinds: dict statinds: dict
trades: List[TradeUpdate] trades: List[TradeUpdate]
ext_data: Optional[dict] ext_data: Optional[dict] = None
class InstantIndicator(BaseModel): class InstantIndicator(BaseModel):

View File

@ -1896,7 +1896,7 @@ def get_alpaca_history_bars(symbol: str, datetime_object_from: datetime, datetim
# Workaround of error when no data foun d AttributeError and has the specific message # Workaround of error when no data foun d AttributeError and has the specific message
if isinstance(e, AttributeError) and str(e) == "'NoneType' object has no attribute 'items'": if isinstance(e, AttributeError) and str(e) == "'NoneType' object has no attribute 'items'":
print("Caught the specific AttributeError: 'NoneType' object has no attribute 'items' means NO DATA FOUND") print("Caught the specific AttributeError: 'NoneType' object has no attribute 'items' means NO DATA FOUND")
#print(str(e) + format_exc()) print(str(e) + format_exc())
return 0, result return 0, result
else: else:
print(str(e) + format_exc()) print(str(e) + format_exc())

View File

@ -40,7 +40,9 @@ class LiveInterface(GeneralInterface):
return market_order.id return market_order.id
except Exception as e: except Exception as e:
print("Nepodarilo se odeslat buy", str(e)) reason = "Nepodarilo se market buy:" + str(e) + format_exc()
print(reason)
send_to_telegram(reason)
return -1 return -1
"""buy limit""" """buy limit"""
@ -65,7 +67,9 @@ class LiveInterface(GeneralInterface):
return limit_order.id return limit_order.id
except Exception as e: except Exception as e:
print("Nepodarilo se odeslat limitku", str(e)) reason = "Nepodarilo se odeslat buy limitku:" + str(e) + format_exc()
print(reason)
send_to_telegram(reason)
return -1 return -1
"""sell market""" """sell market"""
@ -87,7 +91,9 @@ class LiveInterface(GeneralInterface):
return market_order.id return market_order.id
except Exception as e: except Exception as e:
print("Nepodarilo se odeslat sell", str(e)) reason = "Nepodarilo se odeslat sell:" + str(e) + format_exc()
print(reason)
send_to_telegram(reason)
return -1 return -1
"""sell limit""" """sell limit"""
@ -112,8 +118,9 @@ class LiveInterface(GeneralInterface):
return limit_order.id return limit_order.id
except Exception as e: except Exception as e:
print("Nepodarilo se odeslat sell_l", str(e)) reason = "Nepodarilo se odeslat sell limitku:" + str(e) + format_exc()
#raise Exception(e) print(reason)
send_to_telegram(reason)
return -1 return -1
"""order replace""" """order replace"""
@ -136,7 +143,9 @@ class LiveInterface(GeneralInterface):
if e.code == 42210000: return orderid if e.code == 42210000: return orderid
else: else:
##mozna tady proste vracet vzdy ok ##mozna tady proste vracet vzdy ok
print("Neslo nahradit profitku. Problem",str(e)) reason = "Neslo nahradit profitku. Problem:" + str(e) + format_exc()
print(reason)
send_to_telegram(reason)
return -1 return -1
#raise Exception(e) #raise Exception(e)
@ -150,7 +159,9 @@ class LiveInterface(GeneralInterface):
#order doesnt exist #order doesnt exist
if e.code == 40410000: return 0 if e.code == 40410000: return 0
else: else:
print("nepovedlo se zrusit objednavku", str(e)) reason = "Nepovedlo se zrusit objednavku:" + str(e) + format_exc()
print(reason)
send_to_telegram(reason)
#raise Exception(e) #raise Exception(e)
return -1 return -1
@ -178,7 +189,9 @@ class LiveInterface(GeneralInterface):
#list of Orders (orderlist[0].id) #list of Orders (orderlist[0].id)
return orderlist return orderlist
except Exception as e: except Exception as e:
print("Chyba pri dotazeni objednávek.", str(e)) reason = "Chyba pri dotazeni objednávek:" + str(e) + format_exc()
print(reason)
send_to_telegram(reason)
#raise Exception (e) #raise Exception (e)
return -1 return -1

View File

@ -690,7 +690,8 @@ def _generate_analysis(analyzerInputs: AnalyzerInputs):
if res == 0: return StreamingResponse(stream, media_type="image/png") if res == 0: return StreamingResponse(stream, media_type="image/png")
elif res < 0: elif res < 0:
raise HTTPException(status_code=status.HTTP_406_NOT_ACCEPTABLE, detail=f"Error: {res}:{id}") print("Error when generating analysis: ",str(stream))
raise HTTPException(status_code=status.HTTP_406_NOT_ACCEPTABLE, detail=f"Error: {res}:{stream}")
except Exception as e: except Exception as e:
raise HTTPException(status_code=status.HTTP_406_NOT_ACCEPTABLE, detail=f"Error: {str(e)}" + format_exc()) raise HTTPException(status_code=status.HTTP_406_NOT_ACCEPTABLE, detail=f"Error: {str(e)}" + format_exc())

View File

@ -9,7 +9,7 @@ from alpaca.trading.enums import TradeEvent, OrderStatus
from v2realbot.indicators.indicators import ema from v2realbot.indicators.indicators import ema
import orjson import orjson
from datetime import datetime from datetime import datetime
#from rich import print from rich import print as printanyway
from random import randrange from random import randrange
from alpaca.common.exceptions import APIError from alpaca.common.exceptions import APIError
import numpy as np import numpy as np
@ -153,6 +153,10 @@ class StrategyClassicSL(Strategy):
self.state.rel_profit_cum.append(rel_profit) self.state.rel_profit_cum.append(rel_profit)
rel_profit_cum_calculated = round(np.sum(self.state.rel_profit_cum),5) rel_profit_cum_calculated = round(np.sum(self.state.rel_profit_cum),5)
#pro martingale updatujeme loss_series_cnt
self.state.vars["martingale"]["cont_loss_series_cnt"] = 0 if rel_profit > 0 else self.state.vars["martingale"]["cont_loss_series_cnt"]+1
self.state.ilog(lvl=1, e=f"update cont_loss_series_cnt na {self.state.vars['martingale']['cont_loss_series_cnt']}")
self.state.ilog(e=f"BUY notif - SHORT PROFIT: {partial_exit=} {partial_last=} {round(float(trade_profit),3)} celkem:{round(float(self.state.profit),3)} rel:{float(rel_profit)} rel_cum:{round(rel_profit_cum_calculated,7)}", msg=str(data.event), rel_profit_cum=str(self.state.rel_profit_cum), bought_amount=bought_amount, avg_costs=avg_costs, trade_qty=data.qty, trade_price=data.price, orderid=str(data.order.id)) self.state.ilog(e=f"BUY notif - SHORT PROFIT: {partial_exit=} {partial_last=} {round(float(trade_profit),3)} celkem:{round(float(self.state.profit),3)} rel:{float(rel_profit)} rel_cum:{round(rel_profit_cum_calculated,7)}", msg=str(data.event), rel_profit_cum=str(self.state.rel_profit_cum), bought_amount=bought_amount, avg_costs=avg_costs, trade_qty=data.qty, trade_price=data.price, orderid=str(data.order.id))
#zapsat profit do prescr.trades #zapsat profit do prescr.trades
@ -298,6 +302,10 @@ class StrategyClassicSL(Strategy):
self.state.rel_profit_cum.append(rel_profit) self.state.rel_profit_cum.append(rel_profit)
rel_profit_cum_calculated = round(np.sum(self.state.rel_profit_cum),5) rel_profit_cum_calculated = round(np.sum(self.state.rel_profit_cum),5)
#pro martingale updatujeme loss_series_cnt
self.state.vars["martingale"]["cont_loss_series_cnt"] = 0 if rel_profit > 0 else self.state.vars["martingale"]["cont_loss_series_cnt"]+1
self.state.ilog(lvl=1, e=f"update cont_loss_series_cnt na {self.state.vars['martingale']['cont_loss_series_cnt']}")
self.state.ilog(e=f"SELL notif - LONG PROFIT {partial_exit=} {partial_last=}:{round(float(trade_profit),3)} celkem:{round(float(self.state.profit),3)} rel:{float(rel_profit)} rel_cum:{round(rel_profit_cum_calculated,7)}", msg=str(data.event), rel_profit_cum = str(self.state.rel_profit_cum), sold_amount=sold_amount, avg_costs=avg_costs, trade_qty=data.qty, trade_price=data.price, orderid=str(data.order.id)) self.state.ilog(e=f"SELL notif - LONG PROFIT {partial_exit=} {partial_last=}:{round(float(trade_profit),3)} celkem:{round(float(self.state.profit),3)} rel:{float(rel_profit)} rel_cum:{round(rel_profit_cum_calculated,7)}", msg=str(data.event), rel_profit_cum = str(self.state.rel_profit_cum), sold_amount=sold_amount, avg_costs=avg_costs, trade_qty=data.qty, trade_price=data.price, orderid=str(data.order.id))
#zapsat profit do prescr.trades #zapsat profit do prescr.trades
@ -423,12 +431,12 @@ class StrategyClassicSL(Strategy):
#jde o uzavreni short pozice #jde o uzavreni short pozice
if int(self.state.positions) < 0 and (int(self.state.positions) + int(sizer)) > 0: if int(self.state.positions) < 0 and (int(self.state.positions) + int(sizer)) > 0:
self.state.ilog(e="buy nelze nakoupit vic nez shortuji", positions=self.state.positions, size=size) self.state.ilog(e="buy nelze nakoupit vic nez shortuji", positions=self.state.positions, size=size)
print("buy nelze nakoupit vic nez shortuji") printanyway("buy nelze nakoupit vic nez shortuji")
return -2 return -2
if int(self.state.positions) >= self.state.vars.maxpozic: if int(self.state.positions) >= self.state.vars.maxpozic:
self.state.ilog(e="buy Maxim mnozstvi naplneno", positions=self.state.positions) self.state.ilog(e="buy Maxim mnozstvi naplneno", positions=self.state.positions)
print("max mnostvi naplneno") printanyway("max mnostvi naplneno")
return 0 return 0
self.state.blockbuy = 1 self.state.blockbuy = 1
@ -447,13 +455,13 @@ class StrategyClassicSL(Strategy):
#jde o uzavreni long pozice #jde o uzavreni long pozice
if int(self.state.positions) > 0 and (int(self.state.positions) - int(size)) < 0: if int(self.state.positions) > 0 and (int(self.state.positions) - int(size)) < 0:
self.state.ilog(e="nelze prodat vic nez longuji", positions=self.state.positions, size=size) self.state.ilog(e="nelze prodat vic nez longuji", positions=self.state.positions, size=size)
print("nelze prodat vic nez longuji") printanyway("nelze prodat vic nez longuji")
return -2 return -2
#pokud shortuji a mam max pozic #pokud shortuji a mam max pozic
if int(self.state.positions) < 0 and abs(int(self.state.positions)) >= self.state.vars.maxpozic: if int(self.state.positions) < 0 and abs(int(self.state.positions)) >= self.state.vars.maxpozic:
self.state.ilog(e="short - Maxim mnozstvi naplneno", positions=self.state.positions, size=size) self.state.ilog(e="short - Maxim mnozstvi naplneno", positions=self.state.positions, size=size)
print("max mnostvi naplneno") printanyway("short - Maxim mnozstvi naplneno")
return 0 return 0
#self.state.blocksell = 1 #self.state.blocksell = 1

View File

@ -78,6 +78,7 @@ def execute_prescribed_trades(state: StrategyState, data):
size = state.vars.chunk size = state.vars.chunk
res = state.sell(size=size) res = state.sell(size=size)
if isinstance(res, int) and res < 0: if isinstance(res, int) and res < 0:
print(f"error in required operation SHORT {res}")
raise Exception(f"error in required operation SHORT {res}") raise Exception(f"error in required operation SHORT {res}")
#defaultní goalprice nastavujeme az v notifikaci #defaultní goalprice nastavujeme az v notifikaci

View File

@ -147,7 +147,18 @@ def get_multiplier(state: StrategyState, data, signaloptions: dict, direction: T
multiplier = f(input_value) multiplier = f(input_value)
state.ilog(lvl=1,e=f"SIZER - Interpolated value {multiplier}", input_value=input_value, pattern_source_axis=pattern_source_axis, pattern_size_axis=pattern_size_axis, options=options, time=state.time) state.ilog(lvl=1,e=f"SIZER - Interpolated value {multiplier}", input_value=input_value, pattern_source_axis=pattern_source_axis, pattern_size_axis=pattern_size_axis, options=options, time=state.time)
if multiplier > 1 or multiplier <= 0: martingale_enabled = utls.safe_get(options, "martingale_enabled", False)
#pocet ztrátových obchodů v řadě mi udává multiplikátor (0 - 1, 1 ztráta 2x, 3 v řadě - 4x atp.)
if martingale_enabled:
cont_loss_series_cnt = state.vars["martingale"]["cont_loss_series_cnt"]
if cont_loss_series_cnt == 0:
multiplier = 1
else:
multiplier = 2 ** cont_loss_series_cnt
state.ilog(lvl=1,e=f"SIZER - MARTINGALE {multiplier}", options=options, time=state.time, cont_loss_series_cnt=cont_loss_series_cnt)
if (martingale_enabled is False and multiplier > 1) or multiplier <= 0:
state.ilog(lvl=1,e=f"SIZER - Mame nekde problem MULTIPLIER mimo RANGE ERROR {multiplier}", options=options, time=state.time) state.ilog(lvl=1,e=f"SIZER - Mame nekde problem MULTIPLIER mimo RANGE ERROR {multiplier}", options=options, time=state.time)
multiplier = 1 multiplier = 1
return multiplier return multiplier

View File

@ -74,6 +74,16 @@ def fetch_calendar_data(start, end, max_retries=5, backoff_factor=1):
:return: Calendar data. :return: Calendar data.
:raises: ConnectionError if all retries fail. :raises: ConnectionError if all retries fail.
""" """
# Ensure start and end are of type datetime.date
if isinstance(start, datetime):
start = start.date()
if isinstance(end, datetime):
end = end.date()
# Verify that start and end are datetime.date objects after conversion
if not all([isinstance(start, date), isinstance(end, date)]):
raise ValueError("start and end must be datetime.date objects")
clientTrading = TradingClient(ACCOUNT1_PAPER_API_KEY, ACCOUNT1_PAPER_SECRET_KEY, raw_data=False) clientTrading = TradingClient(ACCOUNT1_PAPER_API_KEY, ACCOUNT1_PAPER_SECRET_KEY, raw_data=False)
calendar_request = GetCalendarRequest(start=start, end=end) calendar_request = GetCalendarRequest(start=start, end=end)
last_exception = None last_exception = None