or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-commands.mdconstants-enums.mddata-access.mddata-models.mdframework-core.mdindex.mdportfolio-management.mdstrategy-execution.mdtrading-api.md

framework-core.mddocs/

0

# Framework Core

1

2

Strategy context, execution framework, and event system providing the foundation for strategy development and lifecycle management. The core framework handles strategy execution phases, event processing, global state management, and provides the runtime environment for trading strategies.

3

4

## Capabilities

5

6

### Strategy Context

7

8

The central context object available to all strategy functions, providing access to portfolio, accounts, market data, and system state.

9

10

```python { .api }

11

class StrategyContext:

12

"""

13

Strategy context object (exposed as 'context' in strategies).

14

15

Properties:

16

- portfolio (Portfolio): Main portfolio object with all accounts and positions

17

- stock_account (Account): Stock trading account

18

- future_account (Account): Futures trading account

19

- bond_account (Account): Bond trading account

20

- now (datetime): Current strategy execution time

21

- universe (list[str]): Current strategy universe of instruments

22

- run_info (RunInfo): Strategy run information and metadata

23

- config (dict): Strategy configuration

24

25

Available in strategy functions as global 'context' variable.

26

"""

27

```

28

29

### Global Variables

30

31

Global variable namespace for user data persistence across strategy execution.

32

33

```python { .api }

34

# Global variables namespace (available as 'g' in strategies)

35

g = GlobalVars() # User namespace for storing custom data

36

37

# Usage in strategies:

38

def init(context):

39

g.my_variable = "some_value"

40

g.counters = {"buy": 0, "sell": 0}

41

42

def handle_bar(context, bar_dict):

43

g.counters["buy"] += 1

44

logger.info(f"My variable: {g.my_variable}")

45

```

46

47

### Event System

48

49

Event publishing and subscription system for strategy and system events.

50

51

```python { .api }

52

def subscribe_event(event_type, handler):

53

"""

54

Subscribe to system events.

55

56

Parameters:

57

- event_type (EVENT): Event type to subscribe to

58

- handler (callable): Event handler function

59

60

Returns:

61

None

62

63

The handler function receives (context, event_data) parameters.

64

"""

65

66

class Event:

67

"""

68

Event object for system messaging.

69

70

Properties:

71

- event_type (EVENT): Type of event

72

- timestamp (datetime): Event timestamp

73

- data (dict): Event-specific data

74

"""

75

76

class EventBus:

77

"""

78

Event publishing and subscription system.

79

80

Methods:

81

- publish_event(event): Publish event to subscribers

82

- add_listener(event_type, handler): Add event listener

83

- remove_listener(event_type, handler): Remove event listener

84

"""

85

```

86

87

### Strategy Execution Management

88

89

Core classes managing strategy lifecycle and execution phases.

90

91

```python { .api }

92

class Strategy:

93

"""

94

Strategy execution engine and lifecycle manager.

95

96

Methods:

97

- init(): Initialize strategy

98

- before_trading(): Pre-market phase

99

- open_auction(): Opening auction phase

100

- handle_bar(bar_dict): Process bar data

101

- handle_tick(tick): Process tick data

102

- after_trading(): Post-market phase

103

- teardown(): Strategy cleanup

104

"""

105

106

class ExecutionContext:

107

"""

108

Execution context and phase enforcement.

109

110

Properties:

111

- phase (EXECUTION_PHASE): Current execution phase

112

- strategy_context (StrategyContext): Strategy context

113

-

114

Methods:

115

- set_phase(phase): Set current execution phase

116

- enforce_phase(allowed_phases): Enforce phase restrictions

117

"""

118

119

class Executor:

120

"""

121

Strategy executor and orchestrator.

122

123

Methods:

124

- run(): Execute complete strategy

125

- execute_phase(phase): Execute specific phase

126

- handle_exception(exception): Handle strategy exceptions

127

"""

128

```

129

130

### Strategy Loading

131

132

Strategy loading interfaces for different strategy sources.

133

134

