轮询价格买入卖出

Author: 永赢量化-1, Date: 2020-04-28 09:31:50
Tags: PythonTrade-aided

  • 针对山寨币的一些特性,根据主观判断在某些价格一定可以买入,某些价格可以卖出
  • 为了提高资金利用率,不能提前挂单。此策略就是轮训配置中的币价格,到设置价格后再挂单
  • 感谢子楠的mid_class的思路支持,在B站学习写了这个策略练手
  • 希望大家共同学习进步

import numpy as np
import json

#全局变量
price_precision = {}
amount_precision = {}
hands = {}
can_buy_price = {}
can_sell_price = {}
class mid_class():
    def __init__(self, this_exchange):
        '''
        初始化数据填充交易所的信息,首次获取价格,首次获取account信息
        设定好密钥……
        
        Args:
            this_exchange: FMZ的交易所结构
        
        '''
        self.init_timestamp = time.time()
        self.exchange = this_exchange
        self.name = self.exchange.GetName()
        self.jyd = self.exchange.GetCurrency()        
    
    def get_precision(self,pair):
        '''
        获取交易对的价格精度和数量精度
        '''
        precision = [4,6,1]
        if pair not in price_precision.keys():
            Log('没有配置价格精度: ' + pair)
            return precision
        if pair not in amount_precision.keys():
            Log('没有配置数量精度: ' + pair)
            return precision
        if pair not in hands.keys():
            Log('没有配置一手数量: ' + pair)
            return precision
        return [price_precision[pair], amount_precision[pair], hands[pair]]
        
    def switch_currency(self,pair):
        '''
        替换交易对
        '''
        self.exchange.IO("currency",pair)

    def get_account(self):
        '''
        获取账户信息
        
        Returns:
            获取信息成功返回True,获取信息失败返回False
        '''
        self.Balance = '---'
        self.Amount = '---'
        self.FrozenBalance = '---'
        self.FrozenStocks = '---'
        
        try:
            self.account = self.exchange.GetAccount()

            self.Balance =  self.account['Balance']
            self.Amount = self.account['Stocks']
            self.FrozenBalance =  self.account['FrozenBalance']
            self.FrozenStocks = self.account['FrozenStocks']
            return True
        except:
            return False
    
    def get_ticker(self):
        '''
        获取市价信息
        
        Returns:
            获取信息成功返回True,获取信息失败返回False
        '''
        self.high = '---'
        self.low = '---'
        self.Sell =  '---'
        self.Buy =  '---'
        self.last =  '---'
        self.Volume = '---'
        
        try:
            self.ticker = self.exchange.GetTicker()
        
            self.high = self.ticker['High']
            self.low = self.ticker['Low']
            self.Sell =  self.ticker['Sell']
            self.Buy =  self.ticker['Buy']
            self.last =  self.ticker['Last']
            self.Volume = self.ticker['Volume']
            return True
        except:
            return False
        
        
    def get_depth(self):
        '''
        获取深度信息
        
        Returns:
            获取信息成功返回True,获取信息失败返回False
        '''
        self.Ask = '---'
        self.Bids = '---'
        
        try:
            self.Depth = self.exchange.GetDepth()
            self.Ask = self.Depth['Asks']
            self.Bids = self.Depth ['Bids']
            return True
        except:
            return False
        
        
    
    def get_ohlc_data(self, period = PERIOD_M1):
        '''
        获取K线信息
        
        Args:
            period: K线周期,PERIOD_M1 指1分钟, PERIOD_M5 指5分钟, PERIOD_M15 指15分钟,
            PERIOD_M30 指30分钟, PERIOD_H1 指1小时, PERIOD_D1 指一天。
        '''
        self.ohlc_data = exchange.GetRecords(period)
        
        
    
    def create_order(self, order_type, price, amount):
        '''
        post一个挂单信息
        
        Args:
            order_type:挂单类型,'buy'指挂买单,'sell'指挂卖单
            price:挂单价格
            amount:挂单数量
            
        Returns:
            挂单Id号,可用以取消挂单
        '''
        if order_type == 'buy':
            try:
                order_id = self.exchange.Buy( price, amount)
            except:
                return False
            
        elif order_type == 'sell':
            try:
                order_id = self.exchange.Sell( price, amount)
            except:
                return False
        
        return order_id
    
    def get_orders(self):
        self.undo_ordes = self.exchange.GetOrders()
        return self.undo_ordes
    
    def cancel_order(self, order_id):
        '''
        取消一个挂单信息
        
        Args:
            order_id:希望取消的挂单ID号
            
        Returns:
            取消挂单成功返回True,取消挂单失败返回False
        '''
        return self.exchange.CancelOrder(order_id)
        
    def refreash_data(self):
        '''
        刷新信息
        
        Returns:
            刷新信息成功返回 'refreash_data_finish!' 否则返回相应刷新失败的信息提示
        '''

        if not self.get_account():
            return 'false_get_account'
        
        if not self.get_ticker():
            return 'false_get_ticker'
        if not self.get_depth():
            return 'false_get_depth'
        try:
            self.get_ohlc_data()
        except:
            return 'false_get_K_line_info'
        
        return 'refreash_data_finish!'

 
