diff --git a/.flake8 b/.flake8 new file mode 100644 index 000000000..46b77df53 --- /dev/null +++ b/.flake8 @@ -0,0 +1,4 @@ +[flake8] +ignore = E226,E302,E41,E126,F841 +max-line-length = 160 +exclude = */tests/* diff --git a/freqtrade/constants.py b/freqtrade/constants.py index bc8a7223c..7558ae032 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -35,7 +35,7 @@ SUPPORTED_FIAT = [ "KRW", "MXN", "MYR", "NOK", "NZD", "PHP", "PKR", "PLN", "RUB", "SEK", "SGD", "THB", "TRY", "TWD", "ZAR", "USD", "BTC", "ETH", "XRP", "LTC", "BCH", "USDT" - ] +] # Required json-schema for user specified config CONF_SCHEMA = { diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index c0fc32633..39767cd32 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -45,6 +45,7 @@ def retrier(f): else: logger.warning('Giving up retrying: %s()', f.__name__) raise ex + return wrapper @@ -299,8 +300,8 @@ def get_ticker_history(pair: str, tick_interval: str, since_ms: Optional[int] = try: # last item should be in the time interval [now - tick_interval, now] till_time_ms = arrow.utcnow().shift( - minutes=-constants.TICKER_INTERVAL_MINUTES[tick_interval] - ).timestamp * 1000 + minutes=-constants.TICKER_INTERVAL_MINUTES[tick_interval] + ).timestamp * 1000 # it looks as if some exchanges return cached data # and they update it one in several minute, so 10 mins interval # is necessary to skeep downloading of an empty array when all diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 7438c04c8..90cd8b7ef 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -75,8 +75,7 @@ class Backtesting(object): (arrow.get(min(frame.date)), arrow.get(max(frame.date))) for frame in data.values() ] - return min(timeframe, key=operator.itemgetter(0))[0], \ - max(timeframe, key=operator.itemgetter(1))[1] + return min(timeframe, key=operator.itemgetter(0))[0], max(timeframe, key=operator.itemgetter(1))[1] def _generate_text_table(self, data: Dict[str, Dict], results: DataFrame) -> str: """ diff --git a/freqtrade/strategy/default_strategy.py b/freqtrade/strategy/default_strategy.py index 22689f17a..1fe91726c 100644 --- a/freqtrade/strategy/default_strategy.py +++ b/freqtrade/strategy/default_strategy.py @@ -16,10 +16,10 @@ class DefaultStrategy(IStrategy): # Minimal ROI designed for the strategy minimal_roi = { - "40": 0.0, - "30": 0.01, - "20": 0.02, - "0": 0.04 + "40": 0.0, + "30": 0.01, + "20": 0.02, + "0": 0.04 } # Optimal stoploss designed for the strategy @@ -204,14 +204,14 @@ class DefaultStrategy(IStrategy): """ dataframe.loc[ ( - (dataframe['rsi'] < 35) & - (dataframe['fastd'] < 35) & - (dataframe['adx'] > 30) & - (dataframe['plus_di'] > 0.5) + (dataframe['rsi'] < 35) & + (dataframe['fastd'] < 35) & + (dataframe['adx'] > 30) & + (dataframe['plus_di'] > 0.5) ) | ( - (dataframe['adx'] > 65) & - (dataframe['plus_di'] > 0.5) + (dataframe['adx'] > 65) & + (dataframe['plus_di'] > 0.5) ), 'buy'] = 1 @@ -225,16 +225,16 @@ class DefaultStrategy(IStrategy): """ dataframe.loc[ ( - ( - (qtpylib.crossed_above(dataframe['rsi'], 70)) | - (qtpylib.crossed_above(dataframe['fastd'], 70)) - ) & - (dataframe['adx'] > 10) & - (dataframe['minus_di'] > 0) + ( + (qtpylib.crossed_above(dataframe['rsi'], 70)) | + (qtpylib.crossed_above(dataframe['fastd'], 70)) + ) & + (dataframe['adx'] > 10) & + (dataframe['minus_di'] > 0) ) | ( - (dataframe['adx'] > 70) & - (dataframe['minus_di'] > 0.5) + (dataframe['adx'] > 70) & + (dataframe['minus_di'] > 0.5) ), 'sell'] = 1 return dataframe diff --git a/freqtrade/strategy/resolver.py b/freqtrade/strategy/resolver.py index 845d20874..f822a5d0a 100644 --- a/freqtrade/strategy/resolver.py +++ b/freqtrade/strategy/resolver.py @@ -40,7 +40,6 @@ class StrategyResolver(object): self.strategy: IStrategy = self._load_strategy(strategy_name, extra_dir=config.get('strategy_path')) - # Set attributes # Check if we need to override configuration if 'minimal_roi' in config: diff --git a/requirements-aws.txt b/requirements-aws.txt deleted file mode 100644 index 3e5dbca8d..000000000 --- a/requirements-aws.txt +++ /dev/null @@ -1,18 +0,0 @@ -ccxt==1.14.24 -SQLAlchemy==1.2.7 -arrow==0.12.1 -cachetools==2.1.0 -requests==2.18.4 -urllib3==1.22 -wrapt==1.10.11 -pandas==0.23.0 -scikit-learn==0.19.1 -scipy==1.1.0 -jsonschema==2.6.0 -numpy==1.14.3 -TA-Lib==0.4.17 -git+git://github.com/berlinguyinca/networkx@v1.11 -tabulate==0.8.2 -coinmarketcap==5.0.3 -simplejson==3.15.0 -boto3 diff --git a/serverless.yml b/serverless.yml deleted file mode 100644 index 798187488..000000000 --- a/serverless.yml +++ /dev/null @@ -1,337 +0,0 @@ -service: freq - -frameworkVersion: ">=1.1.0 <2.0.0" - -plugins: - - serverless-domain-manager - - serverless-python-requirements - -############################################################################################ -# configure out provider and the security guide lines -############################################################################################ -provider: - name: aws - runtime: python3.6 - region: us-east-2 - - #required permissions - iamRoleStatements: - - Effect: Allow - Action: - - dynamodb:* - Resource: "*" - - Effect: Allow - Action: - - SNS:* - Resource: { "Fn::Join" : [":", ["arn:aws:sns:${self:custom.region}", "*:*" ] ] } - - Effect: "Allow" - Action: - - ecs:RunTask - Resource: "*" - - Effect: Allow - Action: - - iam:PassRole - Resource: "*" - - memorySize: 128 - timeout: 90 - versionFunctions: false - - logRetentionInDays: 3 - - #where to store out data, needs to be manually created! - deploymentBucket: - name: lambdas-freq - - # limit the invocations a bit to avoid overloading the server - usagePlan: - throttle: - burstLimit: 100 - rateLimit: 50 - -############################################################################################ -#custom configuration settings -############################################################################################ -custom: - stage: ${opt:stage, self:provider.stage} - region: ${opt:region, self:provider.region} - - snsTopic: "FreqQueue-${self:custom.stage}" - snsTradeTopic: "FreqTradeQueue-${self:custom.stage}" - - tradeTable: "FreqTradesTable-${self:custom.stage}" - strategyTable: "FreqStrategyTable-${self:custom.stage}" - - ### - # custom domain management - ### - - customDomain: - basePath: "${self:custom.stage}" - domainName: "freq.isaac.international" - stage: "${self:custom.stage}" - createRoute53Record: true - - pythonRequirements: - slim: true - invalidateCaches: true - dockerizePip: false - fileName: requirements-aws.txt - noDeploy: - - pytest - - moto - - plotly - - boto3 - - pytest-mock - - pytest-cov - - pymongo -package: - exclude: - - test/** - - node_modules/** - - doc/** - - scripts/** - - bin - - freqtrade/tests/** - -############################################################################################ -# this section defines all lambda function and triggers -############################################################################################ -functions: - - #returns all known strategy names from the server - #and if they are private or not - strategies: - memorySize: 128 - handler: freqtrade/aws/strategy.names - events: - - http: - path: strategies - method: get - cors: true - - environment: - strategyTable: ${self:custom.strategyTable} - reservedConcurrency: 5 - - #returns the source code of this given strategy - #unless it's private - code: - memorySize: 128 - handler: freqtrade/aws/strategy.code - events: - - http: - path: strategies/{user}/{name}/code - method: get - cors: true - integration: lambda - request: - parameter: - paths: - user: true - name: true - response: - headers: - Content-Type: "'text/plain'" - template: $input.path('$') - - environment: - strategyTable: ${self:custom.strategyTable} - reservedConcurrency: 5 - - # loads the details of the specific strategy - get: - memorySize: 128 - handler: freqtrade/aws/strategy.get - events: - - http: - path: strategies/{user}/{name} - method: get - cors: true - request: - parameter: - paths: - user: true - name: true - - environment: - strategyTable: ${self:custom.strategyTable} - reservedConcurrency: 5 - - # loads the aggregation report for the given strategy based on different tickers - get_aggregate_interval: - memorySize: 128 - handler: freqtrade/aws/aggregate/strategy.ticker - events: - - http: - path: strategies/{user}/{name}/aggregate/ticker - method: get - cors: true - request: - parameter: - paths: - user: true - name: true - - environment: - strategyTable: ${self:custom.strategyTable} - tradeTable: ${self:custom.tradeTable} - reservedConcurrency: 5 - - # loads the aggregation report for the given strategy based on different tickers - get_aggregate_timeframe: - memorySize: 128 - handler: freqtrade/aws/aggregate/strategy.timeframe - events: - - http: - path: strategies/{user}/{name}/aggregate/timeframe - method: get - cors: true - request: - parameter: - paths: - user: true - name: true - - environment: - strategyTable: ${self:custom.strategyTable} - tradeTable: ${self:custom.tradeTable} - reservedConcurrency: 5 - - #submits a new strategy to the system - submit: - memorySize: 128 - handler: freqtrade/aws/strategy.submit - events: - - http: - path: strategies/submit - method: post - cors: true - - environment: - topic: ${self:custom.snsTopic} - strategyTable: ${self:custom.strategyTable} - BASE_URL: ${self:custom.customDomain.domainName}/${self:custom.customDomain.stage} - reservedConcurrency: 5 - - #submits a new strategy to the system - submit_github: - memorySize: 128 - handler: freqtrade/aws/strategy.submit_github - events: - - http: - path: strategies/submit/github - method: post - cors: true - - environment: - topic: ${self:custom.snsTopic} - strategyTable: ${self:custom.strategyTable} - reservedConcurrency: 1 - -### TRADE REQUESTS - - # loads all trades for a strategy and it's associated pairs - trades: - memorySize: 128 - handler: freqtrade/aws/trade.get_trades - events: - - http: - path: strategies/{user}/{name}/{stake}/{asset} - method: get - cors: true - request: - parameter: - paths: - user: true - name: true - stake: true - asset: true - - environment: - strategyTable: ${self:custom.strategyTable} - tradeTable: ${self:custom.tradeTable} - reservedConcurrency: 5 - - # submits a new trade to the system - trade: - memorySize: 128 - handler: freqtrade/aws/trade.submit - events: - - http: - path: trade - method: post - cors: true - - environment: - tradeTopic: ${self:custom.snsTradeTopic} - reservedConcurrency: 5 - - # query aggregates by day and ticker for all strategies - trade-aggregate: - memorySize: 128 - handler: freqtrade/aws/trade.get_aggregated_trades - - events: - - http: - path: trades/aggregate/{ticker}/{days} - method: get - cors: true - request: - parameter: - paths: - ticker: true - days: true - environment: - tradeTable: ${self:custom.tradeTable} - - reservedConcurrency: 5 -### SNS TRIGGERED FUNCTIONS - - # stores the received message in the trade table - trade-store: - memorySize: 128 - handler: freqtrade/aws/trade.store - - events: - - sns: ${self:custom.snsTradeTopic} - - environment: - tradeTable: ${self:custom.tradeTable} - - reservedConcurrency: 1 - #backtests the strategy - #should be switched to utilze aws fargate instead - #and running a container - #so that we can evaluate long running tasks - backtest: - memorySize: 128 - handler: freqtrade/aws/backtesting_lambda.backtest - - events: - - sns: ${self:custom.snsTopic} - - environment: - topic: ${self:custom.snsTopic} - tradeTable: ${self:custom.tradeTable} - strategyTable: ${self:custom.strategyTable} - BASE_URL: https://${self:custom.customDomain.domainName}/${self:custom.customDomain.stage} - - reservedConcurrency: 1 - - # schedules all registered strategies on a daily base - schedule: - memorySize: 128 - handler: freqtrade/aws/backtesting_lambda.cron - - events: - - schedule: - rate: rate(1440 minutes) - enabled: true - - environment: - topic: ${self:custom.snsTopic} - tradeTable: ${self:custom.tradeTable} - strategyTable: ${self:custom.strategyTable} - - reservedConcurrency: 1 diff --git a/user_data/strategies/test_strategy.py b/user_data/strategies/test_strategy.py index 34f496e38..3e1ff9e0b 100644 --- a/user_data/strategies/test_strategy.py +++ b/user_data/strategies/test_strategy.py @@ -1,4 +1,3 @@ - # --- Do not remove these libs --- from freqtrade.strategy.interface import IStrategy from pandas import DataFrame @@ -7,7 +6,7 @@ from pandas import DataFrame # Add your lib to import here import talib.abstract as ta import freqtrade.vendor.qtpylib.indicators as qtpylib -import numpy # noqa +import numpy # noqa # This class is a sample. Feel free to customize it. @@ -218,9 +217,9 @@ class TestStrategy(IStrategy): """ dataframe.loc[ ( - (dataframe['adx'] > 30) & - (dataframe['tema'] <= dataframe['bb_middleband']) & - (dataframe['tema'] > dataframe['tema'].shift(1)) + (dataframe['adx'] > 30) & + (dataframe['tema'] <= dataframe['bb_middleband']) & + (dataframe['tema'] > dataframe['tema'].shift(1)) ), 'buy'] = 1 @@ -234,9 +233,9 @@ class TestStrategy(IStrategy): """ dataframe.loc[ ( - (dataframe['adx'] > 70) & - (dataframe['tema'] > dataframe['bb_middleband']) & - (dataframe['tema'] < dataframe['tema'].shift(1)) + (dataframe['adx'] > 70) & + (dataframe['tema'] > dataframe['bb_middleband']) & + (dataframe['tema'] < dataframe['tema'].shift(1)) ), 'sell'] = 1 return dataframe