```python { .api }

135

class FileStrategyLoader:

136

"""

137

Load strategy from Python file.

138

139

Methods:

140

- load(file_path): Load strategy from file path

141

- get_strategy_functions(): Extract strategy functions

142

"""

143

144

class SourceCodeStrategyLoader:

145

"""

146

Load strategy from source code string.

147

148

Methods:

149

- load(source_code): Load strategy from code string

150

- compile_strategy(): Compile strategy code

151

"""

152

153

class UserFuncStrategyLoader:

154

"""

155

Load strategy from user-defined functions.

156

157

Methods:

158

- load(user_funcs): Load from function dictionary

159

- validate_functions(): Validate function signatures

160

"""

161

```

162

163

### Run Information

164

165

Metadata and information about strategy execution.

166

167

```python { .api }

168

class RunInfo:

169

"""

170

Strategy run information and metadata.

171

172

Properties:

173

- start_date (date): Strategy start date

174

- end_date (date): Strategy end date

175

- frequency (str): Data frequency

176

- run_type (RUN_TYPE): Execution mode

177

- benchmark (str): Benchmark instrument

178

- matching_type (MATCHING_TYPE): Order matching type

179

- commission_multiplier (float): Commission multiplier

180

- margin_multiplier (float): Margin multiplier

181

- slippage (float): Slippage factor

182

- accounts (dict): Account configurations

183

"""

184

```

185

186

### Environment Singleton

187

188

Global environment singleton managing system state.

189

190

```python { .api }

191

class Environment:

192

"""

193

Global environment singleton for system state.

194

195

Properties:

196

- config (dict): System configuration

197

- data_proxy (DataProxy): Data access layer

198

- broker (AbstractBroker): Order execution broker

199

- portfolio (Portfolio): Portfolio manager

200

- event_bus (EventBus): Event system

201

- phase (EXECUTION_PHASE): Current execution phase

202

203

Methods:

204

- get_instance(): Get singleton instance

205

- set_instance(env): Set singleton instance

206

"""

207

```

208

209

## Framework Usage Examples

210

211

### Strategy Function Definition

212

213

```python

214

# Strategy functions with framework integration

215

def init(context):

216

"""Strategy initialization - called once at start."""

217

# Access context properties

218

logger.info(f"Strategy start date: {context.run_info.start_date}")

219

logger.info(f"Initial portfolio value: {context.portfolio.total_value}")

220

221

# Set up global variables

222

g.trade_count = 0

223

g.last_rebalance = None

224

225

# Configure universe

226

context.stocks = ["000001.XSHE", "000002.XSHE"]

227

update_universe(context.stocks)

228

229

def before_trading(context):

230

"""Pre-market phase - called daily before market open."""

231

logger.info(f"Before trading on {context.now.date()}")

232

233

# Daily preparation logic

234

g.daily_signals = calculate_signals(context)

235

236

# Check for rebalancing

237

if should_rebalance(context):

238

g.rebalance_today = True

239

else:

240

g.rebalance_today = False

241

242

def handle_bar(context, bar_dict):

243

"""Bar processing - called for each bar."""

244

# Access current market data

245

for stock_id, bar in bar_dict.items():

246

current_price = bar.close

247

248

# Strategy logic using global variables

249

if g.rebalance_today and stock_id in g.daily_signals:

250

signal = g.daily_signals[stock_id]

251

target_weight = signal * 0.1 # 10% max per stock

252

order_target_percent(stock_id, target_weight)

253

g.trade_count += 1

254

255

def after_trading(context):

256

"""Post-market phase - called daily after market close."""

257

logger.info(f"After trading on {context.now.date()}")

258

logger.info(f"Portfolio value: {context.portfolio.total_value:.2f}")

259

logger.info(f"Total trades today: {g.trade_count}")

260

261

# Reset daily variables

262

g.rebalance_today = False

263

```

264

265

### Event System Usage

266

267