class qushi_class():
    def __init__(self, mid_class, amount_N, price_N):
        '''
        设定好初始需要考虑的参数
        Args:
            mid_class: 所使用的交易所中间层
            amount_N:数量小数点限制
            price_N:价格小数点限制
            
        Attributes:
            amount_N:数量小数点限制
            price_N:价格小数点限制
            init_time:初始时间
            last_time:上一次执行操作的时间
            trade_list:交易请求的id
        '''
        self.jys = mid_class
        
        self.init_time = time.time()
        self.last_time = time.time()
        
        self.amount_N = amount_N
        self.price_N = price_N
        
        self.trade_list = []
    
    def cancel_orders(self):
        '''
        遍历当前挂单,如果时间超时则取消
        '''
        undo_orders = self.jys.get_orders()
        for i in range(len(undo_orders)):
           self.jys.cancel_order(undo_orders[i].Id)

            
    def refreash_data(self):
        '''
        用来从交易所获取最新的价格和数量信息
        
        Attributes:
            B:商品币数量
            money:计价币数量
            can_buy_B:当前理论可购买商品币数量
            Buy_price:当前市场上最近的一单挂单买价
        '''
        
        message = self.jys.refreash_data()
        if message == 'refreash_data_finish!':
            self.B = self.jys.Amount
            self.money = self.jys.Balance
            self.Buy_price = self.jys.Buy
            self.Sell_price = self.jys.Sell
            self.can_buy_B = self.money/ self.Sell_price * 0.9
            #要求仓位只能是30%
            if self.B > ((self.B + self.can_buy_B)*0.3):
                self.can_buy_B = 0
            else:
                self.can_buy_B = _N(self.can_buy_B, self.amount_N )
            return True
        else:
            return False
            
    def make_trade_by_dict(self, trade_dicts):
        '''
        用来批量完成交易订单
        
        Attributes:
            trade_list:已提交的交易请求的id
        '''
        for this_trade in trade_dicts:
            this_price = _N(this_trade['price'], self.price_N )
            this_amount = _N(this_trade['amount'], self.amount_N )
            
            this_trade_id = self.jys.create_order( this_trade['side'], this_price , this_amount ) 
            self.trade_list.append( this_trade_id )
    
    def condition_chicang(self, hands_num):
        '''
        根据持仓情况来做交易判定的条件
        Args:
            hands_num:表示交易一共几手(我们假设当前每次交易不高于一手)
            
        Attributes:
            min_trade_B: 一手最多交易的商品币数量
            min_trade_money: 一手最多交易的计价币数量
        
        '''
        self.min_trade_B = (self.can_buy_B + self.B) / hands_num
        self.min_buy_B = min(self.min_trade_B, self.can_buy_B)
        self.min_sell_B = min(self.min_trade_B, self.B)
        self.min_trade_money = self.min_trade_B* self.jys.Buy


    
    def condition_qushi(self):
        '''
        根据市场价格情况来做交易判定的条件
        '''
        rt = False
        currency = self.jys.jyd
        #Log('cur price' + self.jys.Sell)
        #Log('cur range' + can_buy_price[currency][0])
        if self.jys.Sell > can_buy_price[currency][0] and self.jys.Sell < can_buy_price[currency][1]:
            rt = 'Buy'
        if self.jys.Buy > can_sell_price[currency][0] and self.jys.Buy < can_sell_price[currency][1]:
            rt = 'Sell'
       
        return rt
    
    
    def make_trade_dicts(self, hands_num ):
        '''
        制作交易用字典表单
        Args:
            hands_num:一共交易多少手
            change_pct:价格变化多少交易一手
            
        Returns:
            this_trade_dicts: 根据当前价格变化,制作出需交易的字典的列表
        
        '''
        self.condition_chicang(hands_num)
        rt = self.condition_qushi()
        this_trade_dicts = []
        if rt:
            if rt == 'Buy':
                if self.min_buy_B > 10**-self.amount_N:
                    this_trade_dicts.append({
                        'side':'buy',
                        'price':self.jys.Buy,
                        'amount':self.min_buy_B
                    })
            else:
                if self.min_sell_B > 10**-self.amount_N:
                    this_trade_dicts.append({
                        'side':'sell',
                        'price':self.jys.Sell,
                        'amount':self.min_sell_B
                    })
            return this_trade_dicts
        else:
            return False



def main():

    #获取配置的值
    global price_precision
    price_precision = json.loads(PRICE_PRECISION)
    global amount_precision 
    amount_precision = json.loads(AMOUNT_PRECISION)
    global hands 
    hands = json.loads(HANDS)
    global can_buy_price
    can_buy_price = json.loads(CAN_BUY_PRICE)
    global can_sell_price
    can_sell_price = json.loads(CAN_SELL_PRICE)
    round = 1
    while True:
        Sleep(1000)
        for i in range(len(exchanges)):
            #定义交易中间件
            test_mid = mid_class(exchanges[i])
            currency = test_mid.jyd
            #获取交易对的价格,数量精度
            currency_precision = test_mid.get_precision(currency)
            #生成策略类
            test_qushi = qushi_class(test_mid , currency_precision[0], currency_precision[1])
            #获取最新数据
            result  = test_qushi.refreash_data()
            if result == True:
                now_trade_dicts = test_qushi.make_trade_dicts(currency_precision[2])
                if now_trade_dicts:
                    test_qushi.make_trade_by_dict(now_trade_dicts)
                    now_trade_dicts = False
            #检查挂单情况
            if round % 20 == 0:
                Log('开始撤单')
                Log(test_mid.account)
                test_qushi.cancel_orders()
        
        round = round + 1


Related

More

小草 子楠为FMZ推广了不少用户啊