├── TradingBot
├── botlog.py
├── botexecutions.py
├── bottrades.py
├── test_support.py
├── bottrade.py
├── botChart.py
├── BotGetData.py
├── AutoScroll.py
├── botMetrics.py
├── botstrategy.py
└── Gui.py
└── README.md
/TradingBot/botlog.py:
--------------------------------------------------------------------------------
1 | class BotLog(object):
2 | def __init__(self):
3 | pass
4 |
5 | def log(self, message):
6 | print (message)
--------------------------------------------------------------------------------
/TradingBot/botexecutions.py:
--------------------------------------------------------------------------------
1 |
2 | class executionsData(object):
3 |
4 | def __init__(self):
5 | self.execData= []
6 |
7 | def addExecutions(self, entryTime, pair, entryPrice, side, pnl):
8 | self.execData.append([str(entryTime), pair, entryPrice, side, pnl])
9 |
10 |
--------------------------------------------------------------------------------
/TradingBot/bottrades.py:
--------------------------------------------------------------------------------
1 |
2 | class tradesData(object):
3 |
4 | def __init__(self):
5 | self.tradesData= []
6 |
7 | def addTrades(self, entryTime, exitTime, pair, entryPrice, exitPrice, side, pnl):
8 | self.tradesData.append([str(entryTime), str(exitTime), pair, entryPrice, exitPrice, side, pnl])
9 |
--------------------------------------------------------------------------------
/TradingBot/test_support.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | #
3 | # Support module generated by PAGE version 4.9
4 | # In conjunction with Tcl version 8.6
5 | # Jan 26, 2018 10:29:14 PM
6 |
7 |
8 | import sys
9 |
10 | try:
11 | from Tkinter import *
12 | except ImportError:
13 | from tkinter import *
14 |
15 | try:
16 | import ttk
17 | py3 = 0
18 | except ImportError:
19 | import tkinter.ttk as ttk
20 | py3 = 1
21 |
22 |
23 | def init(top, gui, *args, **kwargs):
24 | global w, top_level, root
25 | w = gui
26 | top_level = top
27 | root = top
28 |
29 | def destroy_window():
30 | # Function which closes the window.
31 | global top_level
32 | top_level.destroy()
33 | top_level = None
34 |
35 | if __name__ == '__main__':
36 | import test
37 | test.vp_start_gui()
38 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Cryptocurrency trading platform
2 |
3 | Retrieves data using poloniex api.
4 |
5 | ### Availble:
6 | * Control trading sessinon via Start and Stop buttons.
7 | * Immediate close all opened positions, or stop session Together with closing all positions.
8 | * Real time interactive chart with trading strategy executions.
9 | * Real time updating table with opened postions and all trades.
10 | * Trading history storing into csv file.
11 | * Real time messages from exchange and from platform in console.
12 |
13 | Easy to change trading logic, available different markets indicators to use in strategy module(BotGetData.py).
14 | For using neccessary to have your own id and key from poloniex api.
15 | Go to BotGetData.py, 14 row and put your keys Poloniex('your-Api-Key-Here-xxxx','yourSecretKeyHere123456789').
16 |
17 |
18 | ### Requiremets:
19 | * python 3.6
20 | * poloniex
21 | * tkinter
22 | * pandas
23 | * cayons
24 | * colorama
25 |
26 | ### Install latest poloniex api release:
27 | ```
28 | pip install https://github.com/s4w3d0ff/python-poloniex/archive/v0.4.7.zip
29 | ```
30 | ### Run application:
31 | ```From cmd:
32 | python Gui.py
33 | ```
34 | ### Usage:
35 | ```
36 | Press Run button on gui.
37 | Data collection from exchange poloniex will be on, after that you can press StartTrade button.
38 | Trading simulation will be started with specified logic in BotStrategy.py
39 | ```
40 |
41 |
42 |
43 | ### Trading example:
44 |
45 | 
46 |
--------------------------------------------------------------------------------
/TradingBot/bottrade.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | from botlog import BotLog
3 | import colorama
4 | import crayons
5 | colorama.init()
6 |
7 |
8 | class BotTrade(object):
9 | def __init__(self, currentPrice, stopLossEdge):
10 | self.output = BotLog()
11 | self.status = "OPEN"
12 | self.entryPrice = currentPrice
13 | self.exitPrice = 0
14 | self.pnl= 0
15 | self.side= "Buy"
16 | self.entryTime= datetime.datetime.now()
17 | self.exitTime = ""
18 | self.output.log("Trade opened")
19 | self.stopLoss = currentPrice-stopLossEdge
20 |
21 | def close(self, currentPrice):
22 | self.exitTime = datetime.datetime.now()
23 | self.status = "CLOSED"
24 | self.side = "Sell"
25 | self.exitPrice = currentPrice
26 | self.output.log("Trade closed")
27 | self.pnl = self.exitPrice - self.entryPrice
28 |
29 | tradeStatus = "Entry Price: " + str(round(self.entryPrice, 3)) + " Status: " + \
30 | str(self.status) + " Exit Price: " + str(round(self.exitPrice, 3))
31 | tradeStatus = tradeStatus + " Pnl: " + str(round(self.pnl, 3))
32 | if (self.pnl>0):
33 | tradeStatus = crayons.green(tradeStatus)
34 | else:
35 | tradeStatus = crayons.red(tradeStatus)
36 | self.output.log(tradeStatus)
37 |
38 |
39 | def tick(self, currentPrice):
40 | if (self.stopLoss>0):
41 | if (currentPrice <= self.stopLoss):
42 | self.output.log(crayons.magenta("Exit By Stop Loss"))
43 | self.close(currentPrice)
44 |
45 | def showStatus(self):
46 | if (self.status == "OPEN"):
47 | tradeStatus = "Entry Price: " + str(round(self.entryPrice, 3)) + " Status: " + str(self.status)
48 | tradeStatus= crayons.yellow(tradeStatus)
49 | self.output.log(tradeStatus)
50 |
51 |
--------------------------------------------------------------------------------
/TradingBot/botChart.py:
--------------------------------------------------------------------------------
1 |
2 | import matplotlib.pyplot as plt
3 | from matplotlib import style
4 | import numpy as np
5 | import pandas as pd
6 | from matplotlib.ticker import MaxNLocator
7 | import matplotlib.dates as mdates
8 |
9 |
10 | class botChart(object):
11 | def __init__(self):
12 | style.use("dark_background")
13 | #plt.ion()
14 | plt.ioff()
15 | self.fig = plt.figure(figsize=(7, 5))
16 | self.ax = plt.subplot(111)
17 | plt.ion()
18 |
19 |
20 | def botLiveChart(self, x, y, tradesLive, lastTradePnl, totalPnl, percentChange):
21 |
22 | plt.cla()
23 | #plt.clf()
24 | tradesLiveInterval= [j for j in tradesLive if j[0]>=str(x.min())]
25 |
26 | self.ax.plot(x, y, color="steelblue", label="Price", linewidth=0.6, alpha=0.8)
27 | if len(tradesLive)>0:
28 | buyTime= [pd.Timestamp(j[0]) for j in tradesLiveInterval if j[3]=="Buy"]
29 | buyPrice = [j[2] for j in tradesLiveInterval if j[3] == "Buy"]
30 | sellTime = [pd.Timestamp(j[0]) for j in tradesLiveInterval if j[3] == "Sell"]
31 | sellPrice = [j[2] for j in tradesLiveInterval if j[3] == "Sell"]
32 | self.ax.scatter(np.array(buyTime), buyPrice, marker="^", color="g", s=30, label="Buy")
33 | self.ax.scatter(np.array(sellTime), sellPrice, marker="v", color="r", s=30, label="Sell")
34 | self.ax.tick_params(axis="x", labelsize=10, colors="#b3d9ff")
35 | self.ax.tick_params(axis="y", labelsize=10, colors="#b3d9ff")
36 | self.ax.xaxis.set_major_formatter(mdates.DateFormatter("%H:%M:%S"))
37 | locator = MaxNLocator(prune='both', nbins=10, n=10)
38 | self.ax.xaxis.set_major_locator(locator)
39 | for tick in self.ax.get_xticklabels():
40 | tick.set_rotation(30)
41 |
42 | self.ax.grid(True)
43 | self.ax.grid(linestyle="-", linewidth="0.2")
44 | self.ax.legend()
45 | pnlText= "LastPnl: "+str(round(lastTradePnl, 3)) + \
46 | "\nTotalPnl: "+str(round(totalPnl, 3)) + \
47 | "\nPercChange: "+str(round(percentChange, 3))
48 | plt.text(0.02, 0.85, pnlText, fontsize=9, transform=plt.gcf().transFigure, \
49 | color="#b3d9ff",bbox=dict(facecolor='steelblue', alpha=0.3))
50 | plt.subplots_adjust(left=0.27)
51 | plt.pause(0.001)
52 | plt.draw()
53 |
--------------------------------------------------------------------------------
/TradingBot/BotGetData.py:
--------------------------------------------------------------------------------
1 |
2 | import pandas as pd
3 | from poloniex import Poloniex
4 | import time
5 | import datetime
6 |
7 |
8 |
9 | class BotGetData(object):
10 |
11 | def __init__(self, pair, peroid):
12 | self.pair= pair
13 | self.period= peroid
14 | self.conn = Poloniex("YourID", "YourKey")
15 | BotGetData.getHistoricalData(self)
16 | self.lastPrice= 0
17 | self.percentChange= 0
18 | self.askPrice= 0
19 | self.bidPrice= 0
20 |
21 | def getHistoricalData(self):
22 | startTime = str(datetime.datetime.now() - datetime.timedelta(hours=1))[:19]
23 | startTimeUnix = time.mktime(datetime.datetime.strptime(startTime, "%Y-%m-%d %H:%M:%S").timetuple())
24 |
25 | endTime = str(datetime.datetime.now())[:19]
26 | endTimeUnix = time.mktime(datetime.datetime.strptime(endTime, "%Y-%m-%d %H:%M:%S").timetuple())
27 |
28 | dd = self.conn.returnChartData(currencyPair=self.pair, start=startTimeUnix, end=endTimeUnix, period=300)
29 | dd = pd.DataFrame(dd)
30 | dd.date = [pd.Timestamp(datetime.datetime.fromtimestamp(x).strftime("%Y-%m-%d %H:%M:%S")) for x in dd.date]
31 | dd.weightedAverage = dd.weightedAverage.astype(float)
32 | prices = dd[["date", "weightedAverage"]]
33 | prices.columns= ["Date", "Price"]
34 | prices["Ask"]= prices.Price
35 | prices["Bid"] = prices.Price
36 | self.historicalData= prices
37 |
38 | def getLastPrice(self):
39 | self.lastPrice = float(self.conn.returnTicker()[self.pair]["last"])
40 |
41 | def getBestBid(self):
42 | self.bidPrice = float(self.conn.returnTicker()[self.pair]["highestBid"])
43 |
44 | def getBestAsk(self):
45 | self.askPrice = float(self.conn.returnTicker()[self.pair]["lowestAsk"])
46 |
47 | def getPercentChange(self):
48 | self.percentChange = float(self.conn.returnTicker()[self.pair]["percentChange"])
49 |
50 | def updateData(self):
51 | self.getLastPrice()
52 | self.getBestAsk()
53 | self.getBestBid()
54 | self.getPercentChange()
55 | self.historicalData= self.historicalData.append({"Date":datetime.datetime.now(),\
56 | "Price":self.lastPrice, \
57 | "Ask":self.askPrice, \
58 | "Bid": self.bidPrice}, ignore_index=True)
59 |
60 |
--------------------------------------------------------------------------------
/TradingBot/AutoScroll.py:
--------------------------------------------------------------------------------
1 |
2 | from tkinter import *
3 | import tkinter.ttk as ttk
4 |
5 | # The following code is added to facilitate the Scrolled widgets you specified.
6 | class AutoScroll(object):
7 | '''Configure the scrollbars for a widget.'''
8 |
9 | def __init__(self, master):
10 | # Rozen. Added the try-except clauses so that this class
11 | # could be used for scrolled entry widget for which vertical
12 | # scrolling is not supported. 5/7/14.
13 | try:
14 | vsb = ttk.Scrollbar(master, orient='vertical', command=self.yview)
15 | except:
16 | pass
17 | hsb = ttk.Scrollbar(master, orient='horizontal', command=self.xview)
18 |
19 | #self.configure(yscrollcommand=_autoscroll(vsb),
20 | # xscrollcommand=_autoscroll(hsb))
21 | try:
22 | self.configure(yscrollcommand=self._autoscroll(vsb))
23 | except:
24 | pass
25 | self.configure(xscrollcommand=self._autoscroll(hsb))
26 |
27 | self.grid(column=0, row=0, sticky='nsew')
28 | try:
29 | vsb.grid(column=1, row=0, sticky='ns')
30 | except:
31 | pass
32 | hsb.grid(column=0, row=1, sticky='ew')
33 |
34 | master.grid_columnconfigure(0, weight=1)
35 | master.grid_rowconfigure(0, weight=1)
36 |
37 | # Copy geometry methods of master (taken from ScrolledText.py)
38 | methods = Pack.__dict__.keys() | Grid.__dict__.keys() \
39 | | Place.__dict__.keys()
40 |
41 | for meth in methods:
42 | if meth[0] != '_' and meth not in ('config', 'configure'):
43 | setattr(self, meth, getattr(master, meth))
44 |
45 | @staticmethod
46 | def _autoscroll(sbar):
47 | '''Hide and show scrollbar as needed.'''
48 | def wrapped(first, last):
49 | first, last = float(first), float(last)
50 | if first <= 0 and last >= 1:
51 | sbar.grid_remove()
52 | else:
53 | sbar.grid()
54 | sbar.set(first, last)
55 | return wrapped
56 |
57 | def __str__(self):
58 | return str(self.master)
59 |
60 | def _create_container(func):
61 | '''Creates a ttk Frame with a given master, and use this new frame to
62 | place the scrollbars and the widget.'''
63 | def wrapped(cls, master, **kw):
64 | container = ttk.Frame(master)
65 | return func(cls, container, **kw)
66 | return wrapped
67 |
68 | class ScrolledTreeView(AutoScroll, ttk.Treeview):
69 | '''A standard ttk Treeview widget with scrollbars that will
70 | automatically show/hide as needed.'''
71 | @_create_container
72 | def __init__(self, master, **kw):
73 | ttk.Treeview.__init__(self, master, **kw)
74 | AutoScroll.__init__(self, master)
75 |
--------------------------------------------------------------------------------
/TradingBot/botMetrics.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 |
4 | class botMetrics(object):
5 | def __init__(self):
6 | pass
7 |
8 | def movingAverage(self, data, period):
9 | ma= 0
10 | if len(data)> 1:
11 | ma= sum(data[-period:])/len(data[-period:])
12 | return(ma)
13 |
14 | def momentum(self, dataPoints, period=14):
15 | if (len(dataPoints) > period - 1):
16 | return dataPoints[-1] * 100 / dataPoints[-period]
17 |
18 | def EMA(self, prices, period):
19 | x = np.asarray(prices)
20 | if period>len(x):
21 | period=len(x)
22 | weights = None
23 | weights = np.exp(np.linspace(-1., 0., period))
24 | weights /= weights.sum()
25 |
26 | dd= sum([a*b for a,b in zip(weights,x[-period:])])
27 | return dd
28 |
29 | def EMA2(self, prices, period):
30 | s = np.array(prices)
31 | n = period
32 | if len(s)0:
52 | result= ema[0]
53 |
54 | return result
55 |
56 |
57 | def MACD(self, prices, nslow=26, nfast=12):
58 | emaslow = self.EMA(prices, nslow)
59 | emafast = self.EMA(prices, nfast)
60 | return emaslow, emafast
61 |
62 | def RSI(self, prices, period=14):
63 | deltas = np.diff(prices)
64 | seed = deltas[:period + 1]
65 | up = seed[seed >= 0].sum() / period
66 | down = -seed[seed < 0].sum() / period
67 | rs = up / down
68 | rsi = np.zeros_like(prices)
69 | rsi[:period] = 100. - 100. / (1. + rs)
70 |
71 | for i in range(period, len(prices)):
72 | delta = deltas[i - 1] # cause the diff is 1 shorter
73 | if delta > 0:
74 | upval = delta
75 | downval = 0.
76 | else:
77 | upval = 0.
78 | downval = -delta
79 |
80 | up = (up * (period - 1) + upval) / period
81 | down = (down * (period - 1) + downval) / period
82 | rs = up / down
83 | rsi[i] = 100. - 100. / (1. + rs)
84 | if len(prices) > period:
85 | return rsi[-1]
86 | else:
87 | return 50 # output a neutral amount until enough prices in list to calculate RSI
--------------------------------------------------------------------------------
/TradingBot/botstrategy.py:
--------------------------------------------------------------------------------
1 | from botlog import BotLog
2 | from bottrade import BotTrade
3 | from botexecutions import executionsData
4 | from bottrades import tradesData
5 | from botMetrics import botMetrics
6 | import pandas as pd
7 | import datetime
8 | import colorama
9 | import crayons
10 | colorama.init()
11 |
12 |
13 | class BotStrategy(object):
14 |
15 | def __init__(self, prices, pair, lengthMA, openPosLimit, stopLossEdge, entryEdge, timePosEdge):
16 | self.output = BotLog()
17 | self.prices = prices
18 | self.closes = [] # Needed for Momentum Indicator
19 | self.trades = []
20 | self.currentPrice = 0
21 | self.numSimulTrades = openPosLimit
22 | self.pair= pair
23 | self.side= ""
24 | self.lengthMA= lengthMA
25 | self.movAverage= 0
26 | self.expMovAverage= 0
27 | self.strategyTradingMetric= 0
28 | self.allExecutions = executionsData()
29 | self.allTrades = tradesData()
30 | self.metrics= botMetrics()
31 | self.openedPositions =[]
32 | self.lastTradePnl=0
33 | self.totalPnl=0
34 | self.stopLossEdge= stopLossEdge
35 | self.entryEdge= entryEdge
36 | self.timePosEdge= timePosEdge
37 |
38 | def movingAverage(self, data, period):
39 | ma= 0
40 | if len(data)> 1:
41 | ma= sum(data[-period:])/len(data[-period:])
42 | return(ma)
43 |
44 | def tick(self, price, startTrade):
45 | self.currentPrice= price
46 | self.prices.append(self.currentPrice)
47 | self.movAverage= self.metrics.movingAverage(data=self.prices, period=self.lengthMA)
48 | self.expMovAverage = self.metrics.EMA(prices=self.prices, period=self.lengthMA)
49 | self.strategyTradingMetric= self.expMovAverage
50 | self.output.log("Price: " + str(round(price, 3)) + " MA: " + str(round(self.movAverage ,3)) + \
51 | " EMA: "+str(round(self.expMovAverage ,3)))
52 |
53 | if startTrade:
54 | self.evaluatePositions()
55 | if self.stopLossEdge>0:
56 | self.updateOpenTrades()
57 | self.showPositions()
58 | self.updateOpenPositions()
59 |
60 | def evaluatePositions(self):
61 | currentTime= datetime.datetime.now()
62 | openTrades = []
63 | for trade in self.trades:
64 | if (trade.status == "OPEN"):
65 | openTrades.append(trade)
66 |
67 | if (len(openTrades) < self.numSimulTrades):
68 | if ((self.strategyTradingMetric-self.currentPrice)> self.entryEdge):
69 | btrade= BotTrade(self.currentPrice, stopLossEdge=self.stopLossEdge)
70 | self.trades.append(btrade)
71 | self.updateExecutions(trade=btrade, executionTime=btrade.entryTime, executionPrice=btrade.entryPrice)
72 |
73 | for trade in openTrades:
74 | if (self.currentPrice > self.strategyTradingMetric):
75 | if (currentTime-trade.entryTime).seconds>self.timePosEdge:
76 | trade.close(self.currentPrice)
77 | self.updateExecutions(trade=trade, executionTime=trade.exitTime, executionPrice=trade.exitPrice)
78 | self.updateTrades(trade=trade)
79 | self.lastTradePnl= trade.pnl
80 | self.totalPnl= self.totalPnl+self.lastTradePnl
81 |
82 | def closeAll(self):
83 | for trade in self.trades:
84 | if (trade.status == "OPEN"):
85 | trade.close(self.currentPrice)
86 | self.updateExecutions(trade=trade, executionTime=trade.exitTime, executionPrice=trade.exitPrice)
87 | self.updateTrades(trade=trade)
88 | self.lastTradePnl = trade.pnl
89 | self.totalPnl = self.totalPnl + self.lastTradePnl
90 | self.trades= []
91 | self.openedPositions =[]
92 |
93 |
94 | def updateExecutions(self, trade, executionTime, executionPrice):
95 | self.allExecutions.addExecutions(entryTime=executionTime, pair=self.pair, \
96 | entryPrice=executionPrice, side=trade.side, pnl=trade.pnl)
97 | def updateTrades(self, trade):
98 | self.allTrades.addTrades(entryTime=trade.entryTime, exitTime=trade.exitTime, pair=self.pair,\
99 | entryPrice=trade.entryPrice, exitPrice=trade.exitPrice, side=trade.side,
100 | pnl=trade.pnl)
101 | def updateOpenTrades(self):
102 | for trade in self.trades:
103 | if (trade.status == "OPEN"):
104 | if (self.currentPrice < trade.stopLoss):
105 | print("Exit StopLoss")
106 | self.output.log(crayons.magenta("Exit By Stop Loss"))
107 | trade.close(self.currentPrice)
108 | self.updateExecutions(trade=trade, executionTime=trade.exitTime, executionPrice=trade.exitPrice)
109 | self.updateTrades(trade=trade)
110 | self.lastTradePnl = trade.pnl
111 | self.totalPnl = self.totalPnl + self.lastTradePnl
112 |
113 | def updateOpenPositions(self):
114 | openedPositions = []
115 | for trade in self.trades:
116 | if (trade.status=="OPEN"):
117 | openedPositions.append([trade.entryTime, self.pair, trade.side, \
118 | round(trade.entryPrice,2), round(trade.pnl,2)])
119 | self.openedPositions= openedPositions
120 |
121 |
122 | def showPositions(self):
123 | openedPositions= []
124 | for trade in self.trades:
125 | trade.showStatus()
126 | return openedPositions
127 |
128 | def showOpenedPositions(self):
129 | temp= pd.DataFrame(self.openedPositions)
130 | if len(temp)>0:
131 | temp.columns= ["Time", "Pair", "Side", "EntryPrice", "Pnl"]
132 | return temp
133 |
134 | def showExecutions(self):
135 | temp= pd.DataFrame(self.allExecutions.execData)
136 | if len(temp)>0:
137 | temp.columns= ["Time", "Pair", "Price", "Side", "Pnl"]
138 | return temp
139 |
140 | def showTrades(self):
141 | temp = pd.DataFrame(self.allTrades.tradesData)
142 | if len(temp) > 0:
143 | temp.columns = ["EntryTime", "ExitTime", "Pair", "EntryPrice", "ExitPrice", "Side", "Pnl"]
144 | return temp
145 |
146 | def clearExecutions(self):
147 | self.allExecutions = executionsData()
148 | self.allTrades = tradesData()
149 |
--------------------------------------------------------------------------------
/TradingBot/Gui.py:
--------------------------------------------------------------------------------
1 |
2 | from tkinter import *
3 | from tkinter import messagebox
4 | import tkinter.ttk as ttk
5 | import test_support
6 | import datetime
7 | from BotGetData import BotGetData
8 | from botstrategy import BotStrategy
9 | from botChart import botChart
10 | from botlog import BotLog
11 | from AutoScroll import *
12 | import matplotlib.pyplot as plt
13 | import colorama
14 | import crayons
15 | import warnings
16 | warnings.filterwarnings("ignore")
17 | colorama.init()
18 |
19 | def vp_start_gui():
20 | '''Starting point when module is the main routine.'''
21 | global val, w, root
22 | root = Tk()
23 | top = Trading_Gui (root)
24 | test_support.init(root, top)
25 | root.mainloop()
26 |
27 | w = None
28 | def create_Trading_Gui(root, *args, **kwargs):
29 | '''Starting point when module is imported by another program.'''
30 | global w, w_win, rt
31 | rt = root
32 | w = Toplevel (root)
33 | top = Trading_Gui (w)
34 | test_support.init(w, top, *args, **kwargs)
35 | return (w, top)
36 |
37 | def destroy_Trading_Gui():
38 | global w
39 | w.destroy()
40 | w = None
41 |
42 | def chartHorizon(histDataUpdated, interval):
43 | currentTime= histDataUpdated.Date.iloc[-1]
44 | histDataUpdated= histDataUpdated[histDataUpdated.Date>=currentTime-datetime.timedelta(minutes=interval)]
45 | return histDataUpdated
46 |
47 | def clear_all():
48 | gl = globals().copy()
49 | for var in gl:
50 | if var[0] == '_': continue
51 | if 'func' in str(globals()[var]): continue
52 | if 'module' in str(globals()[var]): continue
53 |
54 | del globals()[var]
55 |
56 | class Trading_Gui:
57 | def __init__(self, top=None):
58 | '''This class configures and populates the toplevel window.
59 | top is the toplevel containing window.'''
60 | _bgcolor = '#d9d9d9' # X11 color: 'gray85'
61 | _fgcolor = '#000000' # X11 color: 'black'
62 | _compcolor = '#d9d9d9' # X11 color: 'gray85'
63 | _ana1color = '#d9d9d9' # X11 color: 'gray85'
64 | _ana2color = '#d9d9d9' # X11 color: 'gray85'
65 | self.root = root
66 | self.style = ttk.Style()
67 | self.style.theme_use("vista")
68 | self.style.configure('.',background=_bgcolor)
69 | self.style.configure('.',foreground=_fgcolor)
70 | self.style.configure('.',font="TkDefaultFont")
71 | self.style.map('.',background= [('selected', _compcolor), ('active',_ana2color)])
72 | self.strategy= []
73 | self.showChart = False
74 | self.startTrading = False
75 | self.closeAll= False
76 | self.stopRunning= False
77 | self.numberOfExecutions= 0
78 | self.numberOfTrades = 0
79 | self.output = BotLog()
80 | self.liveChartObject= []
81 | self.CheckVar = IntVar()
82 |
83 | top.geometry("990x518+446+155")
84 | top.title("Trading Gui")
85 | top.configure(background="#d9d9d9")
86 |
87 | self.TFrame1 = ttk.Frame(top)
88 | self.TFrame1.place(relx=0.01, rely=0.02, relheight=0.98, relwidth=0.11)
89 | self.TFrame1.configure(relief=GROOVE)
90 | self.TFrame1.configure(borderwidth="2")
91 | self.TFrame1.configure(relief=GROOVE)
92 | self.TFrame1.configure(width=95)
93 |
94 | self.Run = ttk.Button(self.TFrame1, command=self.main)
95 | self.Run.place(relx=0.11, rely=0.07, height=35, width=76)
96 | self.Run.configure(takefocus="")
97 | self.Run.configure(text='''Run''')
98 | self.Run.configure(width=76)
99 |
100 | self.Stop = ttk.Button(self.TFrame1, command=self.stopRun)
101 | self.Stop.place(relx=0.11, rely=0.17, height=35, width=76)
102 | self.Stop.configure(takefocus="")
103 | self.Stop.configure(text='''Stop''')
104 | self.Stop.configure(width=76)
105 |
106 | self.StartTrade = ttk.Button(self.TFrame1, command= self.useStartegy)
107 | self.StartTrade.place(relx=0.11, rely=0.27, height=35, width=76)
108 | self.StartTrade.configure(takefocus="")
109 | self.StartTrade.configure(text='''StartTrade''')
110 | self.StartTrade.configure(width=76)
111 |
112 | self.StopTrade = ttk.Button(self.TFrame1, command=self.stopTrade)
113 | self.StopTrade.place(relx=0.11, rely=0.37, height=35, width=76)
114 | self.StopTrade.configure(takefocus="")
115 | self.StopTrade.configure(text='''StopTrade''')
116 | self.StopTrade.configure(width=76)
117 |
118 | self.ShowChart = ttk.Button(self.TFrame1, command= self.chartOpen)
119 | self.ShowChart.place(relx=0.11, rely=0.47, height=35, width=76)
120 | self.ShowChart.configure(takefocus="")
121 | self.ShowChart.configure(text='''ShowChart''')
122 | self.ShowChart.configure(width=76)
123 |
124 | self.CloseChart = ttk.Button(self.TFrame1, command= self.chartClose)
125 | self.CloseChart.place(relx=0.11, rely=0.57, height=35, width=76)
126 | self.CloseChart.configure(takefocus="")
127 | self.CloseChart.configure(text='''CloseChart''')
128 | self.CloseChart.configure(width=76)
129 |
130 | self.ClosePos = ttk.Button(self.TFrame1, command= self.closeAllPositions)
131 | self.ClosePos.place(relx=0.11, rely=0.67, height=35, width=76)
132 | self.ClosePos.configure(takefocus="")
133 | self.ClosePos.configure(text='''ClosePos''')
134 |
135 | self.CheckVar.set(1)
136 | self.SaveTrades = Checkbutton(self.TFrame1, text="SaveHistory", variable=self.CheckVar, bg=_bgcolor)
137 | self.SaveTrades.place(relx=0.11, rely=0.77, height=35, width=80)
138 |
139 | self.Exit = ttk.Button(self.TFrame1, command= self.CloseWindow)
140 | self.Exit.place(relx=0.11, rely=0.9, height=35, width=76)
141 | self.Exit.configure(takefocus="")
142 | self.Exit.configure(text='''Exit''')
143 | self.Exit.configure(width=76)
144 |
145 | self.TFrame3 = Frame(top)
146 | self.TFrame3.place(relx=0.15, rely=0.05, relheight=0.1, relwidth=0.8)
147 | self.TFrame3.configure(relief=GROOVE)
148 | self.TFrame3.configure(borderwidth="2")
149 | self.TFrame3.configure(relief=GROOVE)
150 | self.TFrame3.configure(width=475)
151 | self.TFrame3.configure(takefocus="0")
152 |
153 | self.TLabel5 = Label(self.TFrame3)
154 | self.TLabel5.place(relx=0.01, rely=0.18, height=19, width=55)
155 | self.TLabel5.configure(font=('Helvetica', 8))
156 | self.TLabel5.configure(foreground="#075bb8")
157 | self.TLabel5.configure(relief=FLAT)
158 | self.TLabel5.configure(text='''Ticker:''')
159 |
160 | self.ticker = Entry(self.TFrame3)
161 | self.ticker.insert(END, str("USDT_BTC"))
162 | self.ticker.place(relx=0.07, rely=0.18, relheight=0.44, relwidth=0.09)
163 | self.ticker.configure(font=('Helvetica', 10))
164 | self.ticker.configure(background="white")
165 | self.ticker.configure(font="TkTextFont")
166 | self.ticker.configure(foreground="black")
167 | self.ticker.configure(highlightbackground="#d9d9d9")
168 | self.ticker.configure(highlightcolor="black")
169 | self.ticker.configure(insertbackground="black")
170 | self.ticker.configure(selectbackground="#c4c4c4")
171 | self.ticker.configure(selectforeground="black")
172 | self.ticker.configure(takefocus="0")
173 |
174 | self.TLabel4 = Label(self.TFrame3)
175 | self.TLabel4.place(relx=0.18, rely=0.18, height=19, width=75)
176 | self.TLabel4.configure(font=('Helvetica', 8))
177 | self.TLabel4.configure(foreground="#075bb8")
178 | self.TLabel4.configure(relief=FLAT)
179 | self.TLabel4.configure(text='''StopLossEdge:''')
180 |
181 | self.StopLossEdge = Entry(self.TFrame3)
182 | self.StopLossEdge.insert(END, str(10))
183 | self.StopLossEdge.place(relx=0.28, rely=0.18, relheight=0.44, relwidth=0.09)
184 | self.StopLossEdge.configure(font=('Helvetica', 10))
185 | self.StopLossEdge.configure(background="white")
186 | self.StopLossEdge.configure(font="TkTextFont")
187 | self.StopLossEdge.configure(foreground="black")
188 | self.StopLossEdge.configure(highlightbackground="#d9d9d9")
189 | self.StopLossEdge.configure(highlightcolor="black")
190 | self.StopLossEdge.configure(insertbackground="black")
191 | self.StopLossEdge.configure(selectbackground="#c4c4c4")
192 | self.StopLossEdge.configure(selectforeground="black")
193 | self.StopLossEdge.configure(takefocus="0")
194 |
195 | self.TLabel5 = Label(self.TFrame3)
196 | self.TLabel5.place(relx=0.39, rely=0.2, height=19, width=65)
197 | self.TLabel5.configure(font=('Helvetica', 8))
198 | self.TLabel5.configure(foreground="#075bb8")
199 | self.TLabel5.configure(relief=FLAT)
200 | self.TLabel5.configure(takefocus="0")
201 | self.TLabel5.configure(text='''EntryEdge:''')
202 |
203 | self.EntryEdge = Entry(self.TFrame3)
204 | self.EntryEdge.insert(END, str(1))
205 | self.EntryEdge.place(relx=0.47, rely=0.15, relheight=0.44, relwidth=0.09)
206 | self.EntryEdge.configure(background="white")
207 | self.EntryEdge.configure(font="TkTextFont")
208 | self.EntryEdge.configure(foreground="black")
209 | self.EntryEdge.configure(highlightbackground="#d9d9d9")
210 | self.EntryEdge.configure(highlightcolor="black")
211 | self.EntryEdge.configure(insertbackground="black")
212 | self.EntryEdge.configure(selectbackground="#c4c4c4")
213 | self.EntryEdge.configure(selectforeground="black")
214 | self.EntryEdge.configure(takefocus="0")
215 |
216 | self.TLabel6 = Label(self.TFrame3)
217 | self.TLabel6.place(relx=0.58, rely=0.2, height=19, width=85)
218 | self.TLabel6.configure(font=('Helvetica', 8))
219 | self.TLabel6.configure(foreground="#075bb8")
220 | self.TLabel6.configure(relief=FLAT)
221 | self.TLabel6.configure(takefocus="0")
222 | self.TLabel6.configure(text='''OpenTradesLimit:''')
223 |
224 | self.OpenTradesLimit = Entry(self.TFrame3)
225 | self.OpenTradesLimit.insert(END, str(4))
226 | self.OpenTradesLimit.place(relx=0.69, rely=0.15, relheight=0.44, relwidth=0.09)
227 | self.OpenTradesLimit.configure(background="white")
228 | self.OpenTradesLimit.configure(font="TkTextFont")
229 | self.OpenTradesLimit.configure(foreground="black")
230 | self.OpenTradesLimit.configure(highlightbackground="#d9d9d9")
231 | self.OpenTradesLimit.configure(highlightcolor="black")
232 | self.OpenTradesLimit.configure(insertbackground="black")
233 | self.OpenTradesLimit.configure(selectbackground="#c4c4c4")
234 | self.OpenTradesLimit.configure(selectforeground="black")
235 | self.OpenTradesLimit.configure(takefocus="0")
236 |
237 |
238 | self.TLabel7 = Label(self.TFrame3)
239 | self.TLabel7.place(relx=0.79, rely=0.2, height=19, width=85)
240 | self.TLabel7.configure(font=('Helvetica', 8))
241 | self.TLabel7.configure(foreground="#075bb8")
242 | self.TLabel7.configure(relief=FLAT)
243 | self.TLabel7.configure(takefocus="0")
244 | self.TLabel7.configure(text='''Maintenance:''')
245 |
246 | self.Maintenance = Entry(self.TFrame3)
247 | self.Maintenance.insert(END, str(1))
248 | self.Maintenance.place(relx=0.89, rely=0.15, relheight=0.44, relwidth=0.09)
249 | self.Maintenance.configure(background="white")
250 | self.Maintenance.configure(font="TkTextFont")
251 | self.Maintenance.configure(foreground="black")
252 | self.Maintenance.configure(highlightbackground="#d9d9d9")
253 | self.Maintenance.configure(highlightcolor="black")
254 | self.Maintenance.configure(insertbackground="black")
255 | self.Maintenance.configure(selectbackground="#c4c4c4")
256 | self.Maintenance.configure(selectforeground="black")
257 | self.Maintenance.configure(takefocus="0")
258 |
259 |
260 | self.style.configure('Treeview.Heading', font="TkDefaultFont")
261 | self.Scrolledtreeview1 = ScrolledTreeView(top)
262 | self.Scrolledtreeview1.place(relx=0.15, rely=0.23, relheight=0.28, relwidth=0.6)
263 | self.Scrolledtreeview1.configure(columns="Col1 Col2 Col3 Col4 Col5")
264 | self.Scrolledtreeview1.configure(takefocus="0")
265 | self.Scrolledtreeview1.heading("#0",text="Id")
266 | self.Scrolledtreeview1.heading("#0",anchor="center")
267 | self.Scrolledtreeview1.column("#0",width="35")
268 | self.Scrolledtreeview1.column("#0",minwidth="20")
269 | self.Scrolledtreeview1.column("#0",stretch="1")
270 | self.Scrolledtreeview1.column("#0",anchor="w")
271 | self.Scrolledtreeview1.heading("Col1",text="Time")
272 | self.Scrolledtreeview1.heading("Col1",anchor="center")
273 | self.Scrolledtreeview1.column("Col1",width="150")
274 | self.Scrolledtreeview1.column("Col1",minwidth="20")
275 | self.Scrolledtreeview1.column("Col1",stretch="1")
276 | self.Scrolledtreeview1.column("Col1",anchor="w")
277 | self.Scrolledtreeview1.heading("Col2",text="Symbol")
278 | self.Scrolledtreeview1.heading("Col2",anchor="center")
279 | self.Scrolledtreeview1.column("Col2",width="80")
280 | self.Scrolledtreeview1.column("Col2",minwidth="20")
281 | self.Scrolledtreeview1.column("Col2",stretch="1")
282 | self.Scrolledtreeview1.column("Col2",anchor="w")
283 | self.Scrolledtreeview1.heading("Col3",text="Side")
284 | self.Scrolledtreeview1.heading("Col3",anchor="center")
285 | self.Scrolledtreeview1.column("Col3",width="80")
286 | self.Scrolledtreeview1.column("Col3",minwidth="20")
287 | self.Scrolledtreeview1.column("Col3",stretch="1")
288 | self.Scrolledtreeview1.column("Col3",anchor="w")
289 | self.Scrolledtreeview1.heading("Col4",text="Price")
290 | self.Scrolledtreeview1.heading("Col4",anchor="center")
291 | self.Scrolledtreeview1.column("Col4",width="80")
292 | self.Scrolledtreeview1.column("Col4",minwidth="20")
293 | self.Scrolledtreeview1.column("Col4",stretch="1")
294 | self.Scrolledtreeview1.column("Col4",anchor="w")
295 | self.Scrolledtreeview1.heading("Col5",text="Pnl")
296 | self.Scrolledtreeview1.heading("Col5",anchor="center")
297 | self.Scrolledtreeview1.column("Col5",width="80")
298 | self.Scrolledtreeview1.column("Col5",minwidth="20")
299 | self.Scrolledtreeview1.column("Col5",stretch="1")
300 | self.Scrolledtreeview1.column("Col5",anchor="w")
301 |
302 |
303 | self.menubar = Menu(top,font="TkMenuFont",bg='#bef7bb',fg=_fgcolor)
304 | top.configure(menu = self.menubar)
305 |
306 | self.Scrolledtreeview2 = ScrolledTreeView(top)
307 | self.style.configure("Scrolledtreeview2", font='helvetica 24')
308 | self.Scrolledtreeview2.place(relx=0.15, rely=0.61, relheight=0.32, relwidth=0.8)
309 | self.Scrolledtreeview2.configure(columns="Col1 Col2 Col3 Col4 Col5 Col6 Col7")
310 | self.Scrolledtreeview2.configure(takefocus="0")
311 | self.Scrolledtreeview2.heading("#0", text="Id")
312 | self.Scrolledtreeview2.heading("#0", anchor="center")
313 | self.Scrolledtreeview2.column("#0", width="35")
314 | self.Scrolledtreeview2.column("#0", minwidth="20")
315 | self.Scrolledtreeview2.column("#0", stretch="1")
316 | self.Scrolledtreeview2.column("#0", anchor="w")
317 | self.Scrolledtreeview2.heading("Col1", text="EntryTime")
318 | self.Scrolledtreeview2.heading("Col1", anchor="center")
319 | self.Scrolledtreeview2.column("Col1", width="150")
320 | self.Scrolledtreeview2.column("Col1", minwidth="20")
321 | self.Scrolledtreeview2.column("Col1", stretch="1")
322 | self.Scrolledtreeview2.column("Col1", anchor="w")
323 | self.Scrolledtreeview2.heading("Col2", text="ExitTime")
324 | self.Scrolledtreeview2.heading("Col2", anchor="center")
325 | self.Scrolledtreeview2.column("Col2", width="150")
326 | self.Scrolledtreeview2.column("Col2", minwidth="20")
327 | self.Scrolledtreeview2.column("Col2", stretch="1")
328 | self.Scrolledtreeview2.column("Col2", anchor="w")
329 | self.Scrolledtreeview2.heading("Col3", text="Symbol")
330 | self.Scrolledtreeview2.heading("Col3", anchor="center")
331 | self.Scrolledtreeview2.column("Col3", width="81")
332 | self.Scrolledtreeview2.column("Col3", minwidth="20")
333 | self.Scrolledtreeview2.column("Col3", stretch="1")
334 | self.Scrolledtreeview2.column("Col3", anchor="w")
335 | self.Scrolledtreeview2.heading("Col4", text="Side")
336 | self.Scrolledtreeview2.heading("Col4", anchor="center")
337 | self.Scrolledtreeview2.column("Col4", width="80")
338 | self.Scrolledtreeview2.column("Col4", minwidth="20")
339 | self.Scrolledtreeview2.column("Col4", stretch="1")
340 | self.Scrolledtreeview2.column("Col4", anchor="w")
341 | self.Scrolledtreeview2.heading("Col5", text="EntryPrice")
342 | self.Scrolledtreeview2.heading("Col5", anchor="center")
343 | self.Scrolledtreeview2.column("Col5", width="80")
344 | self.Scrolledtreeview2.column("Col5", minwidth="20")
345 | self.Scrolledtreeview2.column("Col5", stretch="1")
346 | self.Scrolledtreeview2.column("Col5", anchor="w")
347 | self.Scrolledtreeview2.heading("Col6", text="ExitPrice")
348 | self.Scrolledtreeview2.heading("Col6", anchor="center")
349 | self.Scrolledtreeview2.column("Col6", width="80")
350 | self.Scrolledtreeview2.column("Col6", minwidth="20")
351 | self.Scrolledtreeview2.column("Col6", stretch="1")
352 | self.Scrolledtreeview2.column("Col6", anchor="w")
353 | self.Scrolledtreeview2.heading("Col7", text="Pnl")
354 | self.Scrolledtreeview2.heading("Col7", anchor="center")
355 | self.Scrolledtreeview2.column("Col7", width="80")
356 | self.Scrolledtreeview2.column("Col7", minwidth="20")
357 | self.Scrolledtreeview2.column("Col7", stretch="1")
358 | self.Scrolledtreeview2.column("Col7", anchor="w")
359 |
360 | self.Label1 = Label(top)
361 | self.Label1.place(relx=0.15, rely=0.17, height=25, width=595)
362 | self.Label1.configure(font=('Helvetica', 10))
363 | self.Label1.configure(anchor=N)
364 | self.Label1.configure(background="#b4c2fe")
365 | self.Label1.configure(compound="left")
366 | self.Label1.configure(cursor="bottom_left_corner")
367 | self.Label1.configure(disabledforeground="#a3a3a3")
368 | self.Label1.configure(foreground="#000000")
369 | self.Label1.configure(justify=LEFT)
370 | self.Label1.configure(relief=RIDGE)
371 | self.Label1.configure(text='''Opened Positions''')
372 | self.Label1.configure(textvariable=test_support)
373 | self.Label1.configure(width=459)
374 |
375 | self.Label2 = Label(top)
376 | self.Label2.place(relx=0.15, rely=0.55, height=25, width=788)
377 | self.Label2.configure(font=('Helvetica', 10))
378 | self.Label2.configure(activebackground="#f9f9f9")
379 | self.Label2.configure(activeforeground="black")
380 | self.Label2.configure(anchor=N)
381 | self.Label2.configure(background="#b4c2fe")
382 | self.Label2.configure(compound="left")
383 | self.Label2.configure(cursor="bottom_left_corner")
384 | self.Label2.configure(disabledforeground="#a3a3a3")
385 | self.Label2.configure(foreground="#000000")
386 | self.Label2.configure(highlightbackground="#d9d9d9")
387 | self.Label2.configure(highlightcolor="black")
388 | self.Label2.configure(justify=LEFT)
389 | self.Label2.configure(relief=RIDGE)
390 | self.Label2.configure(text='''Trades''')
391 | self.Label2.configure(width=459)
392 |
393 | self.TFrame2 = Frame(top)
394 | self.TFrame2.place(relx=0.76, rely=0.23, relheight=0.22, relwidth=0.2)
395 | self.TFrame2.configure(relief=SUNKEN)
396 | self.TFrame2.configure(borderwidth="2")
397 | self.TFrame2.configure(relief=SUNKEN)
398 | self.TFrame2.configure(width=150)
399 | self.TFrame2.configure(takefocus="0")
400 |
401 | self.TotalPnl = Label(self.TFrame2)
402 | self.TotalPnl.place(relx=0.002, rely=0.17, height=29, width=86)
403 | self.TotalPnl.configure(font=('Helvetica', 11))
404 | self.TotalPnl.configure(foreground="#075bb8")
405 | self.TotalPnl.configure(relief=FLAT)
406 | self.TotalPnl.configure(justify=RIGHT)
407 | self.TotalPnl.configure(takefocus="0")
408 | self.TotalPnl.configure(text='''TotalPnl:''')
409 |
410 | self.TradesCount = Label(self.TFrame2)
411 | self.TradesCount.place(relx=0.01, rely=0.63, height=29, width=106)
412 | self.TradesCount.configure(font=('Helvetica', 11))
413 | self.TradesCount.configure(foreground="#075bb8")
414 | self.TradesCount.configure(relief=FLAT)
415 | self.TradesCount.configure(justify=RIGHT)
416 | self.TradesCount.configure(takefocus="0")
417 | self.TradesCount.configure(text='''TradesCount:''')
418 |
419 | self.tradesCount = Text(self.TFrame2)
420 | self.tradesCount.configure(font=('Helvetica', 10))
421 | self.tradesCount.place(relx=0.52, rely=0.6, relheight=0.3, relwidth=0.4)
422 | self.tradesCount.configure(font=('Helvetica', 10))
423 | self.tradesCount.configure(background="white")
424 | self.tradesCount.configure(font="TkTextFont")
425 | self.tradesCount.configure(foreground="black")
426 | self.tradesCount.configure(highlightbackground="#d9d9d9")
427 | self.tradesCount.configure(highlightcolor="black")
428 | self.tradesCount.configure(insertbackground="black")
429 | self.tradesCount.configure(selectbackground="#c4c4c4")
430 | self.tradesCount.configure(selectforeground="black")
431 | self.tradesCount.configure(takefocus="0")
432 | self.tradesCount.configure(width=104)
433 |
434 | self.totalPnl = Text(self.TFrame2, font= ('Times', '24', 'bold italic') )
435 | self.totalPnl.place(relx=0.52, rely=0.1, relheight=0.3, relwidth=0.4)
436 | self.totalPnl.configure(font=('Helvetica', 10))
437 | self.totalPnl.configure(background="white")
438 | self.totalPnl.configure(font="TkTextFont")
439 | self.totalPnl.configure(foreground="black")
440 | self.totalPnl.configure(highlightbackground="#d9d9d9")
441 | self.totalPnl.configure(highlightcolor="black")
442 | self.totalPnl.configure(insertbackground="black")
443 | self.totalPnl.configure(selectbackground="#c4c4c4")
444 | self.totalPnl.configure(selectforeground="black")
445 | self.totalPnl.configure(takefocus="0")
446 | self.totalPnl.configure(width=104)
447 |
448 |
449 | def stopRun(self):
450 | self.root.update()
451 | self.stopRunning= True
452 | self.output.log(crayons.red("System stop.........."))
453 |
454 | def CloseWindow(self) :
455 | self.root.destroy()
456 |
457 | def chartOpen(self) :
458 | self.liveChartObject = botChart()
459 | self.root.update()
460 | self.showChart= True
461 |
462 | def chartClose(self) :
463 | self.root.update()
464 | self.showChart= False
465 | plt.close()
466 |
467 | def useStartegy(self) :
468 | self.root.update()
469 | self.startTrading= True
470 | self.stopRunning= False
471 | self.output.log(crayons.green("Start trading.........."))
472 |
473 | def stopTrade(self) :
474 | self.root.update()
475 | try:
476 | opPos= self.strategy.openedPositions
477 | except:
478 | opPos= []
479 | if len(opPos)>0:
480 | messagebox.showinfo("Warning", "There are opened position. Close all before stopping trading!")
481 | else:
482 | self.startTrading = False
483 | self.output.log(crayons.green("End trading.........."))
484 |
485 | def closeAllPositions(self) :
486 | self.root.update()
487 | self.closeAll = True
488 |
489 | def insertDataExecutions(self, executions):
490 | n= len(executions)
491 | if n>self.numberOfExecutions:
492 | newExecutions= executions[-(n-self.numberOfExecutions):]
493 | k= n
494 | for row in newExecutions:
495 | self.Scrolledtreeview1.insert('', 'end', text=str(k),\
496 | values=( str(row[0]).split(" ")[-1], row[1], row[3], round(row[2],2), round(row[4],3)))
497 | k= k+1
498 | self.numberOfExecutions= n
499 |
500 |
501 | def insertDataTrades(self, trades):
502 | n= len(trades)
503 | if n>self.numberOfTrades:
504 | newTrades= trades[-(n-self.numberOfTrades):]
505 | k= self.numberOfTrades
506 | for row in newTrades:
507 | self.Scrolledtreeview2.insert('', 'end', text=str(k),\
508 | values=( str(row[0]).split(" ")[-1], str(row[1]).split(" ")[-1], row[2], \
509 | row[5], round(row[3],2), round(row[4],2), round(row[6],3)))
510 | k= k+1
511 | self.numberOfTrades= n
512 |
513 | def insertOpenData(self, openedPositions):
514 | self.Scrolledtreeview1.delete(*self.Scrolledtreeview1.get_children())
515 | for i,row in enumerate(openedPositions):
516 | self.Scrolledtreeview1.insert('', 'end', text=str(i),\
517 | values=( str(row[0]).split(" ")[-1], row[1], \
518 | row[2], round(row[3], 2), round(row[4], 2)), tags=('new'))
519 |
520 | def saveTradeHistory(self, strategy):
521 | if self.CheckVar:
522 | data= strategy.showExecutions()
523 | if len(data)>0:
524 | data.to_csv("TradingHistory.csv", index=False)
525 | else:
526 | with open("TradingHistory.csv", 'w'):
527 | pass
528 |
529 |
530 | def main(self):
531 | period = 10
532 | pair = "USDT_BTC"
533 | lengthMA = 50
534 | error=False
535 | self.stopRunning= False
536 | self.numberOfTrades= 0
537 | try:
538 | data = BotGetData(pair, period)
539 | historical = data.historicalData
540 | except Exception as e:
541 | historical = []
542 | messagebox.showinfo("Error", e)
543 | error= True
544 | try:
545 | stopLossEdge= float(self.StopLossEdge.get())
546 | except:
547 | messagebox.showinfo("Error", "Wrong StopLoss input. Must be integer.")
548 | error= True
549 | try:
550 | entryEdge= float(self.EntryEdge.get())
551 | entryEdge= 0
552 | except:
553 | messagebox.showinfo("Error", "Wrong StopLoss input. Must be numeric.")
554 | error= True
555 | try:
556 | openPosLimit= int(self.OpenTradesLimit.get())
557 | if openPosLimit<=0:
558 | messagebox.showinfo("Error", "Wrong openPosLimit input. Must be integer>0.")
559 | openPosLimit= 1
560 | except:
561 | messagebox.showinfo("Error", "Wrong openPosLimit input. Must be integer.")
562 | error= True
563 | try:
564 | timePosEdge= int(self.Maintenance.get())
565 | if timePosEdge<0:
566 | messagebox.showinfo("Error", "Wrong Maintenance input. Must be integer>=0.")
567 | timePosEdge= 1
568 | except:
569 | messagebox.showinfo("Error", "Wrong Maintenance input. Must be integer.")
570 | error= True
571 | if not error:
572 | prices = historical.Price.tolist()
573 | if (len(historical) > lengthMA):
574 | prices = prices[-lengthMA:]
575 | else:
576 | print("Not enough historical data for MA=" + str(lengthMA))
577 | lengthMA = len(prices)
578 |
579 | self.strategy = BotStrategy(prices=prices, pair=pair, lengthMA=lengthMA, \
580 | openPosLimit=openPosLimit, stopLossEdge=stopLossEdge, \
581 | entryEdge=entryEdge, timePosEdge=timePosEdge)
582 | while True:
583 | try:
584 | if self.stopRunning:
585 | self.startTrading = False
586 | self.saveTradeHistory(strategy=self.strategy)
587 | self.Scrolledtreeview1.delete(*self.Scrolledtreeview1.get_children())
588 | self.Scrolledtreeview2.delete(*self.Scrolledtreeview2.get_children())
589 | self.strategy.closeAll()
590 | self.strategy.clearExecutions()
591 | break
592 | data.updateData()
593 | lastPairPrice = data.lastPrice
594 | prices.append(lastPairPrice)
595 | prices = prices[-lengthMA:]
596 | self.strategy.tick(lastPairPrice, self.startTrading)
597 | executions = self.strategy.allExecutions.execData
598 | trades = self.strategy.allTrades.tradesData
599 | histDataUpdated = chartHorizon(histDataUpdated=data.historicalData, interval=15)
600 | openedPositions= self.strategy.openedPositions
601 | self.insertDataTrades(trades)
602 | self.insertOpenData(openedPositions)
603 | self.tradesCount.delete(1.0, END)
604 | self.tradesCount.insert(END, str(len(trades)))
605 | self.totalPnl.delete(1.0, END)
606 | self.totalPnl.insert(END, str(round(self.strategy.totalPnl,1)))
607 | if self.closeAll:
608 | self.strategy.closeAll()
609 | self.saveTradeHistory(strategy=self.strategy)
610 | if self.showChart:
611 | self.liveChartObject.botLiveChart(x=histDataUpdated.Date, y=histDataUpdated.Price, \
612 | tradesLive=executions, lastTradePnl=self.strategy.lastTradePnl, \
613 | totalPnl=self.strategy.totalPnl, percentChange=data.percentChange)
614 | self.root.update()
615 |
616 | except Exception as e:
617 | messagebox.showinfo("Error", str(e))
618 | self.strategy.closeAll()
619 | self.saveTradeHistory(strategy=self.strategy)
620 | break
621 |
622 |
623 | vp_start_gui()
624 |
--------------------------------------------------------------------------------