Skip to content

Commit

Permalink
Merge pull request #122 from marketcalls/chartink-scanner
Browse files Browse the repository at this point in the history
Chartink Scanner, Traffic and Latency Logs Implementation
  • Loading branch information
marketcalls authored Dec 17, 2024
2 parents f84a79e + ddf15ca commit aac3eb8
Show file tree
Hide file tree
Showing 40 changed files with 4,076 additions and 117 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,26 @@ For detailed installation instructions, please refer to [INSTALL.md](INSTALL.md)

## Features

- **ChartInk Platform Integration**:
- Direct integration with ChartInk for strategy execution
- Automated scanning and trading based on ChartInk signals
- Real-time strategy monitoring and management
- Custom strategy configuration and deployment
- Seamless execution of ChartInk strategies through your broker

- **Advanced Monitoring Tools**:
- **Latency Monitor**: Track and analyze order execution performance
- Real-time latency tracking across different brokers
- Detailed breakdown of execution times
- Performance comparison between brokers
- Order execution success rates and patterns
- **Traffic Monitor**: Monitor system performance and API usage
- Real-time API request tracking
- Endpoint-specific analytics
- Error rate monitoring
- System performance metrics
For detailed information about monitoring tools, see [traffic.md](docs/traffic.md)

- **Modern UI with DaisyUI**:
- Sleek and responsive interface built with DaisyUI components
- Three distinct themes:
Expand Down
39 changes: 28 additions & 11 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
from utils.env_check import load_and_check_env_variables # Import the environment check function
load_and_check_env_variables()


from flask import Flask, render_template
from extensions import socketio # Import SocketIO
from limiter import limiter # Import the Limiter instance
from cors import cors # Import the CORS instance
from utils.version import get_version # Import version management
from utils.latency_monitor import init_latency_monitoring # Import latency monitoring
from utils.traffic_logger import init_traffic_logging # Import traffic logging

from blueprints.auth import auth_bp
from blueprints.dashboard import dashboard_bp
Expand All @@ -20,22 +21,27 @@
from blueprints.core import core_bp
from blueprints.analyzer import analyzer_bp # Import the analyzer blueprint
from blueprints.settings import settings_bp # Import the settings blueprint
from blueprints.chartink import chartink_bp # Import the chartink blueprint
from blueprints.traffic import traffic_bp # Import the traffic blueprint
from blueprints.latency import latency_bp # Import the latency blueprint

from restx_api import api_v1_bp
from restx_api import api_v1_bp, api

from database.auth_db import init_db as ensure_auth_tables_exists
from database.user_db import init_db as ensure_user_tables_exists
from database.symbol import init_db as ensure_master_contract_tables_exists
from database.apilog_db import init_db as ensure_api_log_tables_exists
from database.analyzer_db import init_db as ensure_analyzer_tables_exists
from database.settings_db import init_db as ensure_settings_tables_exists
from database.chartink_db import init_db as ensure_chartink_tables_exists
from database.traffic_db import init_logs_db as ensure_traffic_logs_exists
from database.latency_db import init_latency_db as ensure_latency_tables_exists

from utils.plugin_loader import load_broker_auth_functions

from dotenv import load_dotenv
import os


def create_app():
# Initialize Flask application
app = Flask(__name__)
Expand All @@ -53,9 +59,15 @@ def create_app():

# Environment variables
app.secret_key = os.getenv('APP_KEY')
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL') # Adjust the environment variable name as necessary
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL')

# Register RESTx API blueprint first
app.register_blueprint(api_v1_bp)

# Initialize traffic logging middleware after RESTx but before other blueprints
init_traffic_logging(app)

# Register the blueprints
# Register other blueprints
app.register_blueprint(auth_bp)
app.register_blueprint(dashboard_bp)
app.register_blueprint(orders_bp)
Expand All @@ -65,11 +77,15 @@ def create_app():
app.register_blueprint(tv_json_bp)
app.register_blueprint(brlogin_bp)
app.register_blueprint(core_bp)
app.register_blueprint(analyzer_bp) # Register the analyzer blueprint
app.register_blueprint(settings_bp) # Register the settings blueprint
app.register_blueprint(analyzer_bp)
app.register_blueprint(settings_bp)
app.register_blueprint(chartink_bp)
app.register_blueprint(traffic_bp)
app.register_blueprint(latency_bp)

# Register RESTx API blueprint
app.register_blueprint(api_v1_bp)
# Initialize latency monitoring (after registering API blueprint)
with app.app_context():
init_latency_monitoring(app)

@app.errorhandler(404)
def not_found_error(error):
Expand All @@ -81,7 +97,6 @@ def inject_version():