```python

268

from rqalpha.apis import subscribe_event, EVENT

269

270

def init(context):

271

# Subscribe to various events

272

subscribe_event(EVENT.TRADE, on_trade)

273

subscribe_event(EVENT.ORDER_CREATION_PASS, on_order_created)

274

subscribe_event(EVENT.ORDER_CREATION_REJECT, on_order_rejected)

275

subscribe_event(EVENT.SETTLEMENT, on_settlement)

276

277

g.trade_history = []

278

g.order_history = []

279

280

def on_trade(context, trade):

281

"""Handle trade execution events."""

282

logger.info(f"Trade executed: {trade.instrument.symbol} "

283

f"{trade.last_quantity} @ {trade.last_price}")

284

285

# Store trade information

286

trade_info = {

287

"datetime": trade.datetime,

288

"instrument": trade.order_book_id,

289

"quantity": trade.last_quantity,

290

"price": trade.last_price,

291

"side": trade.side,

292

"commission": trade.commission

293

}

294

g.trade_history.append(trade_info)

295

296

def on_order_created(context, order):

297

"""Handle successful order creation."""

298

logger.info(f"Order created: {order.order_id} for {order.instrument.symbol}")

299

300

order_info = {

301

"order_id": order.order_id,

302

"instrument": order.order_book_id,

303

"quantity": order.quantity,

304

"price": order.price,

305

"status": order.status,

306

"created_at": order.created_at

307

}

308

g.order_history.append(order_info)

309

310

def on_order_rejected(context, order):

311

"""Handle order rejection."""

312

logger.warning(f"Order rejected: {order.order_id}")

313

# Implement rejection handling logic

314

315

def on_settlement(context, settlement_data):

316

"""Handle daily settlement."""

317

logger.info("Daily settlement completed")

318

# Daily cleanup or reporting logic

319

```

320

321

### Global Variables Management

322

323

```python

324

def init(context):

325

# Initialize global variables

326

g.indicators = {}

327

g.signals = {}

328

g.position_history = []

329

g.performance_metrics = {

330

"max_drawdown": 0.0,

331

"peak_value": 0.0,

332

"win_rate": 0.0,

333

"trades": []

334

}

335

336

def handle_bar(context, bar_dict):

337

# Update indicators using global variables

338

for stock_id in context.universe:

339

if stock_id not in g.indicators:

340

g.indicators[stock_id] = {

341

"sma_20": [],

342

"sma_60": [],

343

"rsi": []

344

}

345

346

# Calculate indicators

347

price_history = history_bars(stock_id, 60, "1d", fields="close")

348

sma_20 = price_history["close"][-20:].mean()

349

sma_60 = price_history["close"][-60:].mean()

350

351

# Store in global variables

352

g.indicators[stock_id]["sma_20"].append(sma_20)

353

g.indicators[stock_id]["sma_60"].append(sma_60)

354

355

# Keep only recent values

356

if len(g.indicators[stock_id]["sma_20"]) > 252:

357

g.indicators[stock_id]["sma_20"] = g.indicators[stock_id]["sma_20"][-252:]

358

g.indicators[stock_id]["sma_60"] = g.indicators[stock_id]["sma_60"][-252:]

359

360

# Generate signals

361

if sma_20 > sma_60:

362

g.signals[stock_id] = 1 # Buy signal

363

else:

364

g.signals[stock_id] = -1 # Sell signal

365

366

def after_trading(context):

367

# Update performance metrics in global variables

368

current_value = context.portfolio.total_value

369

370

if current_value > g.performance_metrics["peak_value"]:

371

g.performance_metrics["peak_value"] = current_value

372

373

drawdown = (g.performance_metrics["peak_value"] - current_value) / g.performance_metrics["peak_value"]

374

if drawdown > g.performance_metrics["max_drawdown"]:

375

g.performance_metrics["max_drawdown"] = drawdown

376

377

# Store daily position snapshot

378

position_snapshot = {

379

"date": context.now.date(),

380

"total_value": current_value,

381

"cash": context.portfolio.cash,

382

"positions": {pos.order_book_id: pos.quantity for pos in get_positions()}

383

}

384

g.position_history.append(position_snapshot)

385

```

