Skip to content

Commit

Permalink
fix: refactor tradingview (#383)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisleekr authored Nov 2, 2021
1 parent aa9e9ff commit 7f12028
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 102 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to this project will be documented in this file.

## [Unreleased]

- Refactored TradingView python server - [#383](https://github.com/chrisleekr/binance-trading-bot/pull/383)

## [0.0.84] - 2021-10-30

- Enhanced TradingView using get_multiple_analysis - [#375](https://github.com/chrisleekr/binance-trading-bot/pull/375)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ describe('get-trading-view.js', () => {
interval: '1h'
},
paramsSerializer: expect.any(Function),
timeout: 5000
timeout: 20000
}
);
});
Expand Down Expand Up @@ -267,7 +267,7 @@ describe('get-trading-view.js', () => {
interval: '15m'
},
paramsSerializer: expect.any(Function),
timeout: 5000
timeout: 20000
}
);

Expand All @@ -280,7 +280,7 @@ describe('get-trading-view.js', () => {
interval: '5m'
},
paramsSerializer: expect.any(Function),
timeout: 5000
timeout: 20000
}
);
});
Expand Down Expand Up @@ -480,7 +480,7 @@ describe('get-trading-view.js', () => {
interval: '15m'
},
paramsSerializer: expect.any(Function),
timeout: 5000
timeout: 20000
}
);

Expand All @@ -493,7 +493,7 @@ describe('get-trading-view.js', () => {
interval: '5m'
},
paramsSerializer: expect.any(Function),
timeout: 5000
timeout: 20000
}
);
});
Expand Down Expand Up @@ -764,7 +764,7 @@ describe('get-trading-view.js', () => {
interval: '15m'
},
paramsSerializer: expect.any(Function),
timeout: 5000
timeout: 20000
}
);

Expand All @@ -777,7 +777,7 @@ describe('get-trading-view.js', () => {
interval: '5m'
},
paramsSerializer: expect.any(Function),
timeout: 5000
timeout: 20000
}
);
});
Expand Down Expand Up @@ -988,7 +988,7 @@ describe('get-trading-view.js', () => {
interval: '1h'
},
paramsSerializer: expect.any(Function),
timeout: 5000
timeout: 20000
});
});

Expand Down Expand Up @@ -1072,7 +1072,7 @@ describe('get-trading-view.js', () => {
interval: '1h'
},
paramsSerializer: expect.any(Function),
timeout: 5000
timeout: 20000
});
});

Expand Down Expand Up @@ -1138,7 +1138,7 @@ describe('get-trading-view.js', () => {
interval: '1h'
},
paramsSerializer: expect.any(Function),
timeout: 5000
timeout: 20000
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const retrieveTradingView = async (logger, symbols, interval) => {
paramsSerializer:
/* istanbul ignore next */
p => qs.stringify(p, { arrayFormat: 'repeat' }),
timeout: 5000 // timeout 5 seconds
timeout: 20000 // timeout 20 seconds
});
const tradingViewResult = _.get(response.data, 'result', {});

Expand Down
4 changes: 4 additions & 0 deletions docker-compose.rpi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ services:
networks:
- internal
restart: unless-stopped
logging:
driver: 'json-file'
options:
max-size: '50m'

binance-redis:
container_name: binance-redis
Expand Down
4 changes: 4 additions & 0 deletions docker-compose.server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ services:
networks:
- internal
restart: unless-stopped
logging:
driver: 'json-file'
options:
max-size: '50m'

binance-redis:
container_name: binance-redis
Expand Down
4 changes: 4 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ services:
- PYTHONUNBUFFERED=1
ports:
- 8082:8080
logging:
driver: 'json-file'
options:
max-size: '50m'

binance-redis:
container_name: binance-redis
Expand Down
3 changes: 3 additions & 0 deletions tradingview/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ RUN pip install -r requirements.txt

COPY . .

ENV FLASK_APP=main.py
ENV FLASK_ENV=production

CMD [ "python", "main.py"]

EXPOSE 8080
2 changes: 1 addition & 1 deletion tradingview/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# TradingView Indicator

