Skip to content

Commit 5fa7a2d

Browse files
committed
task1
1 parent ccfef70 commit 5fa7a2d

File tree

6 files changed

+809
-5
lines changed

6 files changed

+809
-5
lines changed
Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,153 +1,186 @@
11
# Implementation Plan
22

3-
- [ ] 1. Set up core infrastructure and state management
3+
- [x] 1. Set up core infrastructure and state management
4+
45
- Create state management system for tracking spread creation sessions
56
- Implement session storage with automatic cleanup
67
- Add basic command handler structure for `/addspread`
78
- _Requirements: 1.1, 1.2_
89

9-
- [ ] 1.1 Create spread state management module
10+
- [x] 1.1 Create spread state management module
11+
1012
- Write tests for SpreadCreationState class and state management functions
1113
- Write `bot/spread_state.py` with SpreadCreationState class
1214
- Implement in-memory state storage with user_id as key
1315
- Add state persistence methods: save_state, get_state, clear_state, update_state
1416
- _Requirements: 1.1, 1.2_
1517

16-
- [ ] 1.2 Create basic command handler for addspread
18+
- [x] 1.2 Create basic command handler for addspread
19+
1720
- Write tests for command parsing and initial validation logic
1821
- Add `/addspread` command to ROUTINES in `bot/commands.py`
1922
- Create `bot/spread_creator.py` with handle_addspread_command function
2023
- Implement ticker parsing and validation from command arguments
2124
- _Requirements: 1.1, 1.4_
2225

2326
- [ ] 2. Implement ticker validation and API integration
27+
2428
- Create API integration module for ticker validation
2529
- Add price fetching functionality using existing Tinkoff integration
2630
- Implement duplicate spread detection
2731
- _Requirements: 1.2, 1.3, 7.5_
2832

2933
- [ ] 2.1 Create API integration module for spread creation
34+
3035
- Write tests for ticker validation and price fetching functions
3136
- Write `bot/spread_api.py` with ticker validation functions
3237
- Implement validate_ticker function using existing ticker endpoint
3338
- Add get_current_prices function using existing price fetching logic
3439
- _Requirements: 1.2, 1.3_
3540

3641
- [ ] 2.2 Add spread creation API endpoint integration
42+
3743
- Write tests for spread creation and duplicate detection functions
3844
- Implement create_spread function to POST to Django spreads endpoint
3945
- Add check_duplicate_spread function to detect existing spreads
4046
- Handle API errors and connection issues gracefully
4147
- _Requirements: 6.1, 6.2, 7.4_
4248

4349
- [ ] 3. Implement market-neutral price calculation logic
50+
4451
- Create price calculator module with ratio calculation
4552
- Implement spread price calculations for different asset type combinations
4653
- Add market-neutral explanation generation
4754
- _Requirements: 2.1, 2.2, 2.3_
4855

4956
- [ ] 3.1 Create spread pricing calculation module
57+
5058
- Write tests for spread price calculations and ratio calculations for different asset combinations
5159
- Write `bot/spread_pricing.py` with calculate_spread_price function
5260
- Implement calculate_ratio function for stock-future and future-future pairs
5361
- Add get_market_neutral_explanation function for user display
5462
- _Requirements: 2.1, 2.2, 2.3_
5563

5664
- [ ] 3.2 Integrate price calculations with existing Tinkoff API
65+
5766
- Write tests for price integration and error handling scenarios
5867
- Use existing get_current_prices_by_uid function for market data
5968
- Implement bid/ask price fetching for spread calculations
6069
- Add price unavailable handling and fallback logic
6170
- _Requirements: 2.5, 2.6_
6271

6372
- [ ] 4. Create interactive menu system with inline keyboards
73+
6474
- Implement inline keyboard generators for each step
6575
- Create callback query handlers for menu interactions
6676
- Add menu navigation and state transitions
6777
- _Requirements: 2.4, 3.1, 4.1, 5.1_
6878

6979
- [ ] 4.1 Create inline keyboard menu generators
80+
81+
- Write tests for menu generation functions and keyboard layouts
7082
- Write `bot/spread_menu.py` with menu generation functions
7183
- Implement generate_direction_menu for buy/sell selection
7284
- Add generate_price_menu and generate_amount_menu functions
7385
- Create generate_confirmation_menu for final review
7486
- _Requirements: 2.4, 3.1, 4.1, 5.1_
7587