return app


def setup_environment(app):
with app.app_context():
#load broker plugins
Expand All @@ -93,14 +108,16 @@ def setup_environment(app):
ensure_api_log_tables_exists()
ensure_analyzer_tables_exists()
ensure_settings_tables_exists()
ensure_chartink_tables_exists()
ensure_traffic_logs_exists()
ensure_latency_tables_exists()

# Conditionally setup ngrok in development environment
if os.getenv('NGROK_ALLOW') == 'TRUE':
from pyngrok import ngrok
public_url = ngrok.connect(name='flask').public_url # Assuming Flask runs on the default port 5000
print(" * ngrok URL: " + public_url + " *")


app = create_app()

# Explicitly call the setup environment function
Expand Down
31 changes: 10 additions & 21 deletions blueprints/brlogin.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ def ratelimit_handler(e):
@limiter.limit(LOGIN_RATE_LIMIT_HOUR)
def broker_callback(broker,para=None):
print(f'Broker is {broker}')
# Check if user is not in session first
if 'user' not in session:
return redirect(url_for('auth.login'))

if session.get('logged_in'):
# Store broker in session and g
session['broker'] = broker
Expand All @@ -36,8 +40,6 @@ def broker_callback(broker,para=None):

if broker == 'fivepaisa':
if request.method == 'GET':
if 'user' not in session:
return redirect(url_for('auth.login'))
return render_template('5paisa.html')

elif request.method == 'POST':
Expand All @@ -50,8 +52,6 @@ def broker_callback(broker,para=None):

elif broker == 'angel':
if request.method == 'GET':
if 'user' not in session:
return redirect(url_for('auth.login'))
return render_template('angel.html')

elif request.method == 'POST':
Expand All @@ -63,8 +63,6 @@ def broker_callback(broker,para=None):

elif broker == 'aliceblue':
if request.method == 'GET':
if 'user' not in session:
return redirect(url_for('auth.login'))
return render_template('aliceblue.html')

elif request.method == 'POST':
Expand Down Expand Up @@ -111,8 +109,6 @@ def broker_callback(broker,para=None):

elif broker == 'zebu':
if request.method == 'GET':
if 'user' not in session:
return redirect(url_for('auth.login'))
return render_template('zebu.html')

elif request.method == 'POST':
Expand All @@ -125,8 +121,6 @@ def broker_callback(broker,para=None):

elif broker == 'shoonya':
if request.method == 'GET':
if 'user' not in session:
return redirect(url_for('auth.login'))
return render_template('shoonya.html')

elif request.method == 'POST':
Expand All @@ -140,11 +134,8 @@ def broker_callback(broker,para=None):
elif broker=='kotak':
print(f"The Broker is {broker}")
if request.method == 'GET':
if 'user' not in session:
return redirect(url_for('auth.login'))
return render_template('kotak.html')


elif request.method == 'POST':
otp = request.form.get('otp')
token = request.form.get('token')
Expand All @@ -153,11 +144,8 @@ def broker_callback(broker,para=None):
api_secret = get_broker_api_secret()

auth_token, error_message = auth_function(otp,token,sid,userid,api_secret)

forward_url = 'kotak.html'



else:
code = request.args.get('code') or request.args.get('request_token')
print(f'The code is {code}')
Expand All @@ -169,21 +157,22 @@ def broker_callback(broker,para=None):
session['broker'] = broker
print(f'Connected broker: {broker}')
if broker == 'zerodha':
#token = request.args.get('request_token')
auth_token = f'{BROKER_API_KEY}:{auth_token}'
if broker == 'dhan':
#token = request.args.get('request_token')
auth_token = f'{auth_token}'
return handle_auth_success(auth_token, session['user'],broker)
return handle_auth_success(auth_token, session['user'], broker)
else:
return handle_auth_failure(error_message, forward_url=forward_url)



@brlogin_bp.route('/<broker>/loginflow', methods=['POST','GET'])
@limiter.limit(LOGIN_RATE_LIMIT_MIN)
@limiter.limit(LOGIN_RATE_LIMIT_HOUR)
def broker_loginflow(broker):
# Check if user is not in session first
if 'user' not in session:
return redirect(url_for('auth.login'))

if broker == 'kotak':
mobilenumber = request.form.get('mobilenumber')
password = request.form.get('password')
Expand Down Expand Up @@ -241,4 +230,4 @@ def getKotakOTP(userid,token):
res = conn.getresponse()
data = res.read()

return 'success'
return 'success'
Loading

0 comments on commit aac3eb8

Please sign in to comment.