pancakeSwap、uniswapV2 ... 如何实现交易手续费(滑点)

心血来潮,写篇小文章,就写一点点示例代码吧

实现交易滑点其实很简单,首先要理解的是从哪里扣手续费

扣手续费,那么得理解那些东西呢 ?

  • swap 背后的逻辑是什么
    • 通俗的来讲,swap其实就是他给创建了一个 LP 的合约 (createPair)
    • 在dex进行交易的时候,你要理解是用你的TokenA 去兑换 TokenB 出来
    • 👌,理解以上两个,就知道你下一步应该做什么了
    • 类似于swap背后的原理什么的,这里不做多的阐述,只讲实现滑点
  • 上面提到了 TokenA 兑换TokenB,既然有兑换,那肯定有转账,也就是 Transfer
    • Erc20 标准中 Transfer 有transfer(); transferFrom(); 两个方法
    • 可以看到这两个方法最终会调用内部方法 _transfer();
    • ok,下面开始盲写一波代码
//  其他代码省略,这里只写_transfer 中的部分代码

uint256 fee = 4; // 滑点为 4%

function _transfer(from, to, amount) internal {
	// 不管这玩意的难度,你只要知道,这玩意很简单就👌
	... 省略开头
	
    // 👌,我们正式开始实现 滑点
	// 如果是从 lp 的地址转入,或者转出,则说明这是在dex交易
	if (from == pair || to == pair ) {
	    // 从pair转出,也就是你要买的Token
		if (from == pair) {
			uint256 totalFee = fee * amount / 100;
			// 买入,实现买入滑点,你可以在他转给用户之前,实现,转移出去
			_balance[addr1] += totalFee / 2 ; // 这里扣除 2%
			_balance[addr2] += totalFee - totalFee / 2 ; // 这里扣除 2%
			// 这里 只是给 对应的 接受 手续费的地址增加了手续费,还需要给其增加转账事件
			emit Transfer(pair, addr1, totalFee / 2); // 表示pair转了了totalFee/2 给addr
			emit Transfer(pair, addr2, totalFee / 2); 			
		} else {
			// 卖出 Token
			// 操作和 买入一样
      	}
	}

	... 省略结尾

}

👌,粗略的代码就已经实现了,dex 交易滑点了,其他的可以举一反三,调整代码。
不懂的可留言

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个backtrader股票回测示例,考虑手续费滑点、资金管理: ```python import backtrader as bt class MyStrategy(bt.Strategy): params = ( ('sma_period', 15), ('atr_period', 14), ('atr_multiplier', 2), ('commission', 0.001), ('slippage', 0.001), ('initial_capital', 100000), ) def __init__(self): self.sma = bt.indicators.SimpleMovingAverage( self.data.close, period=self.params.sma_period) self.atr = bt.indicators.ATR( self.data.high, self.data.low, self.data.close, period=self.params.atr_period) self.position_size = None def next(self): if self.position: if self.data.close[0] < self.sma[0]: self.close() else: if self.data.close[0] > self.sma[0] + \ self.params.atr_multiplier * self.atr[0]: self.position_size = self.params.initial_capital * \ self.params.risk / self.atr[0] self.buy(size=self.position_size) def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: return if order.status in [order.Completed]: if order.isbuy(): self.log( 'BUY EXECUTED, Size: %.2f, Price: %.2f, Cost: %.2f, Comm: %.2f' % (order.executed.size, order.executed.price, order.executed.value, order.executed.comm)) self.position_size = order.executed.size else: self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm: %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.position_size = None elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log('Order Canceled/Margin/Rejected') def notify_trade(self, trade): self.log('Trade Profit/Loss: %.2f' % trade.pnl) if __name__ == '__main__': cerebro = bt.Cerebro() cerebro.addstrategy(MyStrategy, risk=0.01) data = bt.feeds.YahooFinanceData( dataname='AAPL', fromdate=datetime.datetime(2010, 1, 1), todate=datetime.datetime(2020, 12, 31)) cerebro.adddata(data) cerebro.broker.setcash(100000) cerebro.broker.setcommission(commission=self.params.commission, margin=0, mult=1) cerebro.broker.set_slippage_fixed( size=self.params.slippage, price=None) cerebro.run() ``` 这个策略使用了SMA和ATR指标来进行交易决策。如果当前没有持仓且价格上穿SMA加上ATR乘以一个倍数,则进行买入;如果当前持仓且价格下穿SMA,则进行卖出。其中,ATR用于计算每次交易的头寸大小。 在`notify_order`方法中,我们输出了每次交易的成本和手续费,用于计算总体的交易成本。在`notify_trade`方法中,我们输出了每次交易的盈亏情况。 在主程序中,我们使用了YahooFinanceData作为数据源,设置了回测时间和初始资金,并设置了手续费滑点交易参数。回测时,我们将risk参数设置为0.01,表示每次交易风险不超过总资金的1%。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值