7688
- [ ] 4.2 Implement callback query handlers
89+
90+
- Write tests for callback handling and state transitions
7791
- Add callback query handler to `bot/spread_creator.py`
7892
- Implement state transitions based on user selections
7993
- Add input validation for custom price and amount entries
8094
- Handle menu navigation (back, cancel) functionality
8195
- _Requirements: 3.2, 3.4, 4.2, 4.4, 5.4_
8296

8397
- [ ] 5. Add comprehensive input validation and error handling
98+
8499
- Implement validation for all user inputs (price, amount, tickers)
85100
- Add error message generation and user feedback
86101
- Create session timeout and cleanup mechanisms
87102
- _Requirements: 3.4, 4.4, 7.1, 7.3_
88103

89104
- [ ] 5.1 Implement input validation functions
105+
106+
- Write tests for all validation functions with edge cases and error scenarios
90107
- Add price validation (valid integer, reasonable range)
91108
- Implement amount validation (positive integer, minimum lot requirements)
92109
- Create ticker format validation and existence checking
93110
- _Requirements: 3.2, 3.4, 4.2, 4.4_
94111

95112
- [ ] 5.2 Add comprehensive error handling and user feedback
113+
114+
- Write tests for error handling scenarios and message generation
96115
- Implement error message generation for all validation failures
97116
- Add graceful handling of API connection errors
98117
- Create user-friendly error messages with suggested corrections
99118
- _Requirements: 7.1, 7.3, 7.4_
100119

101120
- [ ] 6. Integrate spread creation with Django backend
121+
102122
- Connect menu system to Django API for spread persistence
103123
- Implement SpreadStats creation and association
104124
- Add success confirmation and spread activation
105125
- _Requirements: 5.5, 6.1, 6.2, 6.3_
106126

107127
- [ ] 6.1 Implement Django API integration for spread creation
128+
129+
- Write tests for spread creation payload generation and API integration
108130
- Create spread creation payload from menu state
109131
- POST spread data to Django spreads endpoint
110132
- Handle SpreadStats creation automatically in Django
111133
- _Requirements: 5.5, 6.1, 6.2_
112134

113135
- [ ] 6.2 Add spread activation and confirmation
136+
137+
- Write tests for spread activation and confirmation flow
114138
- Set active=True by default for new spreads
115139
- Return spread ID and confirmation to user
116140
- Clear session state after successful creation
117141
- _Requirements: 6.3, 6.4, 5.6_
118142

119143
- [ ] 7. Add logging, monitoring and session cleanup
144+
120145
- Implement comprehensive logging for all operations
121146
- Add session timeout and automatic cleanup
122147
- Create monitoring for spread creation activity
123148
- _Requirements: 7.1, 7.2, 7.3_
124149

125150
- [ ] 7.1 Add comprehensive logging system
151+
152+
- Write tests for logging functionality and log message formats
126153
- Log all spread creation attempts with user and parameters
127154
- Add error logging with full context for troubleshooting
128155
- Implement success logging with spread details
129156
- _Requirements: 7.1, 7.2, 7.3_
130157

131-
- [ ]* 7.2 Create session cleanup and monitoring
158+
- [ ] 7.2 Create session cleanup and monitoring
159+
160+
- Write tests for session timeout and cleanup functionality
132161
- Implement automatic session timeout (30 minutes)
133162
- Add periodic cleanup of stale sessions
134163
- Create monitoring dashboard for spread creation metrics
135164
- _Requirements: 7.1, 7.3_
136165

137166
- [ ] 8. Integration testing and final wiring
167+
138168
- Connect all modules and test complete user flow
139169
- Add the addspread command to bot command routing
140170
- Verify integration with existing spreads trading functionality
141171
- _Requirements: 6.5_
142172

143173
- [ ] 8.1 Wire up complete spread creation flow
174+
175+
- Write integration tests for complete user journey from command to spread creation
144176
- Register addspread command handler in bot dispatcher
145177
- Connect all modules: state management, API integration, menus, pricing
146178
- Test complete user journey from command to spread creation
147179
- _Requirements: 6.5_
148180

149181
- [ ] 8.2 Verify integration with existing spread trading system
182+
- Write integration tests for spread trading system compatibility
150183
- Ensure newly created spreads appear in spreads command
151184
- Test that created spreads are properly formatted for trading logic
152185
- Verify SpreadStats integration works with existing patch operations
153-
- _Requirements: 6.4, 6.5_
186+
- _Requirements: 6.4, 6.5_

