Comments (13)
Hi @tuncbb , it seems a type error in the position calc. Can you share the block of code with error. The menssage shows the erro in line: btlivebot/main.py", line 92
from backtrader-binance-bot.
I just forked your repo,changed api key/secret in config file and changed env=development to env=production. Also i changed debug=debug to debug=false and compression=30 to 1 for fast testing.
Here is the main.py
import time
import backtrader as bt
import datetime as dt
from ccxtbt import CCXTStore
from config import BINANCE, ENV, PRODUCTION, COIN_TARGET, COIN_REFER, DEBUG
from dataset.dataset import CustomDataset
from sizer.percent import FullMoney
from strategies.basic_rsi import BasicRSI
from utils import print_trade_analysis, print_sqn, send_telegram_message
def main():
cerebro = bt.Cerebro(quicknotify=True)
if ENV == PRODUCTION: # Live trading with Binance
broker_config = {
'apiKey': BINANCE.get("key"),
'secret': BINANCE.get("secret"),
'nonce': lambda: str(int(time.time() * 1000)),
'enableRateLimit': True,
}
store = CCXTStore(exchange='binance', currency=COIN_REFER, config=broker_config, retries=5, debug=False)
broker_mapping = {
'order_types': {
bt.Order.Market: 'market',
bt.Order.Limit: 'limit',
bt.Order.Stop: 'stop-loss',
bt.Order.StopLimit: 'stop limit'
},
'mappings': {
'closed_order': {
'key': 'status',
'value': 'closed'
},
'canceled_order': {
'key': 'status',
'value': 'canceled'
}
}
}
broker = store.getbroker(broker_mapping=broker_mapping)
cerebro.setbroker(broker)
hist_start_date = dt.datetime.utcnow() - dt.timedelta(minutes=30000)
data = store.getdata(
dataname='%s/%s' % (COIN_TARGET, COIN_REFER),
name='%s%s' % (COIN_TARGET, COIN_REFER),
timeframe=bt.TimeFrame.Minutes,
fromdate=hist_start_date,
compression=1,
ohlcv_limit=99999
)
# Add the feed
cerebro.adddata(data)
else: # Backtesting with CSV file
data = CustomDataset(
name=COIN_TARGET,
dataname="dataset/binance_nov_18_mar_19_btc.csv",
timeframe=bt.TimeFrame.Minutes,
fromdate=dt.datetime(2018, 9, 20),
todate=dt.datetime(2019, 3, 13),
nullvalue=0.0
)
cerebro.resampledata(data, timeframe=bt.TimeFrame.Minutes, compression=30)
broker = cerebro.getbroker()
broker.setcommission(commission=0.001, name=COIN_TARGET) # Simulating exchange fee
broker.setcash(100000.0)
cerebro.addsizer(FullMoney)
# Analyzers to evaluate trades and strategies
# SQN = Average( profit / risk ) / StdDev( profit / risk ) x SquareRoot( number of trades )
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="ta")
cerebro.addanalyzer(bt.analyzers.SQN, _name="sqn")
# Include Strategy
cerebro.addstrategy(BasicRSI)
# Starting backtrader bot
initial_value = cerebro.broker.getvalue()
print('Starting Portfolio Value: %.8f' % initial_value)
result = cerebro.run()
# Print analyzers - results
final_value = cerebro.broker.getvalue()
print('Final Portfolio Value: %.8f' % final_value)
print('Profit %.3f%%' % ((final_value - initial_value) / initial_value * 100))
print_trade_analysis(result[0].analyzers.ta.get_analysis())
print_sqn(result[0].analyzers.sqn.get_analysis())
if DEBUG:
cerebro.plot()
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("finished.")
time = dt.datetime.now().strftime("%d-%m-%y %H:%M")
send_telegram_message("Bot finished by user at %s" % time)
except Exception as err:
send_telegram_message("Bot finished with error: %s" % err)
print("Finished with error: ", err)
raise
from backtrader-binance-bot.
This is the position.py for the err:
self.price = (self.price * oldsize + size * price) / self.size
TypeError: unsupported operand type(s) for *: 'NoneType' and 'float'
The code:
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015, 2016, 2017 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
unicode_literals)
from copy import copy
class Position(object):
'''
Keeps and updates the size and price of a position. The object has no
relationship to any asset. It only keeps size and price.
Member Attributes:
- size (int): current size of the position
- price (float): current price of the position
The Position instances can be tested using len(position) to see if size
is not null
'''
def __str__(self):
items = list()
items.append('--- Position Begin')
items.append('- Size: {}'.format(self.size))
items.append('- Price: {}'.format(self.price))
items.append('- Price orig: {}'.format(self.price_orig))
items.append('- Closed: {}'.format(self.upclosed))
items.append('- Opened: {}'.format(self.upopened))
items.append('- Adjbase: {}'.format(self.adjbase))
items.append('--- Position End')
return '\n'.join(items)
def __init__(self, size=0, price=0.0):
self.size = size
if size:
self.price = self.price_orig = price
else:
self.price = 0.0
self.adjbase = None
self.upopened = size
self.upclosed = 0
self.set(size, price)
self.updt = None
def fix(self, size, price):
oldsize = self.size
self.size = size
self.price = price
return self.size == oldsize
def set(self, size, price):
if self.size > 0:
if size > self.size:
self.upopened = size - self.size # new 10 - old 5 -> 5
self.upclosed = 0
else:
# same side min(0, 3) -> 0 / reversal min(0, -3) -> -3
self.upopened = min(0, size)
# same side min(10, 10 - 5) -> 5
# reversal min(10, 10 - -5) -> min(10, 15) -> 10
self.upclosed = min(self.size, self.size - size)
elif self.size < 0:
if size < self.size:
self.upopened = size - self.size # ex: -5 - -3 -> -2
self.upclosed = 0
else:
# same side max(0, -5) -> 0 / reversal max(0, 5) -> 5
self.upopened = max(0, size)
# same side max(-10, -10 - -5) -> max(-10, -5) -> -5
# reversal max(-10, -10 - 5) -> max(-10, -15) -> -10
self.upclosed = max(self.size, self.size - size)
else: # self.size == 0
self.upopened = self.size
self.upclosed = 0
self.size = size
self.price_orig = self.price
if size:
self.price = price
else:
self.price = 0.0
return self.size, self.price, self.upopened, self.upclosed
def __len__(self):
return abs(self.size)
def __bool__(self):
return bool(self.size != 0)
__nonzero__ = __bool__
def clone(self):
return Position(size=self.size, price=self.price)
def pseudoupdate(self, size, price):
return Position(self.size, self.price).update(size, price)
def update(self, size, price, dt=None):
'''
Updates the current position and returns the updated size, price and
units used to open/close a position
Args:
size (int): amount to update the position size
size < 0: A sell operation has taken place
size > 0: A buy operation has taken place
price (float):
Must always be positive to ensure consistency
Returns:
A tuple (non-named) contaning
size - new position size
Simply the sum of the existing size plus the "size" argument
price - new position price
If a position is increased the new average price will be
returned
If a position is reduced the price of the remaining size
does not change
If a position is closed the price is nullified
If a position is reversed the price is the price given as
argument
opened - amount of contracts from argument "size" that were used
to open/increase a position.
A position can be opened from 0 or can be a reversal.
If a reversal is performed then opened is less than "size",
because part of "size" will have been used to close the
existing position
closed - amount of units from arguments "size" that were used to
close/reduce a position
Both opened and closed carry the same sign as the "size" argument
because they refer to a part of the "size" argument
'''
self.datetime = dt # record datetime update (datetime.datetime)
self.price_orig = self.price
oldsize = self.size
self.size += size
if not self.size:
# Update closed existing position
opened, closed = 0, size
self.price = 0.0
elif not oldsize:
# Update opened a position from 0
opened, closed = size, 0
self.price = price
elif oldsize > 0: # existing "long" position updated
if size > 0: # increased position
opened, closed = size, 0
self.price = (self.price * oldsize + size * price) / self.size
elif self.size > 0: # reduced position
opened, closed = 0, size
# self.price = self.price
else: # self.size < 0 # reversed position form plus to minus
opened, closed = self.size, -oldsize
self.price = price
else: # oldsize < 0 - existing short position updated
if size < 0: # increased position
opened, closed = size, 0
self.price = (self.price * oldsize + size * price) / self.size
elif self.size < 0: # reduced position
opened, closed = 0, size
# self.price = self.price
else: # self.size > 0 - reversed position from minus to plus
opened, closed = self.size, -oldsize
self.price = price
self.upopened = opened
self.upclosed = closed
return self.size, self.price, opened, closed
from backtrader-binance-bot.
It the code, the error come from the command initial_value = cerebro.broker.getvalue()
which is a internal library of bt-ccxt-store. What version are you using?
from backtrader-binance-bot.
Hi,
Backtrader 1.9.69.122
ccxt 1.18.965
bt-ccxt-store 1.0
from backtrader-binance-bot.
Hello again, I am struggling with the project. The bot buys and sells sometimes but the bug continues. What i realized is that order prices returns zero as you can see below. Maybe the zero returns cause this error. What am i missing?
`ENV = production
Starting Portfolio Value: 0.00045425
DELAYED
LIVE
{'dteos': 737246.9999999999, 'exectype': 0, 'ordtype': 0, 'size': 0.017, 'position': 0, 'p': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7ffaced6b940>, 'ref': 1, 'status': 4, 'data': <ccxtbt.ccxtfeed.CCXTFeed object at 0x7ffad7e55f28>, 'executed': <backtrader.order.OrderData object at 0x7ffae95f9438>, 'params': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7ffaced6b940>, 'broker': None, '_active': True, 'ccxt_order': {'price': 0.02231764705882353, 'datetime': '2019-07-26T19:53:19.784Z', 'symbol': 'ETH/BTC', 'lastTradeTimestamp': None, 'amount': 0.017, 'remaining': 0.0, 'average': 0.02231764705882353, 'fee': None, 'side': 'buy', 'type': 'market', 'id': '441732094', 'cost': 0.0003794, 'timestamp': 1564170799784, 'status': 'closed', 'info': {'price': '0.00000000', 'icebergQty': '0.00000000', 'type': 'MARKET', 'cummulativeQuoteQty': '0.00037940', 'orderId': 441732094, 'executedQty': '0.01700000', 'side': 'BUY', 'isWorking': True, 'stopPrice': '0.00000000', 'time': 1564170799784, 'origQty': '0.01700000', 'symbol': 'ETHBTC', 'updateTime': 1564170799784, 'clientOrderId': 'Ma4x8A2WqBudmPuOtdVEPB', 'timeInForce': 'GTC', 'status': 'FILLED'}, 'filled': 0.017, 'trades': None}, 'owner': <live_strategy.bt_bandtrader_v3_trend.Strategy object at 0x7ffad7e55cc0>, 'info': AutoOrderedDict(), 'created': <backtrader.order.OrderData object at 0x7ffad7e77828>, '_limitoffset': 0.0, '_plimit': None, 'comminfo': None, 'triggered': False}
BUY EXECUTED, Price: 0.00000000, Cost: 0.00000000, Comm 0.00000000 True
{'dteos': 737246.9999999999, 'exectype': 0, 'ordtype': 0, 'size': 0.017, 'position': 0, 'p': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7ffaced6b940>, 'ref': 1, 'status': 4, 'data': <ccxtbt.ccxtfeed.CCXTFeed object at 0x7ffad7e55f28>, 'executed': <backtrader.order.OrderData object at 0x7ffae95f9438>, 'params': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7ffaced6b940>, 'broker': None, '_active': True, 'ccxt_order': {'price': 0.02231764705882353, 'datetime': '2019-07-26T19:53:19.784Z', 'symbol': 'ETH/BTC', 'lastTradeTimestamp': None, 'amount': 0.017, 'remaining': 0.0, 'average': 0.02231764705882353, 'fee': None, 'side': 'buy', 'type': 'market', 'id': '441732094', 'cost': 0.0003794, 'timestamp': 1564170799784, 'status': 'closed', 'info': {'price': '0.00000000', 'icebergQty': '0.00000000', 'type': 'MARKET', 'cummulativeQuoteQty': '0.00037940', 'orderId': 441732094, 'executedQty': '0.01700000', 'side': 'BUY', 'isWorking': True, 'stopPrice': '0.00000000', 'time': 1564170799784, 'origQty': '0.01700000', 'symbol': 'ETHBTC', 'updateTime': 1564170799784, 'clientOrderId': 'Ma4x8A2WqBudmPuOtdVEPB', 'timeInForce': 'GTC', 'status': 'FILLED'}, 'filled': 0.017, 'trades': None}, 'owner': <live_strategy.bt_bandtrader_v3_trend.Strategy object at 0x7ffad7e55cc0>, 'info': AutoOrderedDict(), 'created': <backtrader.order.OrderData object at 0x7ffad7e77828>, '_limitoffset': 0.0, '_plimit': None, 'comminfo': None, 'triggered': False}
BUY EXECUTED, Price: 0.00000000, Cost: 0.00000000, Comm 0.00000000 True
SELL EXECUTED, Price: 0.00000000, Cost: 0.00000000, Comm 0.00000000 True
SELL EXECUTED, Price: 0.00000000, Cost: 0.00000000, Comm 0.00000000 True
{'dteos': 737246.9999999999, 'exectype': 0, 'ordtype': 0, 'size': 0.127, 'position': 0, 'p': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7ffacef8a3c8>, 'ref': 3, 'status': 4, 'data': <ccxtbt.ccxtfeed.CCXTFeed object at 0x7ffad7e55f28>, 'executed': <backtrader.order.OrderData object at 0x7ffacef46518>, 'params': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7ffacef8a3c8>, 'broker': None, '_active': True, 'ccxt_order': {'price': 0.022296929133858265, 'datetime': '2019-07-26T19:55:23.200Z', 'symbol': 'ETH/BTC', 'lastTradeTimestamp': None, 'amount': 0.127, 'remaining': 0.0, 'average': 0.022296929133858265, 'fee': None, 'side': 'buy', 'type': 'market', 'id': '441732983', 'cost': 0.00283171, 'timestamp': 1564170923200, 'status': 'closed', 'info': {'price': '0.00000000', 'icebergQty': '0.00000000', 'type': 'MARKET', 'cummulativeQuoteQty': '0.00283171', 'orderId': 441732983, 'executedQty': '0.12700000', 'side': 'BUY', 'isWorking': True, 'stopPrice': '0.00000000', 'time': 1564170923200, 'origQty': '0.12700000', 'symbol': 'ETHBTC', 'updateTime': 1564170923200, 'clientOrderId': '2ZWJFmhksnBVwpql2Ur0C4', 'timeInForce': 'GTC', 'status': 'FILLED'}, 'filled': 0.127, 'trades': None}, 'owner': <live_strategy.bt_bandtrader_v3_trend.Strategy object at 0x7ffad7e55cc0>, 'info': AutoOrderedDict(), 'created': <backtrader.order.OrderData object at 0x7ffacef465f8>, '_limitoffset': 0.0, '_plimit': None, 'comminfo': None, 'triggered': False}
BUY EXECUTED, Price: 0.00000000, Cost: 0.00000000, Comm 0.00000000 True
{'dteos': 737246.9999999999, 'exectype': 0, 'ordtype': 0, 'size': 0.127, 'position': 0, 'p': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7ffacef8a3c8>, 'ref': 3, 'status': 4, 'data': <ccxtbt.ccxtfeed.CCXTFeed object at 0x7ffad7e55f28>, 'executed': <backtrader.order.OrderData object at 0x7ffacef46518>, 'params': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7ffacef8a3c8>, 'broker': None, '_active': True, 'ccxt_order': {'price': 0.022296929133858265, 'datetime': '2019-07-26T19:55:23.200Z', 'symbol': 'ETH/BTC', 'lastTradeTimestamp': None, 'amount': 0.127, 'remaining': 0.0, 'average': 0.022296929133858265, 'fee': None, 'side': 'buy', 'type': 'market', 'id': '441732983', 'cost': 0.00283171, 'timestamp': 1564170923200, 'status': 'closed', 'info': {'price': '0.00000000', 'icebergQty': '0.00000000', 'type': 'MARKET', 'cummulativeQuoteQty': '0.00283171', 'orderId': 441732983, 'executedQty': '0.12700000', 'side': 'BUY', 'isWorking': True, 'stopPrice': '0.00000000', 'time': 1564170923200, 'origQty': '0.12700000', 'symbol': 'ETHBTC', 'updateTime': 1564170923200, 'clientOrderId': '2ZWJFmhksnBVwpql2Ur0C4', 'timeInForce': 'GTC', 'status': 'FILLED'}, 'filled': 0.127, 'trades': None}, 'owner': <live_strategy.bt_bandtrader_v3_trend.Strategy object at 0x7ffad7e55cc0>, 'info': AutoOrderedDict(), 'created': <backtrader.order.OrderData object at 0x7ffacef465f8>, '_limitoffset': 0.0, '_plimit': None, 'comminfo': None, 'triggered': False}
BUY EXECUTED, Price: 0.00000000, Cost: 0.00000000, Comm 0.00000000 True
SELL EXECUTED, Price: 0.00000000, Cost: 0.00000000, Comm 0.00000000 True
SELL EXECUTED, Price: 0.00000000, Cost: 0.00000000, Comm 0.00000000 True
{'dteos': 737246.9999999999, 'exectype': 0, 'ordtype': 0, 'size': 0.126, 'position': 0, 'p': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7ffacef46d68>, 'ref': 5, 'status': 4, 'data': <ccxtbt.ccxtfeed.CCXTFeed object at 0x7ffad7e55f28>, 'executed': <backtrader.order.OrderData object at 0x7ffacef464a8>, 'params': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7ffacef46d68>, 'broker': None, '_active': True, 'ccxt_order': {'price': 0.022314285714285714, 'datetime': '2019-07-26T19:56:20.376Z', 'symbol': 'ETH/BTC', 'lastTradeTimestamp': None, 'amount': 0.126, 'remaining': 0.0, 'average': 0.022314285714285714, 'fee': None, 'side': 'buy', 'type': 'market', 'id': '441733466', 'cost': 0.0028116, 'timestamp': 1564170980376, 'status': 'closed', 'info': {'price': '0.00000000', 'icebergQty': '0.00000000', 'type': 'MARKET', 'cummulativeQuoteQty': '0.00281160', 'orderId': 441733466, 'executedQty': '0.12600000', 'side': 'BUY', 'isWorking': True, 'stopPrice': '0.00000000', 'time': 1564170980376, 'origQty': '0.12600000', 'symbol': 'ETHBTC', 'updateTime': 1564170980376, 'clientOrderId': 'TwXVKXWuXd1MRZ7Fcmjruk', 'timeInForce': 'GTC', 'status': 'FILLED'}, 'filled': 0.126, 'trades': None}, 'owner': <live_strategy.bt_bandtrader_v3_trend.Strategy object at 0x7ffad7e55cc0>, 'info': AutoOrderedDict(), 'created': <backtrader.order.OrderData object at 0x7ffacef46eb8>, '_limitoffset': 0.0, '_plimit': None, 'comminfo': None, 'triggered': False}
BUY EXECUTED, Price: 0.00000000, Cost: 0.00000000, Comm 0.00000000 True
{'dteos': 737246.9999999999, 'exectype': 0, 'ordtype': 0, 'size': 0.126, 'position': 0, 'p': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7ffacef46d68>, 'ref': 5, 'status': 4, 'data': <ccxtbt.ccxtfeed.CCXTFeed object at 0x7ffad7e55f28>, 'executed': <backtrader.order.OrderData object at 0x7ffacef464a8>, 'params': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7ffacef46d68>, 'broker': None, '_active': True, 'ccxt_order': {'price': 0.022314285714285714, 'datetime': '2019-07-26T19:56:20.376Z', 'symbol': 'ETH/BTC', 'lastTradeTimestamp': None, 'amount': 0.126,
'remaining': 0.0, 'average': 0.022314285714285714, 'fee': None, 'side': 'buy', 'type': 'market', 'id':
'441733466', 'cost': 0.0028116, 'timestamp': 1564170980376, 'status': 'closed', 'info': {'price': '0.00000000', 'icebergQty': '0.00000000', 'type': 'MARKET', 'cummulativeQuoteQty': '0.00281160', 'orderId': 441733466, 'executedQty': '0.12600000', 'side': 'BUY', 'isWorking': True, 'stopPrice': '0.00000000', 'time': 1564170980376, 'origQty': '0.12600000', 'symbol': 'ETHBTC', 'updateTime': 1564170980376, 'clientOrderId': 'TwXVKXWuXd1MRZ7Fcmjruk', 'timeInForce': 'GTC', 'status': 'FILLED'}, 'filled': 0.126, 'trades': None}, 'owner': <live_strategy.bt_bandtrader_v3_trend.Strategy object at 0x7ffad7e55cc0>, 'info': AutoOrderedDict(), 'created': <backtrader.order.OrderData object at 0x7ffacef46eb8>, '_limitoffset': 0.0, '_plimit': None, 'comminfo': None, 'triggered': False}
BUY EXECUTED, Price: 0.00000000, Cost: 0.00000000, Comm 0.00000000 True
Finished with error: unsupported operand type(s) for *: 'NoneType' and 'float'`
from backtrader-binance-bot.
Hey @tuncbb, I updated my ccxt library and the error appears here too. I think this is related to a bug with new updates in the library. I will debug and try to open an issue there.
from backtrader-binance-bot.
Which version is working? Do i need to downgrade it?
Maybe the problem is somewhere in the fork of Dave-Vallance? Does the Bartosh's repo work?
Thank you!
from backtrader-binance-bot.
I tried to downgrade and the problem persists. I will investigate and repport to you soon.
from backtrader-binance-bot.
Hi @tuncbb, I not found a solution for this. My temporary solution is a custom class that implement the postion (get_balance()) and sell / buy operations direclty in ccxt library:
https://gist.github.com/rodrigo-brito/8c82020f04e946e3f0c39c7243cfe1ee
from backtrader-binance-bot.
Do you mean you cannot found a solution but bypassed it by a custom class? I couldnt get "I not found..."
Thanks
from backtrader-binance-bot.
Yes, it is a temporary solution. It is applied in the project in the base strategy. I use a custom function to this operations short
, long
.
from backtrader-binance-bot.
Could you update project files as is or could you provide me a to do list? I am not a python guru but i am working on it :) I dont want to mess the project up.
Thanks
from backtrader-binance-bot.
Related Issues (6)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from backtrader-binance-bot.