Project
Project
This project is a comprehensive Real-Time Trading Management System built using React and supporting
APIs. The system provides traders with the tools to monitor, manage, and execute trading strategies
dynamically. Its core functionalities revolve around fetching real-time stock market data, managing
strategies, executing trades, and providing an intuitive interface for decision-making. Here's an overview
of the key features and components:
Key Features:
Integrated APIs to fetch and display the latest stock market data for indices like BankNifty and Nifty.
Data updates every 3 seconds to ensure the most accurate and up-to-date information for trading
decisions.
Users can create and manage trading strategies, which include details such as stop-loss, re-entry
conditions, quantity, and more.
Strategies are fetched dynamically based on user IDs to ensure personalized strategy handling.
The application calculates and displays ATM Strike Prices and associated Straddle Prices.
Provides calculated values for optimal trade execution, such as OTM gaps and current percentages.
Trade Execution:
A highly interactive trade execution feature allows users to execute trades directly from the platform.
Includes validation mechanisms for confirming or modifying trade actions based on calculated values.
Supports customizable inputs like quantity, stop loss, and re-entry percentages for both Call Options
(CE) and Put Options (PE).
Interactive UI/UX:
A clean and intuitive interface with data tables, input fields, dropdowns, and buttons for seamless
navigation and user experience.
Includes a loading indicator to signal when background processes, such as data fetching or trade
execution, are ongoing.
Technical Stack:
Backend Communication: REST APIs for data fetching and trade execution.
1. Error Handling :
o very API call is wrapped in a try-catch block to catch potential errors during the
fetch operations.
o Example:
javascript
Copy code
try {
const response = await axios.get(GETCREATEDSTATEGY);
setStrategylist(response.data);
} catch (error) {
console.error(error);
}
Key Functionalities
Component States
Lifecycle Management
1. Initialization (useEffect):
o Starts a data-fetching interval that repeatedly calls mergedStategyData.
o Cleans up the interval on component unmount.
2. Fetching Data (mergedStategyData):
o Sends a POST request to fetch data for the logged-in user (userID from
localStorage).
o Maps the data to include last trade prices from a separate stock data array and
groups trades by orderUniqueIdentifier for display.
Core Functions
Sends POST requests for all trades in parallel using Promise.all to optimize
performance.
User Interface
1. Header:
o Displays the title "CURRENT POSITIONS."
o Provides a button to "Square Off All" trades, disabled while processing.
2. Table:
o Lists all trades with columns for:
Instrument (Trade Identifier or Re-entry details).
Order Side.
Mark-to-Market (MTM) profit/loss (totalLastTradePrice -
totalPriceAtOrderTime).
Buttons for:
Square Off (single trade).
View Trades (fetch trade details).
3. Popup:
o Displays confirmation dialogs or notifications.
o For confirmations (e.g., square off all trades), includes "Confirm" and "Cancel"
buttons.
4. Footer:
o Conditionally renders a footer using the Footer component.
Key Workflow
1. Data Fetching:
o Trades are fetched every 2 seconds.
o Each trade is grouped and processed for display.
2. Viewing a Trade:
o The user clicks "View Trades" for a specific trade.
o Trade details are fetched, and calculations like difference are displayed.
3. Squaring Off:
o Single trade: User clicks "Square Off" for a trade, triggering an API call.
o All trades: User clicks "Square Off All," confirms the action, and API calls are
made for all trades.
4. Notifications:
o Success or error messages are displayed in a popup.
Error Handling
Real-World Usage
This code is ideal for a trading platform, where users monitor live positions, view individual
trade details, and close positions interactively. The frequent updates ensure real-time accuracy,
while the interactive UI supports user actions effectively.
useEffect(() => {
onLoadingChange(isLoading);
}, [isLoading, onLoadingChange]);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
useEffect(() => {
fetchExpiryDates(); // Fetch expiry dates on component mount
}, [formData.index]); // Fetch expiry dates when the index changes
if ((name === "ceEntry" || name === "peEntry") && (value > 5 || value
< 0)) {
alert(`${name.toUpperCase()} should be between 0 and 5`);
return;
}
setForm(prevFormData => ({
...prevFormData,
[name]: value
}));
const jsonData = {
orderQuantity: parseInt(formData.orderQuantity, 10),
orderSide: formData.orderSide,
orderType: formData.orderType,
index: formData.index,
stopPrice: stopPrice,
otm: parseInt(formData.otm, 10),
ceEntry: formData.ceEntry,
peEntry: formData.peEntry,
disclosedQuantity: 0,
userId: localStorage.getItem("objectId"),
date: formData.date,
expiryDate: expiryDate, // Ensure expiryDate is being sent
indexExpiry: formData.index // Pass index as indexExpiry
};
return (
<div className="container">
<label>
QUANTITY
<input
type="number"
onChange={handleChange}
value={formData.orderQuantity}
name="orderQuantity"
/>
</label><br />
<label>
STOP LOSS
<input
type="number"
onChange={handleChange}
value={formData.stopPrice}
name="stopPrice"
/>
</label><br />
<label>
INDEX
<select
onChange={handleChange}
value={formData.index}
name="index"
>
<option value="BANKNIFTY">BANKNIFTY</option>
<option value="NIFTY">NIFTY</option>
</select>
</label><br />
<label>
ORDER SIDE
<select
onChange={handleChange}
value={formData.orderSide}
name="orderSide"
>
<option value="BUY">BUY</option>
<option value="SELL">SELL</option>
</select>
</label><br />
<label>
CE RE-ENTRY
<input
type="number"
onChange={handleChange}
value={formData.ceEntry}
name="ceEntry"
/>
</label><br />
<label>
PE RE-ENTRY
<input
type="number"
onChange={handleChange}
value={formData.peEntry}
name="peEntry"
/>
</label><br />
<label>
OTM
<input
type="number"
onChange={handleChange}
value={formData.otm}
name="otm"
/>
</label><br />
<label>
EXPIRY DATE
<select
onChange={(e) => {
const selectedDate = e.target.value;
setForm(prevFormData => ({ ...prevFormData, date:
selectedDate })); // Update form data with selected date
setExpiryDate(selectedDate); // Update expiry date
state
console.log("Selected Expiry Date:", selectedDate);
// Log the selected expiry date
}}
value={formData.date}
name="expirydate"
>
<option value="" disabled></option> {/* Placeholder
option */}
{availableExpiryDates.map((date, index) => (
<option key={index} value={date}>{date}</option>
))}
</select>
</label>
<br />
<button onClick={handleSubmit} disabled={isLoading}>
{isLoading ? 'LOADING...' : 'EXECUTE'}
</button>
</div>
);
};
Qn:Chart PLotting
This React component (NiftyLineChartComponent) is a comprehensive solution for rendering
two interactive line charts using the Chart.js library. The charts visualize Nifty Straddle Price
data, incorporating Bollinger Bands and SMA (Simple Moving Average), with a time period
filtering mechanism. Let’s break it down step by step:
Code Explanation
1. Dependencies
2. State Variables
3. Core Functions
1. calculateBollingerBands:
o Computes SMA, Upper Band, and Lower Band for a given set of prices.
o Purpose: To enhance the chart by visualizing volatility using Bollinger Bands.
2. fetchNiftyData:
o Fetches the Nifty Straddle Price data from the backend.
o Processes the data into:
Labels: Strike prices.
Values: Corresponding straddle prices.
o Stores full and time-filtered datasets in timePeriodData.
o Calculates Bollinger Bands and updates chartData.
3. fetchLastDateIndexPrice:
o Fetches the latest Nifty index price and updates lastDateIndexPrice.
4. Lifecycle Management
useEffect:
o Initial Data Fetch: On component mount, it triggers fetchNiftyData and
fetchLastDateIndexPrice.
o Auto-Refresh: Re-fetches data every 30 seconds using setInterval.
useEffect for selectedTab:
o Updates chartData based on the selected time period (e.g., '1 day', '30 min').
5. Chart Plotting
Data Structure:
o Chart.js expects datasets, each having:
label: Describes the dataset (e.g., "Straddle Price").
data: Y-axis values.
Styling: Colors, line tension, etc.
Options:
o Configures axes and plugins like zoom/pan.
Rendering:
o Two charts are rendered side-by-side, each with its own chartData and options.
Chart Workflow
1. Data Fetching:
o The component fetches Nifty Straddle Price data and computes necessary
transformations (e.g., Bollinger Bands).
o Time-filtered datasets ('30 min', '10 min', etc.) are created using slice.
2. Chart Data Preparation:
o A common structure is used for chartData:
Labels: X-axis (Strike prices).
Datasets: Y-axis data for Straddle Price, SMA, Upper Band, and Lower
Band.
3. Chart Rendering:
o The Line component from react-chartjs-2 is used to render the chart.
o Plugins (e.g., chartjs-plugin-zoom) enable interactivity like zooming and
panning.
4. Dynamic Updates:
o On time period selection, useEffect recalculates and updates chartData.
o Every 30 seconds, the data refreshes automatically.
Key Features
Chart Customization
Chart Appearance:
o Line colors and tensions define how the chart looks.
o Bollinger Bands are highlighted with distinct colors.
Interactivity:
o Zoom and pan provide a better exploration experience for users.
Decay Calculation:
o The component displays the percentage change in straddle price
(decayPercentage) relative to the last index price.
1. X-Axis (Labels):
o Strike prices (chartLabels) are set as the X-axis labels.
2. Y-Axis (Values):
o Four datasets:
Straddle Price
SMA
Upper Band
Lower Band
o Y-axis values are derived from fetched data or calculated metrics.
3. Time Period Selection:
o Dynamically filters data for specific intervals, updating both labels and values.
If you'd like further clarification on any specific part, feel free to ask!
4o
O
Chat
Code: import React, { useState, useEffect, useRef } from 'react';
const timePeriods = {
'1 day': 1, // Full data
'30 min': 30, // Last 30 minutes
'20 min': 20, // Last 20 minutes
'10 min': 10, // Last 10 minutes
'5 min': 5, // Last 5 minutes
};
sma.push(mean);
upperBand.push(mean + deviations * stdDeviation);
lowerBand.push(mean - deviations * stdDeviation);
} else {
sma.push(null);
upperBand.push(null);
lowerBand.push(null);
}
}
setTimePeriodData({
'1 day': { labels: chartLabels, values: chartValues },
'30 min': { labels: chartLabels.slice(-30), values:
chartValues.slice(-30) },
'20 min': { labels: chartLabels.slice(-20), values:
chartValues.slice(-20) },
'10 min': { labels: chartLabels.slice(-10), values:
chartValues.slice(-10) },
'5 min': { labels: chartLabels.slice(-5), values:
chartValues.slice(-5) },
});
const commonChartData = {
labels: chartLabels,
datasets: [
{
label: 'Straddle Price',
data: chartValues,
fill: false,
borderColor: 'rgb(75, 192, 192)',
tension: 0.1,
},
{
label: 'Upper Bollinger Band',
data: upperBand,
fill: false,
borderColor: 'rgb(255, 99, 132)',
tension: 0.1,
},
{
label: 'Lower Bollinger Band',
data: lowerBand,
fill: false,
borderColor: 'rgb(54, 162, 235)',
tension: 0.1,
},
{
label: 'SMA (20)',
data: sma,
fill: false,
borderColor: 'rgb(153, 102, 255)',
tension: 0.1,
},
],
};
setChartData(commonChartData);
setChartData2({ ...commonChartData, datasets: [{
...commonChartData.datasets[0], label: 'Different Straddle Price' }] });
} catch (error) {
console.error('Error fetching Nifty data:', error);
}
};
try {
const response = await fetch(GETLASTINDEXRATE, {
method: 'POST',
headers: myHeaders,
body: params,
});
if (!response.ok) throw new Error('Network response was not ok');
const data = await response.json();
if (!data.data || !data.data[0]) throw new Error('Data is missing');
useEffect(() => {
const fetchData = async () => {
setLoading(true);
await fetchNiftyData();
await fetchLastDateIndexPrice();
setLoading(false);
};
fetchData();
const interval = setInterval(fetchData, 30000);
useEffect(() => {
if (chartData && timePeriodData) {
const { labels, values } = timePeriodData[selectedTab] || {};
const { sma, upperBand, lowerBand } = calculateBollingerBands(values,
20, 2);
const updatedChartData = {
labels,
datasets: [
{
label: 'Straddle Price',
data: values,
fill: false,
borderColor: 'rgb(75, 192, 192)',
tension: 0.1,
},
{
label: 'Upper Bollinger Band',
data: upperBand,
fill: false,
borderColor: 'rgb(255, 99, 132)',
tension: 0.1,
},
{
label: 'Lower Bollinger Band',
data: lowerBand,
fill: false,
borderColor: 'rgb(54, 162, 235)',
tension: 0.1,
},
{
label: 'SMA (20)',
data: sma,
fill: false,
borderColor: 'rgb(153, 102, 255)',
tension: 0.1,
},
],
};
setChartData(updatedChartData);
setChartData2({ ...updatedChartData, datasets: [{
...updatedChartData.datasets[0], label: 'Different Straddle Price' }] });
}
}, [selectedTab, timePeriodData]);
const options = {
scales: {
x: {
type: 'category',
labels: chartData ? chartData.labels : [],
},
y: {
ticks: {
beginAtZero: true,
},
},
},
plugins: {
zoom: {
pan: {
enabled: true,
mode: 'x',
},
zoom: {
wheel: {
enabled: true,
},
pinch: {
enabled: true,
},
mode: 'x',
},
},
},
};
return (
<div className='chart-container'>
<h2>
Nifty Straddle Price Line Charts
{decayPercentage && lastDateIndexPrice && (
<> Decay: {((lastDateIndexPrice - decayPercentage) /
lastDateIndexPrice * 100).toFixed(1)} %</>
)}
</h2>
<div className='time-periods'>
{Object.keys(timePeriods).map(period => (
<button
key={period}
className={`tab ${selectedTab === period ? 'active' :
''}`}
onClick={() => setSelectedTab(period)}
>
{period}
</button>
))}
</div>
{loading ? (
<p>Loading...</p>
) : (
<div className='chart-content'>
{chartData && (
<>
<div className='chart'>
<Line ref={chartRef1} data={chartData}
options={options} />
</div>
<div className='chart'>
<Line ref={chartRef2} data={chartData2}
options={options} />
</div>
</>
)}
</div>
)}
</div>
);
};
export default NiftyLineChartComponent;
Qn:Challenges faced
In response to the interviewer's question about challenges faced while working on this project,
you could provide an answer like this:
Challenges Faced:
This answer highlights some of the technical challenges and how you addressed them while
working on the project. It also demonstrates problem-solving skills and an understanding of the
complexities involved in real-time data applications.
2/2
4o mini