stable/freqtrade/custom_orders_strat.py
creslin 6748e897a5 Custom_Orders - Demo.
Early demonstration of Strategy controlling
Order Type on the Exchange, Stop / Stop_limit / Market / limit etc
The stake
The price to submit

Demo allows multiple orders to be placed, so ladding buys down to a fib
Or buying and setting stop-loss
Or Take profit in stages etc.

Included a strategy demo with stubs for
limit, market, take_profit and stop_limit orders

Obviously very early code.
Submitted as buys, stops etc are working / showing in GDAX.
and we have hte order IDs to update trade table.
2018-07-31 20:21:01 +00:00

297 lines
11 KiB
Python

# --- Do not remove these libs ---
from freqtrade.strategy.interface import IStrategy
from pandas import DataFrame
import talib.abstract as ta
from datetime import datetime
import time
import timeit
# --------------------------------
class customorders(IStrategy):
"""
author@: Creslin
"""
minimal_roi = {
"0": 0.20
}
# Optimal stoploss designed for the strategy
stoploss = -0.01
# Optimal ticker interval for the strategy
ticker_interval = '5m'
def get_ticker_indicator(self):
return int(self.ticker_interval[:-1])
def populate_indicators(self, dataframe: DataFrame) -> DataFrame:
#
# dataframe['rsi'] = ta.RSI(dataframe, timeperiod=7)
time.sleep(1)
return dataframe
# # # If using Berlins expose pairs to strategy
# def advise_indicators(self, dataframe: DataFrame, pair: str) -> DataFrame:
#
# # RSI
# dataframe['rsi'] = ta.RSI(dataframe, timeperiod=7)
#
# return dataframe
#####
# EXAMPLE Strat - buys every even minute sells every odd
####
def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame:
if int(datetime.now().strftime('%M')) % 2 == 0: #buy = 1 every even minute
print('----------------we are in strategy', datetime.now().time())
b: float = 9999999.99
print( "buy = 1")
else:
b = 0.00000001
dataframe.loc[
(
# L-RSI When below 0.01 / vfi -26
#(dataframe['lrsi'] < 0.5) &
#(dataframe['vfi'] < -4)
(dataframe['close'] < b )
),
'buy'] = 1
return dataframe
#####
# EXAMPLE Strat - buys every even minute sells every odd
####
def populate_sell_trend(self, dataframe: DataFrame) -> DataFrame:
if int(datetime.now().strftime('%M'))% 2 != 0: ## sell = 1 every ODD minute
print('----------------we are in strategy', datetime.now().time())
s: float = 9999999.99
print("sell = 1")
else:
s = 0.00000001
dataframe.loc[
(
# vfi 0.99
#(dataframe['vfi'] > 0.41)
(dataframe['close'] < s )
),
'sell'] = 1
return dataframe
def stop_stops_plugin(self, dataframe: DataFrame, pair: str) -> DataFrame:
"""
stop_stops_pligin. To stop a buy where X trades from Y have stopped out.
i.e to remove a pair from being bought that is on a losing streak.
Only processed if buy=1
"""
"""
Called before a trade executes if exists,
:param dataframe:
:param pair:
:return:
"""
from freqtrade.persistence import Trade
import pandas as pd
df = dataframe
# Only check buys, else return DF untouched
if df.iloc[-1]['buy'] == 1:
print("STOP_STOPS STOP_STOPS STOP_STOPS STOP_STOP STOP_STOPS STOP_STOP STOP_STOPS")
from pandas import set_option
set_option('display.max_rows', 2000)
set_option('display.max_columns', 8)
def closed_pair_trades(pair):
"""
To return list of closed trades for a pair
enriched with open/closd dates, profit, and stake
:param pair:
:return: df_c pair open, close, profit, stake
"""
pair = pair
df_c = pd.DataFrame(columns=['pair', 'profit', 'open_date', 'close_date', 'stake'])
pair_trades = Trade.query.filter(Trade.pair.is_(pair)).all()
for pair_trade in pair_trades:
if pair_trade.is_open == False:
# print("closed trade for", pair, "closed with ", pair_trade.close_profit )
p = pair
pcp = pair_trade.close_profit
od = pair_trade.open_date
cd = pair_trade.close_date
sa = pair_trade.stake_amount
df_c = df_c.append([{'pair':p, 'profit':pcp, 'open_date':od,
'close_date':cd, 'stake':sa}], ignore_index=True)
return df_c
def has_past_perf(df_c, lost_the_last=1, out_of=1):
"""
Return if pair lost_the_last X trades out_of Y trades
:param df_c: dataframe of closed trades for the pair
:param lost_the_last: number of bad trades to look for
:param out_of: within the last number over trades closed
:return: bool
"""
lost_the_last =lost_the_last
out_of = out_of
df_c = df_c
df_c_tail = df_c.tail(out_of)
lost_from_last_count = df_c_tail[df_c_tail['profit'] < 0].shapec
if lost_from_last_count[0] >= lost_the_last:
return True
else:
return False
# load this pairs closed trades into a df
# df_c = closed_pair_trades(pair=pair)
# print("df_c", df_c)
# Get bool if on pairs past profitable trades count, cancel the buy if limit hit
# past_perf = has_past_perf(df_c, lost_the_last=9, out_of=10)
# if past_perf:
# #set buy to 0
# print("STOP STOP SETTING BUY TO ZERO ")
# df.loc['buy'] = 0
dataframe = df
return dataframe
#def money_mgt_plugin(self, dataframe: DataFrame, pair: str) -> DataFrame:
def money_mgt_plugin(self, dataframe: DataFrame, pair: str) -> DataFrame:
"""
pre_trade_mgt.
To allow money mamagement and or other checks to be put against dataframe
with buy or sell set to "1"
Returns a list of custom order trades.
Each custom order to include, above the needed fields for exchange
dict['order_type'] = 'a_open_limit'
order_types are later ordered and executed in alphabetical order.
order to enter market are executed before stops and take profits are played in.
Supported types are:
- a_open_limit # enter market with limit order
- a_open_market # enter market with market order
- b_stop_limit # set a stop_limit order
- b_stop_market # set a stop_market order
- c_take_limit # set a take profit limit order
- c_take_market # set a take profit market order
Multipe orders can be processed but an asset may only have the sum of its open value
in either stop or take profit orders.
i.e we can open a $500 for 500 tokens position and have any combination of
stop or take profit orders at any prices that COMBINED do not break 500 tokens.
"one" common scenario may be an 'a_open_limit' or 'a_open_market' order
and 'b_stop_limit' or 'b_stop_market' order to protect capital.
"""
print("MONEY_MGT MONEY_MGT MONEY_MGT MONEY_MGT MONEY_MGT MONEY_MGT MONEY_MGT MONEY_MGT MONEY_MGT")
df = dataframe
# If buy = 1 and Exchange is GDAX
if df.iloc[-1]['buy'] == 1:
exchange = self.config['exchange']['name']
# GDAX Stop-Limit Order
if exchange == "gdax":
custom_orders = []
limit = {}
take_profit = {}
# Take profit Market example "b_take_market"
# open market order example "a_open_market"
# Open limit order example
amount = 0.5
limit_price = df.iloc[-1]['close'] * 1.05 # pay 5% for testing order are made
limit = {}
limit["order_type"] = "a_open_limit"
limit["symbol"] = pair
limit["type"] = "limit"
limit["side"] = "buy"
limit["amount"] = amount
limit["price"] = limit_price
params: dict = {}
limit["params"] = params
custom_orders.append(limit)
# Market Example
market_amount = 1
market = {}
market_price = 1.05 # pay 5% for testing order are made
market["order_type"] = "a_open_market"
market["symbol"] = pair
market["type"] = "market"
market["side"] = "buy"
market["amount"] = market_amount
params: dict = {}
market["params"] = params
custom_orders.append(market)
# Stop Limit order
stop_limit = {}
stop_limit_amount = 0.01
stop_limit_price = df.iloc[-1]['close'] * 0.90 # take 10% hard code for testing
stop_price = df.iloc[-1]['close'] * 0.95 # trigger at 7% loss, hard code for testing
stop_limit['order_type'] = 'b_stop_limit'
stop_limit['symbol'] = pair
stop_limit['type'] = 'limit'
stop_limit['side'] = 'sell'
stop_limit['amount'] = stop_limit_amount
stop_limit['price'] = stop_limit_price
params: dict = {}
params['stop'] = 'loss'
params['stop_price'] = stop_price
stop_limit['params'] = params
custom_orders.append(stop_limit)
# Take profit Limit example
take_profit_limit_price = df.iloc[-1]['close'] * 1.2 # take_proft at 20% - for demo
take_profit_amount = 0.01
take_profit["order_type"] = "c_take_profit_limit"
take_profit["order_template"] = (pair, amount, take_profit_limit_price)
take_profit["symbol"] = pair
take_profit["type"] = "limit"
take_profit["side"] = "sell"
take_profit["amount"] = take_profit_amount
take_profit["price"] = take_profit_limit_price
take_profit_params: dict = {}
take_profit["params"] = take_profit_params
# custom_orders.append(take_profit)
#todo Add library of trade templates for binance, polo, gdax...
#todo Code to check have all the fields and sense check
# Cancel Legacy buy/sell signals if there are custom orders.
# Set buy / sell = 0 if we have custom orders
dataframe.loc['buy'] = 0
dataframe.loc['sell'] = 0
return dataframe, custom_orders
return dataframe, None