- Cloned from [https://github.com/reg2005/tradingview-ta-docker](https://github.com/reg2005/tradingview-ta-docker)
- Based on [https://github.com/reg2005/tradingview-ta-docker](https://github.com/reg2005/tradingview-ta-docker)
- Based on [https://github.com/brian-the-dev/python-tradingview-ta](https://github.com/brian-the-dev/python-tradingview-ta)

Since `tradingview-ta-docker` does not provide ARM docker image, I had to build in this project.
130 changes: 47 additions & 83 deletions tradingview/main.py
Original file line number Diff line number Diff line change
@@ -1,89 +1,53 @@
from http.server import BaseHTTPRequestHandler, HTTPServer
from tradingview_ta import TA_Handler, get_multiple_analysis
from urllib.parse import urlparse, parse_qs
import json

hostName = "0.0.0.0"
serverPort = 8080


class MyServer(BaseHTTPRequestHandler):
def _set_headers(self, statusCode):
self.send_response(statusCode)
self.send_header('Content-type', 'application/json')
self.end_headers()

def _handle_symbol(self, qParsed):
print('Process _handle_symbol')

symbol = qParsed['symbol'][0]
screener = qParsed['screener'][0]
exchange = qParsed['exchange'][0]
interval = qParsed['interval'][0]
tv = TA_Handler(
symbol=symbol,
screener=screener,
exchange=exchange,
interval=interval
)
analyse = tv.get_analysis()

print({symbol, screener, exchange, interval}, vars(analyse))
self._set_headers(200)
self.wfile.write(bytes(json.dumps({'request': {'symbol': symbol, 'screener': screener, 'exchange': exchange, 'interval': interval}, 'result': {
'summary': analyse.summary, 'time': analyse.time.isoformat(), 'oscillators': analyse.oscillators, 'moving_averages': analyse.moving_averages, 'indicators': analyse.indicators}}), "utf-8"))

def _handle_symbols(self, qParsed):
print('Process _handle_symbols')

symbols = qParsed['symbols']
screener = qParsed['screener'][0]
interval = qParsed['interval'][0]

analyse = get_multiple_analysis(
screener, interval, symbols
)

result = {}
for symbol in symbols:
symbolAnalyse = analyse[symbol]
import logging
import sys
import colorlog

from flask import Flask, jsonify, request
from tradingview_ta import get_multiple_analysis

app = Flask(__name__)

logger = logging.getLogger('')
logger.setLevel(logging.DEBUG)
sh = logging.StreamHandler(sys.stdout)
sh.setFormatter(colorlog.ColoredFormatter(
'%(log_color)s [%(asctime)s] %(levelname)s [%(filename)s.%(funcName)s:%(lineno)d] %(message)s', datefmt='%a, %d %b %Y %H:%M:%S'))
logger.addHandler(sh)


@app.route('/', methods=['GET'])
def index():
logger.info("Request: "+str(request.args))
symbols = request.args.getlist('symbols')
screener = request.args.get('screener')
interval = request.args.get('interval')

analyse = get_multiple_analysis(
screener, interval, symbols
)

result = {}
for symbol in symbols:
symbolAnalyse = analyse[symbol]
if not (symbolAnalyse is None):
result[symbol] = {
'summary': symbolAnalyse.summary, 'time': symbolAnalyse.time.isoformat(), 'oscillators': symbolAnalyse.oscillators, 'moving_averages': symbolAnalyse.moving_averages, 'indicators': symbolAnalyse.indicators}

print({tuple(symbols), screener, interval}, result)

self._set_headers(200)
self.wfile.write(bytes(json.dumps({'request': {
'symbols': symbols, 'screener': screener, 'interval': interval}, 'result': result}), "utf-8"))

def do_HEAD(self):
self._set_headers()

def do_GET(self):
o = urlparse(self.path)
qParsed = parse_qs(o.query)

symbolExists = 'symbol' in qParsed
symbolsExists = 'symbols' in qParsed

if symbolExists == True:
self._handle_symbol(qParsed)
elif symbolsExists == True:
self._handle_symbols(qParsed)
else:
self._set_headers(500)
self.wfile.write(bytes(json.dumps(
{'request': qParsed, 'message': 'symbol or symbols must be provided.'})))

result[symbol] = {}
# logger.info('Processed '+symbol)

if __name__ == "__main__":
webServer = HTTPServer((hostName, serverPort), MyServer)
print("Server started http://%s:%s" % (hostName, serverPort))
response = {
'request': {
'symbols': symbols,
'screener': screener,
'interval': interval
},
'result': result
}
logger.info("Response: "+str(response))
return jsonify(response)

try:
webServer.serve_forever()
except KeyboardInterrupt:
pass

webServer.server_close()
print("Server stopped.")
if __name__ == "__main__":
from waitress import serve
serve(app, host="0.0.0.0", port=8080)
11 changes: 4 additions & 7 deletions tradingview/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
certifi==2021.10.8
chardet==4.0.0
idna==3.3
protobuf==3.19.0
pybind11==2.8.0
requests==2.26.0
six==1.16.0
tradingview-ta==3.2.9
Flask==2.0.2
waitress==2.0.0
urllib3==1.26.7
paste==3.5.0
colorlog==6.5.0

0 comments on commit 7f12028

Please sign in to comment.