bot/commands.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from sellbuy import sellbuy
1313
from spreads import spreads
1414
from stop_orders import restore_stops, save_stops
15+
from spread_creator import handle_addspread_command
1516

1617
RUNNING_TASKS = {}
1718

@@ -52,6 +53,7 @@ async def tasks(*args, **kwargs):
5253
'restore': ('Restoring stop orders', restore_stops),
5354
'sellbuy': ('SellBuy', sellbuy),
5455
'spreads': ('Spreads monitoring and trading', spreads),
56+
'addspread': ('Add new spread', handle_addspread_command),
5557
'help': ('Help', help),
5658
'stop': ('Stopping tasks', stop_running_tasks),
5759
'cancel': ('Cancel', cancel_all_orders),

bot/spread_creator.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
"""
2+
Spread creator module for handling /addspread command.
3+
4+
This module provides the main command handler for initiating spread creation
5+
through the Telegram bot interface.
6+
"""
7+
8+
from typing import Optional, Tuple
9+
from aiogram import types
10+
from spread_state import SpreadCreationState, save_state, get_state
11+
12+
13+
def parse_addspread_command(args: str) -> Optional[Tuple[str, str]]:
14+
"""
15+
Parse the addspread command arguments.
16+
17+
Args:
18+
args: Command arguments string
19+
20+
Returns:
21+
Tuple of (far_leg_ticker, near_leg_ticker) or None if invalid
22+
"""
23+
if not args or not args.strip():
24+
return None
25+
26+
# Split and clean up arguments
27+
tickers = args.strip().split()
28+
29+
# Must have exactly 2 tickers
30+
if len(tickers) != 2:
31+
return None
32+
33+
far_leg, near_leg = tickers[0].upper(), tickers[1].upper()
34+
return (far_leg, near_leg)
35+
36+
37+
def validate_command_format(
38+
far_leg: Optional[str], near_leg: Optional[str]
39+
) -> bool:
40+
"""
41+
Validate the command format and ticker values.
42+
43+
Args:
44+
far_leg: Far leg ticker symbol
45+
near_leg: Near leg ticker symbol
46+
47+
Returns:
48+
True if valid, False otherwise
49+
"""
50+
# Check for None or empty values
51+
if not far_leg or not near_leg:
52+
return False
53+
54+
# Check for empty strings after stripping
55+
if not far_leg.strip() or not near_leg.strip():
56+
return False
57+
58+
# Check that tickers are different (case insensitive)
59+
if far_leg.upper() == near_leg.upper():
60+
return False
61+
62+
return True
63+
64+
65+
async def handle_addspread_command(message: types.Message) -> None:
66+
"""
67+
Handle the /addspread command.
68+
69+
Parses the command arguments, validates the format, and initiates
70+
the spread creation process by saving initial state.
71+
72+
Args:
73+
message: Telegram message containing the command
74+
"""
75+
user_id = message.from_user.id
76+
args = message.get_args()
77+
78+
# Parse command arguments
79+
parsed_tickers = parse_addspread_command(args)
80+
81+
if not parsed_tickers:
82+
await message.answer(
83+
"Usage: /addspread <far_leg_ticker> <near_leg_ticker>\n"
84+
"Example: /addspread GAZP GZZ4"
85+
)
86+
return
87+
88+
far_leg_ticker, near_leg_ticker = parsed_tickers
89+
90+
# Validate ticker format
91+
if not validate_command_format(far_leg_ticker, near_leg_ticker):
92+
await message.answer(
93+
"Usage: /addspread <far_leg_ticker> <near_leg_ticker>\n"
94+
"Example: /addspread GAZP GZZ4\n"
95+
"Note: Tickers must be different"
96+
)
97+
return
98+
99+
# Check if user already has an active session
100+
existing_state = get_state(user_id)
101+
if existing_state:
102+
# Replace existing session with new one
103+
pass # Will be overwritten below
104+
105+
# Create initial state
106+
initial_state = SpreadCreationState(
107+
user_id=user_id,
108+
far_leg_ticker=far_leg_ticker,
109+
near_leg_ticker=near_leg_ticker,
110+
current_step='ticker_validation'
111+
)
112+
113+
# Save state
114+
save_state(user_id, initial_state.to_dict())
115+
116+
# Send confirmation message
117+
await message.answer(
118+
f"Starting spread creation process:\n"
119+
f"Far leg: {far_leg_ticker}\n"
120+
f"Near leg: {near_leg_ticker}\n\n"
121+
f"Validating tickers..."
122+
)

0 commit comments

Comments
 (0)