dev progress

This commit is contained in:
2025-12-30 10:52:33 +00:00
parent 2e32b26fad
commit 121c85def0
20 changed files with 211 additions and 515 deletions
+25 -23
View File
@@ -8,8 +8,7 @@ import pandas as pd
# ---
from cvttpy_tools.base import NamedObject
from cvttpy_tools.app import App
from cvttpy_tools.logger import Log
from cvttpy_tools.settings.cvtt_types import JsonDictT
from cvttpy_tools.settings.cvtt_types import IntervalSecT
# ---
from cvttpy_trading.trading.instrument import ExchangeInstrument
from cvttpy_trading.trading.mkt_data.md_summary import MdTradesAggregate
@@ -18,7 +17,6 @@ from pairs_trading.lib.pt_strategy.model_data_policy import ModelDataPolicy
from pairs_trading.lib.pt_strategy.pt_model import Prediction
from pairs_trading.lib.pt_strategy.trading_pair import PairState, TradingPair
from pairs_trading.apps.pairs_trader import PairsTrader
from pairs_trading.lib.pt_strategy.pt_market_data import RealTimeMarketData
"""
--config=pair.cfg
--pair=PAIR-BTC-USDT:COINBASE_AT,PAIR-ETH-USDT:COINBASE_AT
@@ -41,7 +39,6 @@ class PtLiveStrategy(NamedObject):
model_data_policy_: ModelDataPolicy
pairs_trader_: PairsTrader
pt_mkt_data_: RealTimeMarketData
# ti_sender_: TradingInstructionsSender
# for presentation: history of prediction values and trading signals
@@ -90,27 +87,32 @@ class PtLiveStrategy(NamedObject):
pass # URGENT PtiveStrategy.on_mkt_data_hist_snapshot()
async def on_mkt_data_update(self, aggr: MdTradesAggregate) -> None:
market_data_df = await self.pt_mkt_data_.on_mkt_data_update(update=aggr)
if market_data_df is not None:
self.trading_pair_.market_data_ = market_data_df
self.model_data_policy_.advance()
prediction = self.trading_pair_.run(
market_data_df, self.model_data_policy_.advance()
)
self.predictions_ = pd.concat(
[self.predictions_, prediction.to_df()], ignore_index=True
)
# if market_data_df is not None:
# self.trading_pair_.market_data_ = market_data_df
# self.model_data_policy_.advance()
# prediction = self.trading_pair_.run(
# market_data_df, self.model_data_policy_.advance()
# )
# self.predictions_ = pd.concat(
# [self.predictions_, prediction.to_df()], ignore_index=True
# )
trading_instructions: List[TradingInstruction] = (
self._create_trading_instructions(
prediction=prediction, last_row=market_data_df.iloc[-1]
)
)
if len(trading_instructions) > 0:
await self._send_trading_instructions(trading_instructions)
# trades = self._create_trades(prediction=prediction, last_row=market_data_df.iloc[-1])
pass
# trading_instructions: List[TradingInstruction] = (
# self._create_trading_instructions(
# prediction=prediction, last_row=market_data_df.iloc[-1]
# )
# )
# if len(trading_instructions) > 0:
# await self._send_trading_instructions(trading_instructions)
# # trades = self._create_trades(prediction=prediction, last_row=market_data_df.iloc[-1])
pass # URGENT
def interval_sec(self) -> IntervalSecT:
return 60 # URGENT use config
def history_depth_sec(self) -> IntervalSecT:
return 3600 * 60 * 2 # URGENT use config
async def _send_trading_instructions(
self, trading_instructions: List[TradingInstruction]
) -> None:
@@ -1,87 +0,0 @@
```python
from __future__ import annotations
from functools import partial
from typing import Dict, List
# from cvtt_client.mkt_data import (CvttPricerWebSockClient,
# CvttPricesSubscription, MessageTypeT,
# SubscriptionIdT)
from cvttpy_tools.app import App
from cvttpy_tools.base import NamedObject
from cvttpy_tools.config import Config
from cvttpy_tools.logger import Log
from cvttpy_tools.settings.cvtt_types import JsonDictT
from pairs_trading.lib.pt_strategy.live.live_strategy import PtLiveStrategy
from pairs_trading.lib.pt_strategy.trading_pair import TradingPair
"""
--config=pair.cfg
--pair=PAIR-BTC-USDT:COINBASE_AT,PAIR-ETH-USDT:COINBASE_AT
"""
class PtMktDataClient(NamedObject):
config_: Config
live_strategy_: PtLiveStrategy
pricer_client_: CvttPricerWebSockClient
subscriptions_: List[CvttPricesSubscription]
def __init__(self, live_strategy: PtLiveStrategy, pricer_config: Config):
self.config_ = pricer_config
self.live_strategy_ = live_strategy
App.instance().add_call(App.Stage.Start, self._on_start())
App.instance().add_call(App.Stage.Run, self.run())
async def _on_start(self) -> None:
pricer_url = self.config_.get_value("pricer_url")
assert pricer_url is not None, "pricer_url is not found in config"
self.pricer_client_ = CvttPricerWebSockClient(url=pricer_url)
async def _subscribe(self) -> None:
history_depth_sec = self.config_.get_value("history_depth_sec", 86400)
interval_sec = self.config_.get_value("interval_sec", 60)
pair: TradingPair = self.live_strategy_.trading_pair_
subscriptions = [CvttPricesSubscription(
exchange_config_name=instrument["exchange_config_name"],
instrument_id=instrument["instrument_id"],
interval_sec=interval_sec,
history_depth_sec=history_depth_sec,
callback=partial(
self.on_message, instrument_id=instrument["instrument_id"]
),
) for instrument in pair.instruments_]
for subscription in subscriptions:
Log.info(f"{self.fname()} Subscribing to {subscription}")
await self.pricer_client_.subscribe(subscription)
async def on_message(
self,
message_type: MessageTypeT,
subscr_id: SubscriptionIdT,
message: Dict,
instrument_id: str,
) -> None:
Log.info(f"{self.fname()}: {message_type=} {subscr_id=} {instrument_id}")
aggr: JsonDictT
if message_type == "md_aggregate":
aggr = message.get("md_aggregate", {})
await self.live_strategy_.on_mkt_data_update(aggr)
elif message_type == "historical_md_aggregate":
aggr = message.get("historical_data", {})
await self.live_strategy_.on_mkt_data_hist_snapshot(aggr)
else:
Log.info(f"Unknown message type: {message_type}")
async def run(self) -> None:
if not await CvttPricerWebSockClient.check_connection(self.pricer_client_.ws_url_):
Log.error(f"Unable to connect to {self.pricer_client_.ws_url_}")
raise Exception(f"Unable to connect to {self.pricer_client_.ws_url_}")
await self._subscribe()
await self.pricer_client_.run()
```
+1 -1
View File
@@ -91,7 +91,7 @@ class OptimizedWndDataPolicy(ModelDataPolicy, ABC):
self.min_training_size_ = cast(int, config.get("min_training_size"))
self.max_training_size_ = cast(int, config.get("max_training_size"))
from pt_strategy.trading_pair import TradingPair
from pairs_trading.lib.pt_strategy.trading_pair import TradingPair
self.pair_ = cast(TradingPair, kwargs.get("pair"))
if "mkt_data" in kwargs:
+2 -2
View File
@@ -6,8 +6,8 @@ import statsmodels.api as sm
from pt_strategy.pt_model import PairsTradingModel, Prediction
from pt_strategy.trading_pair import TradingPair
from pairs_trading.lib.pt_strategy.pt_model import PairsTradingModel, Prediction
from pairs_trading.lib.pt_strategy.trading_pair import TradingPair
class OLSModel(PairsTradingModel):
-60
View File
@@ -171,63 +171,3 @@ class ResearchMarketData(PtMarketData):
f"exec_price_{self.symbol_b_}",
]
class RealTimeMarketData(PtMarketData):
def __init__(self, config: Dict[str, Any], *args: Any, **kwargs: Any):
super().__init__(config, *args, **kwargs)
async def on_mkt_data_hist_snapshot(self, snapshot: JsonDictT) -> None:
# URGENT
# create origin_mkt_data_df_ from snapshot
# verify that the data for both instruments are present
# transform it to market_data_df_ tstamp, close_symbolA, close_symbolB
'''
# from cvttpy/exchanges/binance/spot/mkt_data.py
values = {
"time_ns": time_ns,
"tstamp": format_nanos_utc(time_ns),
"exchange_id": exch_inst.exchange_id_,
"instrument_id": exch_inst.instrument_id(),
"interval_ns": interval_sec * 1_000_000_000,
"open": float(kline[1]),
"high": float(kline[2]),
"low": float(kline[3]),
"close": float(kline[4]),
"volume": float(kline[5]),
"num_trades": kline[8],
"vwap": float(kline[7]) / float(kline[5]) if float(kline[5]) > 0 else 0.0 # Calculate VWAP
}
'''
pass
async def on_mkt_data_update(self, update: MdTradesAggregate) -> Optional[pd.DataFrame]:
# URGENT
# make sure update has both instruments
# create DataFrame tmp1 from update
# transform tmp1 into temp. datframe tmp2
# add tmp1 to origin_mkt_data_df_
# add tmp2 to market_data_df_
# return market_data_df_
'''
class MdTradesAggregate(NamedObject):
def to_dict(self) -> Dict[str, Any]:
return {
"time_ns": self.time_ns_,
"tstamp": format_nanos_utc(self.time_ns_),
"exchange_id": self.exch_inst_.exchange_id_,
"instrument_id": self.exch_inst_.instrument_id(),
"interval_ns": self.interval_ns_,
"open": self.exch_inst_.get_price(self.open_),
"high": self.exch_inst_.get_price(self.high_),
"low": self.exch_inst_.get_price(self.low_),
"close": self.exch_inst_.get_price(self.close_),
"volume": self.exch_inst_.get_quantity(self.volume_),
"vwap": self.exch_inst_.get_price(self.vwap_),
"num_trades": self.exch_inst_.get_quantity(self.num_trades_),
}
'''
return pd.DataFrame()
+6 -6
View File
@@ -3,10 +3,10 @@ from __future__ import annotations
from typing import Any, Dict, List, Optional
import pandas as pd
from pt_strategy.model_data_policy import ModelDataPolicy
from pt_strategy.pt_market_data import ResearchMarketData
from pt_strategy.pt_model import Prediction
from pt_strategy.trading_pair import PairState, TradingPair
from pairs_trading.lib.pt_strategy.model_data_policy import ModelDataPolicy
from pairs_trading.lib.pt_strategy.pt_market_data import ResearchMarketData
from pairs_trading.lib.pt_strategy.pt_model import Prediction
from pairs_trading.lib.pt_strategy.trading_pair import PairState, TradingPair
class PtResearchStrategy:
@@ -24,8 +24,8 @@ class PtResearchStrategy:
datafiles: List[str],
instruments: List[Dict[str, str]],
):
from pt_strategy.model_data_policy import ModelDataPolicy
from pt_strategy.trading_pair import TradingPair
from pairs_trading.lib.pt_strategy.model_data_policy import ModelDataPolicy
from pairs_trading.lib.pt_strategy.trading_pair import TradingPair
self.config_ = config
self.trades_ = []
+1 -1
View File
@@ -4,7 +4,7 @@ from datetime import date, datetime
from typing import Any, Dict, List, Optional, Tuple
import pandas as pd
from pt_strategy.trading_pair import TradingPair
from pairs_trading.lib.pt_strategy.trading_pair import TradingPair
# Recommended replacement adapters and converters for Python 3.12+
+1 -1
View File
@@ -57,7 +57,7 @@ class TradingPair:
instruments: List[Dict[str, str]],
):
from pt_strategy.pt_model import PairsTradingModel
from pairs_trading.lib.pt_strategy.pt_model import PairsTradingModel
assert len(instruments) == 2, "Trading pair must have exactly 2 instruments"