Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: refactor tradingview #383

Merged
merged 3 commits into from
Nov 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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