wiz-trader 0.34.0__tar.gz → 0.36.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wiz_trader
3
- Version: 0.34.0
3
+ Version: 0.36.0
4
4
  Summary: A Python SDK for connecting to the Wizzer.
5
5
  Home-page: https://bitbucket.org/wizzer-tech/quotes_sdk.git
6
6
  Author: Pawan Wagh
@@ -38,6 +38,7 @@ Dynamic: requires-python
38
38
  - [Callbacks](#callbacks)
39
39
  - [Subscribing to Instruments](#subscribing-to-instruments)
40
40
  - [Unsubscribing from Instruments](#unsubscribing-from-instruments)
41
+ - [Account Events](#account-events)
41
42
  - [Handling WebSocket Connection](#handling-websocket-connection)
42
43
  - [Complete Examples](#quotes-client-examples)
43
44
  5. [Wizzer Client](#wizzer-client)
@@ -253,6 +254,347 @@ ws.unsubscribe(["NSE:RELIANCE:2885"])
253
254
  - Can be called multiple times for different instrument sets
254
255
  - No callback fired for unsubscribed instruments
255
256
 
257
+ ### Account Events
258
+
259
+ The QuotesClient now supports automatic reception of account-related events (orders, trades, positions, holdings) from the quotes server. These events are automatically pushed to SDK users via dedicated callback handlers based on the event type.
260
+
261
+ #### Event Handlers
262
+
263
+ Register event handlers to receive real-time updates for your account activity:
264
+
265
+ ```python
266
+ def on_order(ws, order):
267
+ print(f"Order event: {order}")
268
+
269
+ def on_trade(ws, trade):
270
+ print(f"Trade event: {trade}")
271
+
272
+ def on_position(ws, position):
273
+ print(f"Position event: {position}")
274
+
275
+ def on_holding(ws, holding):
276
+ print(f"Holding event: {holding}")
277
+
278
+ # Register event handlers
279
+ client.on_order = on_order
280
+ client.on_trade = on_trade
281
+ client.on_position = on_position
282
+ client.on_holding = on_holding
283
+ ```
284
+
285
+ #### Key Features
286
+
287
+ - **Automatic Event Reception**: No explicit subscription needed - events are automatically sent based on your JWT token's account ID and strategy ID
288
+ - **Optional Handlers**: Events are silently dropped if no handler is registered - you only receive what you need
289
+ - **Message Normalization**: The SDK automatically handles different message formats and delivers clean, flattened event data to your handlers
290
+ - **Error Resilience**: Handler exceptions are caught and logged without breaking the event flow
291
+ - **Backward Compatible**: Existing tick and Greeks functionality remains unchanged
292
+
293
+ #### Event Data Structure
294
+
295
+ All event handlers receive flattened event data with the event type preserved:
296
+
297
+ ```python
298
+ # Example order event data
299
+ {
300
+ "_id": "order_01k10np7weemkv812nx55bppw5",
301
+ "accountEntityType": "client",
302
+ "accountId": "user_01j9brznsffphvzqn9gzyj1frw",
303
+ "avgPrice": 72.65,
304
+ "broker": "wizzer",
305
+ "brokerOrderId": "dssorder_175344314711184",
306
+ "brokerTimestamp": "2025-07-25T11:32:28.147Z",
307
+ "cancelledQty": 0,
308
+ "completedAt": "2025-07-25T11:32:28.147Z",
309
+ "createdAt": "2025-07-25T11:32:27.722Z",
310
+ "disclosedQty": 0,
311
+ "exchange": "NSE",
312
+ "exchangeOrderId": "dssx_1753443147",
313
+ "exchangeToken": 11184,
314
+ "exchangeUpdateTimestamp": "2025-07-25T11:32:28.147Z",
315
+ "executionType": "regular",
316
+ "filledQty": 1,
317
+ "guid": "t0lVueivgBgcEh2k_BP",
318
+ "instrumentType": "EQLC",
319
+ "isDealer": false,
320
+ "isOrderModified": false,
321
+ "legs": [],
322
+ "marginUsed": 0,
323
+ "meta": {
324
+ "dss": {"orderId": "order_01k10np7weemkv812nx55bppw5"},
325
+ "source": "wizzer.dss",
326
+ "wizzer": {"mode": "paper_trading"}
327
+ },
328
+ "orderType": "MARKET",
329
+ "parentOrderId": "",
330
+ "pendingQty": 1,
331
+ "placedBy": "user_01j9brznsffphvzqn9gzyj1frw",
332
+ "price": 0,
333
+ "product": "CNC",
334
+ "qty": 1,
335
+ "remarks": "",
336
+ "segment": "NSECM",
337
+ "slPrice": 0,
338
+ "slTriggerPrice": 0,
339
+ "sqOffHoldingId": "",
340
+ "sqOffPositionId": "",
341
+ "status": "COMPLETED",
342
+ "stoploss": 0,
343
+ "stoplossOrderId": "",
344
+ "strategy": {
345
+ "id": "stgy_01jtn7t3erf8ss78spqy40k8en",
346
+ "identifier": "S-608377",
347
+ "name": "Test 1122"
348
+ },
349
+ "target": 0,
350
+ "targetOrderId": "",
351
+ "tradingSymbol": "IDFCFIRSTB",
352
+ "transactionType": "BUY",
353
+ "triggerId": "",
354
+ "triggerPrice": 0,
355
+ "updatedAt": "2025-07-25T11:32:28.254Z",
356
+ "userId": "user_01j9brznsffphvzqn9gzyj1frw",
357
+ "validity": "DAY",
358
+ "variety": "REGULAR"
359
+ }
360
+
361
+ # Example trade event data
362
+ {
363
+ "_id": "trade_01k10np8rqef793zr93ctqj0wt",
364
+ "accountId": "user_01j9brznsffphvzqn9gzyj1frw",
365
+ "avgPrice": 72.65,
366
+ "broker": "wizzer",
367
+ "brokerOrderId": "dssorder_175344314711184",
368
+ "createdAt": "2025-07-25T11:32:28.567Z",
369
+ "exchange": "NSE",
370
+ "exchangeOrderId": "dssx_1753443147",
371
+ "exchangeTimestamp": "2025-07-25T11:32:28.147Z",
372
+ "exchangeToken": 11184,
373
+ "isDividend": false,
374
+ "meta": {
375
+ "dss": {"orderId": "order_01k10np7weemkv812nx55bppw5"},
376
+ "source": "wizzer.dss",
377
+ "wizzer": {"mode": "paper_trading"}
378
+ },
379
+ "orderId": "order_01k10np7weemkv812nx55bppw5",
380
+ "orderType": "MARKET",
381
+ "parentOrderId": "",
382
+ "parentTradeId": "",
383
+ "product": "CNC",
384
+ "qty": 1,
385
+ "segment": "NSECM",
386
+ "strategy": {
387
+ "id": "stgy_01jtn7t3erf8ss78spqy40k8en",
388
+ "identifier": "S-608377",
389
+ "name": "Test 1122"
390
+ },
391
+ "tradeId": "dsstrade_50PccSfWvsCg-Cr5dQE",
392
+ "tradingSymbol": "IDFCFIRSTB",
393
+ "transactionType": "BUY",
394
+ "updatedAt": "2025-07-25T11:32:28.567Z",
395
+ "userId": "user_01j9brznsffphvzqn9gzyj1frw"
396
+ }
397
+
398
+ # Example position event data
399
+ {
400
+ "_id": "pos_01k10np8t7e0fs63q52hacbx8m",
401
+ "accountEntityType": "client",
402
+ "accountId": "user_01j9brznsffphvzqn9gzyj1frw",
403
+ "bep": 0,
404
+ "broker": "wizzer",
405
+ "buyAvgPrice": 72.65,
406
+ "buyOrders": ["order_01k10np7weemkv812nx55bppw5"],
407
+ "buyQty": 1,
408
+ "buyTrades": ["trade_01k10np8rqef793zr93ctqj0wt"],
409
+ "buyValue": 72.65,
410
+ "closePrice": 0,
411
+ "createdAt": "2025-07-25T11:32:28.614Z",
412
+ "exchange": "NSE",
413
+ "exchangeToken": 11184,
414
+ "instrumentType": "EQLC",
415
+ "lotSize": 1,
416
+ "meta": {
417
+ "source": "wizzer.dss",
418
+ "wizzer": {"mode": "paper_trading"}
419
+ },
420
+ "netQty": 1,
421
+ "pnlPercentage": 0,
422
+ "product": "CNC",
423
+ "realisedPnlToday": 0,
424
+ "segment": "NSECM",
425
+ "sellAvgPrice": 0,
426
+ "sellOrders": [],
427
+ "sellQty": 0,
428
+ "sellTrades": [],
429
+ "sellValue": 0,
430
+ "slPrice": null,
431
+ "slTriggerPrice": null,
432
+ "status": "open",
433
+ "stoploss": 0,
434
+ "strategy": {
435
+ "id": "stgy_01jtn7t3erf8ss78spqy40k8en",
436
+ "identifier": "S-608377",
437
+ "name": "Test 1122"
438
+ },
439
+ "target": 0,
440
+ "tradingSymbol": "IDFCFIRSTB",
441
+ "unrealisedPnlToday": 0,
442
+ "updatedAt": "2025-07-25T11:32:28.614Z",
443
+ "userId": "user_01j9brznsffphvzqn9gzyj1frw"
444
+ }
445
+
446
+ # Example holding event data
447
+ {
448
+ "_id": "holding_01k10np8t7e0fs63q52hacbx8m",
449
+ "accountEntityType": "client",
450
+ "accountId": "user_01j9brznsffphvzqn9gzyj1frw",
451
+ "bep": 0,
452
+ "broker": "wizzer",
453
+ "buyAvgPrice": 72.65,
454
+ "buyOrders": ["order_01k10np7weemkv812nx55bppw5"],
455
+ "buyQty": 1,
456
+ "buyTrades": ["trade_01k10np8rqef793zr93ctqj0wt"],
457
+ "buyValue": 72.65,
458
+ "closePrice": 0,
459
+ "createdAt": "2025-07-25T11:32:28.614Z",
460
+ "exchange": "NSE",
461
+ "exchangeToken": 11184,
462
+ "instrumentType": "EQLC",
463
+ "lotSize": 1,
464
+ "meta": {
465
+ "source": "wizzer.dss",
466
+ "wizzer": {"mode": "paper_trading"}
467
+ },
468
+ "netQty": 1,
469
+ "pnlPercentage": 0,
470
+ "product": "CNC",
471
+ "realisedPnlToday": 0,
472
+ "segment": "NSECM",
473
+ "sellAvgPrice": 0,
474
+ "sellOrders": [],
475
+ "sellQty": 0,
476
+ "sellTrades": [],
477
+ "sellValue": 0,
478
+ "slPrice": null,
479
+ "slTriggerPrice": null,
480
+ "status": "open",
481
+ "stoploss": 0,
482
+ "strategy": {
483
+ "id": "stgy_01jtn7t3erf8ss78spqy40k8en",
484
+ "identifier": "S-608377",
485
+ "name": "Test 1122"
486
+ },
487
+ "target": 0,
488
+ "tradingSymbol": "IDFCFIRSTB",
489
+ "unrealisedPnlToday": 0,
490
+ "updatedAt": "2025-07-25T11:32:28.614Z",
491
+ "userId": "user_01j9brznsffphvzqn9gzyj1frw"
492
+ }
493
+ ```
494
+
495
+ #### Complete Event Handling Example
496
+
497
+ ```python
498
+ from wiz_trader import QuotesClient
499
+
500
+ # Initialize client
501
+ client = QuotesClient(
502
+ base_url="wss://websocket-url/quotes",
503
+ token="your-jwt-token",
504
+ log_level="info"
505
+ )
506
+
507
+ def on_order(ws, order):
508
+ # React to order status changes
509
+ if order['status'] == ORDER_STATUS_COMPLETED:
510
+ print(f"Order {order['_id']} completed!")
511
+ elif order['status'] == ORDER_STATUS_REJECTED:
512
+ print(f"Order {order['_id']} rejected: {order.get('remarks', 'Unknown')}")
513
+
514
+ def on_trade(ws, trade):
515
+ print(f"Trade executed: {trade['qty']} x {trade['tradingSymbol']} @ {trade['avgPrice']}")
516
+
517
+ def on_position(ws, position):
518
+ print(f"Position update: {position['tradingSymbol']} = {position['netQty']} (PnL: {position.get('unrealisedPnlToday', 0)})")
519
+
520
+ def on_holding(ws, holding):
521
+ print(f"Holding update: {holding['tradingSymbol']} = {holding['netQty']}")
522
+
523
+ def on_connect(ws):
524
+ print("Connected! Ready to receive events.")
525
+ # Also subscribe to some ticks if needed
526
+ ws.subscribe(["NSE:SBIN:3045"], mode="ticks")
527
+
528
+ # Register all handlers
529
+ client.on_order = on_order
530
+ client.on_trade = on_trade
531
+ client.on_position = on_position
532
+ client.on_holding = on_holding
533
+ client.on_connect = on_connect
534
+
535
+ # Connect and receive events
536
+ client.connect()
537
+ ```
538
+
539
+ #### Event-Driven Trading Strategy Example
540
+
541
+ ```python
542
+ class EventDrivenStrategy:
543
+ def __init__(self):
544
+ self.orders = {}
545
+ self.positions = {}
546
+ self.pending_orders = set()
547
+
548
+ def on_order_event(self, ws, order):
549
+ order_id = order['_id']
550
+ self.orders[order_id] = order
551
+
552
+ # Track pending orders
553
+ if order['status'] == ORDER_STATUS_OPEN:
554
+ self.pending_orders.add(order_id)
555
+ elif order_id in self.pending_orders:
556
+ self.pending_orders.remove(order_id)
557
+
558
+ # Log order lifecycle
559
+ print(f"Order {order_id}: {order['status']}")
560
+
561
+ # React to rejections
562
+ if order['status'] == ORDER_STATUS_REJECTED:
563
+ print(f"Order rejected! Reason: {order.get('remarks', 'Unknown')}")
564
+ # Implement retry logic or alternative strategy
565
+
566
+ def on_position_event(self, ws, position):
567
+ symbol = position['tradingSymbol']
568
+ self.positions[symbol] = position
569
+
570
+ # Monitor position changes
571
+ print(f"Position {symbol}: Qty={position['netQty']}, PnL={position.get('unrealisedPnlToday', 0)}")
572
+
573
+ # Implement stop-loss or take-profit logic
574
+ pnl = position.get('unrealisedPnlToday', 0)
575
+ if pnl < -100: # Stop loss at -100
576
+ print(f"Stop loss triggered for {symbol}")
577
+ # Place exit order
578
+ elif pnl > 200: # Take profit at 200
579
+ print(f"Take profit triggered for {symbol}")
580
+ # Place exit order
581
+
582
+ def on_trade_event(self, ws, trade):
583
+ print(f"Trade executed: {trade['qty']} @ {trade['avgPrice']}")
584
+ # Update internal trade log, calculate VWAP, etc.
585
+
586
+ # Initialize strategy
587
+ strategy = EventDrivenStrategy()
588
+
589
+ # Set up client with strategy handlers
590
+ client = QuotesClient(base_url="wss://...", token="...")
591
+ client.on_order = strategy.on_order_event
592
+ client.on_position = strategy.on_position_event
593
+ client.on_trade = strategy.on_trade_event
594
+
595
+ client.connect()
596
+ ```
597
+
256
598
  ### Complete Examples
257
599
 
258
600
  #### Blocking Example
@@ -425,6 +767,7 @@ Available constants:
425
767
  - Transaction types: `TRANSACTION_TYPE_BUY`, `TRANSACTION_TYPE_SELL`
426
768
  - Product types: `PRODUCT_CNC`, `PRODUCT_MIS`, `PRODUCT_NRML`
427
769
  - Order types: `ORDER_TYPE_MARKET`, `ORDER_TYPE_LIMIT`, `ORDER_TYPE_SL`, `ORDER_TYPE_SLM`
770
+ - Order status: `ORDER_STATUS_OPEN`, `ORDER_STATUS_CANCELLED`, `ORDER_STATUS_REJECTED`, `ORDER_STATUS_PENDING`, `ORDER_STATUS_COMPLETED`
428
771
  - Validity types: `VALIDITY_DAY`, `VALIDITY_IOC`, `VALIDITY_GTT`
429
772
  - Variety types: `VARIETY_REGULAR`, `VARIETY_AMO`, `VARIETY_BO`, `VARIETY_CO`
430
773
  - Exchanges: `EXCHANGE_NSE`, `EXCHANGE_BSE`, `EXCHANGE_WZR`
@@ -3663,3 +4006,243 @@ results = client.run_screener(
3663
4006
  limit=10
3664
4007
  )
3665
4008
  ```
4009
+
4010
+ ## KV Store Integration
4011
+
4012
+ The WizzerClient includes comprehensive Key-Value (KV) store functionality for persistent data management. This feature allows you to store configuration data, state information, user preferences, and other persistent data associated with your trading strategies.
4013
+
4014
+ ### Supported Data Types
4015
+
4016
+ The KV store supports all JSON-serializable data types:
4017
+
4018
+ - **STRING**: Text values (`"production"`, `"user123"`)
4019
+ - **NUMBER**: Integer and float values (`42`, `150.25`)
4020
+ - **BOOLEAN**: True/false values (`True`, `False`)
4021
+ - **ARRAY**: Lists of values (`["AAPL", "GOOGL", "MSFT"]`)
4022
+ - **OBJECT**: Dictionaries/objects (`{"positions": 30, "cash": 50000}`)
4023
+
4024
+ ### Available Constants
4025
+
4026
+ ```python
4027
+ client.KV_TYPE_STRING # "string"
4028
+ client.KV_TYPE_NUMBER # "number"
4029
+ client.KV_TYPE_BOOLEAN # "boolean"
4030
+ client.KV_TYPE_ARRAY # "array"
4031
+ client.KV_TYPE_OBJECT # "object"
4032
+ ```
4033
+
4034
+ ### Core CRUD Operations
4035
+
4036
+ #### Create Key-Value Pair
4037
+
4038
+ ```python
4039
+ # Store different data types
4040
+ client.create_kv("environment", "production")
4041
+ client.create_kv("trade_count", 42)
4042
+ client.create_kv("is_active", True)
4043
+ client.create_kv("symbols", ["AAPL", "GOOGL", "MSFT"])
4044
+
4045
+ # Store complex configuration with TTL (expires in 1 hour)
4046
+ config = {
4047
+ "risk_level": "medium",
4048
+ "max_positions": 10,
4049
+ "stop_loss_pct": 0.05,
4050
+ "take_profit_pct": 0.15
4051
+ }
4052
+ client.create_kv("strategy_config", config, ttl=3600)
4053
+ ```
4054
+
4055
+ #### Retrieve Key-Value Pair
4056
+
4057
+ ```python
4058
+ # Get a single KV pair
4059
+ data = client.get_kv("strategy_config")
4060
+ print(data["value"]) # The stored object
4061
+ print(data["type"]) # "object"
4062
+ print(data["ttl"]) # Remaining time to live (if set)
4063
+
4064
+ # Access nested values
4065
+ risk_level = data["value"]["risk_level"] # "medium"
4066
+ ```
4067
+
4068
+ #### Update Key-Value Pair (Complete Replacement)
4069
+
4070
+ ```python
4071
+ # Complete replacement of existing key
4072
+ new_config = {"risk_level": "high", "max_positions": 5}
4073
+ client.update_kv("strategy_config", new_config, ttl=1800)
4074
+ ```
4075
+
4076
+ #### Patch Key-Value Pair (Partial Update)
4077
+
4078
+ ```python
4079
+ # For objects - merges with existing data
4080
+ client.patch_kv("strategy_config", {"last_updated": "2024-01-15"})
4081
+
4082
+ # For non-objects - replaces entirely
4083
+ client.patch_kv("trade_count", 50)
4084
+
4085
+ # Update only TTL
4086
+ client.patch_kv("strategy_config", ttl=7200)
4087
+ ```
4088
+
4089
+ #### Delete Key-Value Pair
4090
+
4091
+ ```python
4092
+ response = client.delete_kv("old_config")
4093
+ if response["success"]:
4094
+ print("Key deleted successfully")
4095
+ ```
4096
+
4097
+ ### List Operations
4098
+
4099
+ #### Get All KV Pairs (with values)
4100
+
4101
+ ```python
4102
+ # Get first page (20 items)
4103
+ kvs = client.get_all_kvs(page_no=1)
4104
+
4105
+ # Get all pages automatically
4106
+ all_kvs = client.get_all_kvs(paginate=True)
4107
+
4108
+ for kv in all_kvs:
4109
+ print(f"Key: {kv['key']}")
4110
+ print(f"Type: {kv['type']}")
4111
+ print(f"Value: {kv['value']}")
4112
+ ```
4113
+
4114
+ #### Get Keys Only (memory efficient)
4115
+
4116
+ ```python
4117
+ # Get all keys without values (faster for large datasets)
4118
+ keys = client.get_kv_keys(paginate=True)
4119
+
4120
+ for key_info in keys:
4121
+ print(f"Key: {key_info['key']}, Type: {key_info['type']}")
4122
+ if 'ttl' in key_info:
4123
+ print(f" TTL: {key_info['ttl']} seconds remaining")
4124
+ ```
4125
+
4126
+ ### Advanced Usage Examples
4127
+
4128
+ #### Strategy Configuration Management
4129
+
4130
+ ```python
4131
+ # Store strategy parameters
4132
+ params = {
4133
+ "moving_average_period": 20,
4134
+ "rsi_oversold": 30,
4135
+ "rsi_overbought": 70,
4136
+ "position_size": 0.02
4137
+ }
4138
+ client.create_kv("strategy_params", params)
4139
+
4140
+ # Update specific parameters using patch (merges with existing)
4141
+ client.patch_kv("strategy_params", {"moving_average_period": 50})
4142
+ ```
4143
+
4144
+ #### State Persistence
4145
+
4146
+ ```python
4147
+ # Save current portfolio state
4148
+ portfolio_state = {
4149
+ "cash_balance": 50000,
4150
+ "open_positions": 5,
4151
+ "daily_pnl": 1250.75,
4152
+ "last_updated": "2024-01-15T15:30:00Z"
4153
+ }
4154
+ client.create_kv("portfolio_state", portfolio_state, ttl=3600)
4155
+
4156
+ # Update state periodically
4157
+ client.patch_kv("portfolio_state", {
4158
+ "daily_pnl": 1500.25,
4159
+ "last_updated": "2024-01-15T16:00:00Z"
4160
+ })
4161
+ ```
4162
+
4163
+ #### Feature Flags
4164
+
4165
+ ```python
4166
+ # Enable/disable features dynamically
4167
+ features = {
4168
+ "advanced_charts": True,
4169
+ "paper_trading": True,
4170
+ "options_trading": False,
4171
+ "algo_trading": True
4172
+ }
4173
+ client.create_kv("feature_flags", features)
4174
+
4175
+ # Toggle a feature
4176
+ client.patch_kv("feature_flags", {"options_trading": True})
4177
+ ```
4178
+
4179
+ #### Data Caching with TTL
4180
+
4181
+ ```python
4182
+ # Cache market data with short TTL (5 minutes)
4183
+ market_status = {
4184
+ "nse_open": True,
4185
+ "bse_open": True,
4186
+ "last_checked": "2024-01-15T09:15:00Z"
4187
+ }
4188
+ client.create_kv("market_status", market_status, ttl=300)
4189
+ ```
4190
+
4191
+ ### Object Merge Behavior
4192
+
4193
+ For OBJECT type data, the `patch_kv` method performs intelligent merging:
4194
+
4195
+ ```python
4196
+ # Initial object
4197
+ client.create_kv("user_prefs", {
4198
+ "theme": "dark",
4199
+ "notifications": True,
4200
+ "language": "en"
4201
+ })
4202
+
4203
+ # Patch merges new fields with existing ones
4204
+ client.patch_kv("user_prefs", {
4205
+ "notifications": False, # Updates existing field
4206
+ "timezone": "UTC" # Adds new field
4207
+ })
4208
+
4209
+ # Result: {"theme": "dark", "notifications": False, "language": "en", "timezone": "UTC"}
4210
+ ```
4211
+
4212
+ ### Delete All KV Pairs
4213
+
4214
+ The `delete_all_kv` method allows you to remove all key-value pairs for a strategy at once:
4215
+
4216
+ ```python
4217
+ # Delete all KV pairs for the current strategy
4218
+ response = client.delete_all_kv()
4219
+ print(f"Deleted {response['deleted']} key-value pairs")
4220
+
4221
+ # Example response:
4222
+ # {
4223
+ # "success": True,
4224
+ # "deleted": 15,
4225
+ # "message": "Successfully deleted 15 key-value pairs"
4226
+ # }
4227
+
4228
+ # Common usage - reset strategy state before reinitialization
4229
+ def reset_strategy_state():
4230
+ """Reset all persistent state for the strategy."""
4231
+ # Clear all existing KV pairs
4232
+ result = client.delete_all_kv()
4233
+ print(f"Cleared {result['deleted']} KV pairs")
4234
+
4235
+ # Reinitialize with default configuration
4236
+ client.create_kv("config", {
4237
+ "mode": "production",
4238
+ "risk_percentage": 0.02,
4239
+ "max_positions": 10
4240
+ })
4241
+ client.create_kv("state", {
4242
+ "initialized": True,
4243
+ "start_time": datetime.now().isoformat()
4244
+ })
4245
+ print("Strategy state reset successfully")
4246
+
4247
+ # Use with caution - this operation cannot be undone!
4248
+ ```