Filter Overbought and Oversold Stocks using JAVA and Zerodha Kiteconnect API.
IMPORT LIBRARIES
import com.zerodhatech.kiteconnect.KiteConnect;
import com.zerodhatech.kiteconnect.kitehttp.exceptions.KiteException;
import com.zerodhatech.models.*;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import org.json.JSONException;
DECLARE VARIABLES
public static KiteConnect kiteSdk;
public static String instrumentToken[][]=new String[1900][2];
public static int instrumentCount=0;
public static boolean stopScan=false;
CONNECTING TO KITE
String req_token=JOptionPane.showInputDialog(this,"ENTER REQUEST TOKEN");
String api_key="";
String sec_key="";
kiteSdk = new KiteConnect("");
kiteSdk.setUserId("LP8865");
User users = null;
try {
users = kiteSdk.generateSession(req_token, sec_key);
} catch (IOException ex) {
} catch (KiteException | JSONException ex) {
Logger.getLogger(mainFrame.class.getName()).log(Level.SEVERE, null, ex);
}
kiteSdk.setAccessToken(users.accessToken);
kiteSdk.setPublicToken(users.publicToken);
Profile profile = null;
importStocks();
IMPORT STOCKS
private void importStocks()
{
int j=0;
try {
List<Instrument> instruments = kiteSdk.getInstruments();
System.out.println(instruments.size());
for(int i=0;i<instruments.size();i++)
{
if((!instruments.get(i).segment.equals("INDICES"))&&(instruments.get(i).exchange.equals("NSE"))&&(instruments.get(i).name!=null)&&(instruments.get(i).instrument_type.equals("EQ"))){
instrumentToken[j][0]=instruments.get(i).instrument_token+"";
instrumentToken[j][1]=instruments.get(i).tradingsymbol;
j+=1;
}
}
} catch (KiteException ex) {
Logger.getLogger(mainFrame.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(mainFrame.class.getName()).log(Level.SEVERE, null, ex);
} catch (JSONException ex) {
Logger.getLogger(mainFrame.class.getName()).log(Level.SEVERE, null, ex);
}
instrumentCount=j;
jLabel1.setText(j+" STOCKS");
System.out.println(instrumentCount+" STOCKS IMPORTED");
// TODO add your handling code here:
}
STRATEGY CLASS
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.table.DefaultTableModel;
/**
*
* @author mukesh
*/
public class strategy implements Runnable{
DefaultTableModel model;
@Override
public void run() {
model=(DefaultTableModel)mainFrame.jTable1.getModel();
int count=model.getRowCount();
for(int i=0;i<count;i++)
{
model.removeRow(0);
}
String instrumentToken[][]=mainFrame.instrumentToken;
int j=mainFrame.instrumentCount;
/** Get historical data dump, requires from and to date, intrument token, interval, continuous (for expired F&O contracts), oi (open interest)
* returns historical data object which will have list of historical data inside the object.*/
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String fromString ="";
String toString = "";
LocalDate fromDay = LocalDate.now().minusDays(60);
System.out.println(fromDay);
fromString = fromDay+" 09:15:00";
toString = formatter.format(new Date());
Date from = null;
Date to = null;
try {
from = formatter.parse(fromString);
to = formatter.parse(toString);
} catch (ParseException ex) {
Logger.getLogger(mainFrame.class.getName()).log(Level.SEVERE, null, ex);
}
String timeFrame=mainFrame.jComboBox3.getSelectedItem().toString();
mainFrame.jProgressBar1.setMaximum(j);
for(int i=0;i<j;i++){
if(mainFrame.stopScan)
{
break;
}
if(mainFrame.jComboBox1.getSelectedItem().toString().equals("RSI")){
new Thread(new rsiStrtegy(from,to,instrumentToken[i][0],timeFrame,model,instrumentToken[i][1])).start();}
else
{
break;
}
if((i%30==0)&&(i>0))
{
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(strategy.class.getName()).log(Level.SEVERE, null, ex);
}
}
mainFrame.jProgressBar1.setValue(i);
}
}
}
RSI CALCULATION CLASS
import com.zerodhatech.kiteconnect.kitehttp.exceptions.KiteException;
import com.zerodhatech.models.HistoricalData;
import java.io.IOException;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.table.DefaultTableModel;
import org.json.JSONException;
import static stockscanner.mainFrame.kiteSdk;
/**
*
* @author mukesh
*/
public class rsiStrtegy implements Runnable{
DefaultTableModel model;
Date from;
Date to;
String instrument;
String timeFrame;
String stockName;
rsiStrtegy(Date from,Date to,String instrument,String timeFrame,DefaultTableModel model,String stockName)
{
this.from=from;
this.to=to;
this.instrument=instrument;
this.timeFrame=timeFrame;
this.model=model;
this.stockName=stockName;
}
@Override
public void run() {
HistoricalData historicalData = null;
try {
historicalData = kiteSdk.getHistoricalData(from, to, instrument, timeFrame, false, false);
int size=historicalData.dataArrayList.size()-1;
double gain=0;double loss=0;
for(int i=0;i<14;i++)
{
if(historicalData.dataArrayList.get(i+1).close>historicalData.dataArrayList.get(i).close)
{
gain+=((historicalData.dataArrayList.get(i+1).close-historicalData.dataArrayList.get(i).close)/historicalData.dataArrayList.get(i).close)*100;
}
else
{
loss+=((historicalData.dataArrayList.get(i).close-historicalData.dataArrayList.get(i+1).close)/historicalData.dataArrayList.get(i+1).close)*100;
}
}
gain=gain/14;
loss=loss/14;
double rsi=100-(100/(1+(gain/loss)));
for(int i=14;i<size;i++)
{
if(historicalData.dataArrayList.get(i+1).close>historicalData.dataArrayList.get(i).close)
{
gain=(gain*13+((historicalData.dataArrayList.get(i+1).close-historicalData.dataArrayList.get(i).close)/historicalData.dataArrayList.get(i).close)*100)/14;
loss=(loss*13)/14;
}
else
{
loss=(loss*13+((historicalData.dataArrayList.get(i).close-historicalData.dataArrayList.get(i+1).close)/historicalData.dataArrayList.get(i+1).close)*100)/14;
gain=(gain*13)/14;
}
rsi=100-100/(1+(gain/loss));
}
if(mainFrame.jComboBox2.getSelectedItem().toString().equals("GREATER THAN")){
if((rsi>Double.parseDouble(mainFrame.jTextField1.getText())))
{
model.addRow(new Object[]{stockName,(int)(rsi),historicalData.dataArrayList.get(size).close});
}
} else if(rsi<Double.parseDouble(mainFrame.jTextField1.getText()))
{
model.addRow(new Object[]{stockName,(int)(rsi),historicalData.dataArrayList.get(size).close});
}
} catch (KiteException ex) {
Logger.getLogger(mainFrame.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(mainFrame.class.getName()).log(Level.SEVERE, null, ex);
} catch (JSONException ex) {
Logger.getLogger(mainFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
START THREAD
stopScan=false;
new Thread(new strategy()).start();
STOP THREAD
stopScan=true;
LOOK AND FEEL
try {
// select Look and Feel
UIManager.setLookAndFeel("com.jtattoo.plaf.hifi.HiFiLookAndFeel");
// start application
new mainFrame().setVisible(true);
}
catch (Exception ex) {
ex.printStackTrace();
}
Thanks for explaining algo trading in such a clear way. Your breakdown of how automated strategies work makes the concept much easier to understand. The insights on risk control, speed, and disciplined execution are especially helpful for anyone looking to explore algorithm-based trading with more confidence and clarity.
ReplyDelete