386

387

### Context Properties Access

388

389

```python

390

def handle_bar(context, bar_dict):

391

# Portfolio information

392

logger.info(f"Portfolio total value: {context.portfolio.total_value}")

393

logger.info(f"Available cash: {context.portfolio.cash}")

394

logger.info(f"Market value: {context.portfolio.market_value}")

395

396

# Account-specific information

397

stock_cash = context.stock_account.cash

398

stock_value = context.stock_account.total_value

399

future_cash = context.future_account.cash

400

401

logger.info(f"Stock account - Cash: {stock_cash}, Value: {stock_value}")

402

logger.info(f"Future account cash: {future_cash}")

403

404

# Current time and universe

405

logger.info(f"Current time: {context.now}")

406

logger.info(f"Universe size: {len(context.universe)}")

407

408

# Run information

409

logger.info(f"Frequency: {context.run_info.frequency}")

410

logger.info(f"Benchmark: {context.run_info.benchmark}")

411

412

# Configuration access

413

start_date = context.config["base"]["start_date"]

414

accounts = context.config["base"]["accounts"]

415

logger.info(f"Strategy period: {start_date} to {context.run_info.end_date}")

416

```

417

418

### Custom Helper Functions

419

420

```python

421

def init(context):

422

# Define helper functions in global scope

423

g.calculate_rsi = create_rsi_calculator()

424

g.calculate_bollinger = create_bollinger_calculator()

425

g.risk_manager = RiskManager(context.portfolio.total_value)

426

427

def create_rsi_calculator():

428

"""Create RSI calculation function."""

429

def calculate_rsi(prices, period=14):

430

deltas = np.diff(prices)

431

seed = deltas[:period+1]

432

up = seed[seed >= 0].sum() / period

433

down = -seed[seed < 0].sum() / period

434

rs = up / down

435

rsi = np.zeros_like(prices)

436

rsi[:period] = 100. - 100. / (1. + rs)

437

438

for i in range(period, len(prices)):

439

delta = deltas[i-1]

440

if delta > 0:

441

upval = delta

442

downval = 0.

443

else:

444

upval = 0.

445

downval = -delta

446

447

up = (up * (period - 1) + upval) / period

448

down = (down * (period - 1) + downval) / period

449

rs = up / down

450

rsi[i] = 100. - 100. / (1. + rs)

451

452

return rsi

453

return calculate_rsi

454

455

class RiskManager:

456

"""Custom risk management class."""

457

def __init__(self, initial_capital):

458

self.initial_capital = initial_capital

459

self.max_position_size = 0.1 # 10% max per position

460

self.max_drawdown = 0.2 # 20% max drawdown

461

462

def check_position_size(self, portfolio_value, position_value):

463

"""Check if position size exceeds limits."""

464

position_weight = position_value / portfolio_value

465

return position_weight <= self.max_position_size

466

467

def check_drawdown(self, current_value, peak_value):

468

"""Check if drawdown exceeds limits."""

469

drawdown = (peak_value - current_value) / peak_value

470

return drawdown <= self.max_drawdown

471

472

def handle_bar(context, bar_dict):

473

# Use custom helper functions

474

for stock_id in context.universe:

475

price_history = history_bars(stock_id, 30, "1d", fields="close")

476

rsi = g.calculate_rsi(price_history["close"])[-1]

477

478

# Risk management check

479

portfolio_value = context.portfolio.total_value

480

if stock_id in context.portfolio.positions:

481

position_value = context.portfolio.positions[stock_id].market_value

482

if not g.risk_manager.check_position_size(portfolio_value, position_value):

483

logger.warning(f"Position size limit exceeded for {stock_id}")

484

continue

485

486

# Trading logic with RSI

487

if rsi < 30: # Oversold

488

order_target_percent(stock_id, 0.05) # 5% allocation

489

elif rsi > 70: # Overbought

490

order_target_percent(stock_id, 0) # Close position

491

```